| author | |
| committer | |
| log | 5dbc21b511790ff6bfbd8f597e2a8eb875142299 |
| tree | ad3b1771e21b7ffcd4629dc5d765ef704f6a7438 |
| parent | f6edba4a872e2c5781bb6cb05f66a57e16455f15 |
partial implementation of @err_name12 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}") | ... | @@ -198,6 +198,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/errno.zig" DESTINATION "${ZIG_STD_DEST}") |
| 198 | install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") | 198 | install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") |
| 199 | install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}") | 199 | install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}") |
| 200 | install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}") | 200 | install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}") |
| 201 | install(FILES "${CMAKE_SOURCE_DIR}/std/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}") | ||
| 202 | install(FILES "${CMAKE_SOURCE_DIR}/std/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}") | ||
| 201 | 203 | ||
| 202 | add_executable(run_tests ${TEST_SOURCES}) | 204 | add_executable(run_tests ${TEST_SOURCES}) |
| 203 | target_link_libraries(run_tests) | 205 | target_link_libraries(run_tests) |
example/cat/main.zig+24-21| ... | @@ -1,58 +1,61 @@ | ... | @@ -1,58 +1,61 @@ |
| 1 | export executable "cat"; | 1 | use @import("std"); |
| 2 | 2 | ||
| 3 | import "std.zig"; | 3 | // TODO var args printing |
| 4 | |||
| 5 | // Things to do to make this work: | ||
| 6 | // * var args printing | ||
| 7 | // * cast err type to string | ||
| 8 | // * string equality | ||
| 9 | 4 | ||
| 10 | pub fn main(args: [][]u8) -> %void { | 5 | pub fn main(args: [][]u8) -> %void { |
| 11 | const exe = args[0]; | 6 | const exe = args[0]; |
| 12 | var catted_anything = false; | 7 | var catted_anything = false; |
| 13 | for (arg, args[1...]) { | 8 | for (args[1...]) |arg| { |
| 14 | if (arg == "-") { | 9 | if (str_eql(arg, "-")) { |
| 15 | catted_anything = true; | 10 | catted_anything = true; |
| 16 | cat_stream(stdin) %% |err| return err; | 11 | cat_stream(io.stdin) %% |err| return err; |
| 17 | } else if (arg[0] == '-') { | 12 | } else if (arg[0] == '-') { |
| 18 | return usage(exe); | 13 | return usage(exe); |
| 19 | } else { | 14 | } else { |
| 20 | var is = input_stream_open(arg, OpenReadOnly) %% |err| { | 15 | var is = io.InStream.open(arg) %% |err| { |
| 21 | %%stderr.print("Unable to open file: {}", ([]u8)(err)); | 16 | %%io.stderr.write("Unable to open file: "); |
| 17 | %%io.stderr.write(@err_name(err)); | ||
| 18 | %%io.stderr.write("\n"); | ||
| 22 | return err; | 19 | return err; |
| 23 | }; | 20 | }; |
| 24 | defer is.close(); | 21 | defer %%is.close(); |
| 25 | 22 | ||
| 26 | catted_anything = true; | 23 | catted_anything = true; |
| 27 | cat_stream(is) %% |err| return err; | 24 | cat_stream(is) %% |err| return err; |
| 28 | } | 25 | } |
| 29 | } | 26 | } |
| 30 | if (!catted_anything) { | 27 | if (!catted_anything) { |
| 31 | cat_stream(stdin) %% |err| return err; | 28 | cat_stream(io.stdin) %% |err| return err; |
| 32 | } | 29 | } |
| 33 | } | 30 | } |
| 34 | 31 | ||
| 35 | fn usage(exe: []u8) -> %void { | 32 | fn 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"); | ||
| 37 | return error.Invalid; | 36 | return error.Invalid; |
| 38 | } | 37 | } |
| 39 | 38 | ||
| 40 | fn cat_stream(is: InputStream) -> %void { | 39 | fn cat_stream(is: io.InStream) -> %void { |
| 41 | var buf: [1024 * 4]u8 = undefined; | 40 | var buf: [1024 * 4]u8 = undefined; |
| 42 | 41 | ||
| 43 | while (true) { | 42 | while (true) { |
| 44 | const bytes_read = is.read(buf) %% |err| { | 43 | 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"); | ||
| 46 | return err; | 47 | return err; |
| 47 | } | 48 | }; |
| 48 | 49 | ||
| 49 | if (bytes_read == 0) { | 50 | if (bytes_read == 0) { |
| 50 | break; | 51 | break; |
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | stdout.write(buf[0...bytes_read]) %% |err| { | 54 | io.stdout.write(buf[0...bytes_read]) %% |err| { |
| 54 | %%stderr.print("Unable to write to stdout: {}", ([]u8)(err)); | 55 | %%io.stderr.write("Unable to write to stdout: "); |
| 56 | %%io.stderr.write(@err_name(err)); | ||
| 57 | %%io.stderr.write("\n"); | ||
| 55 | return err; | 58 | return err; |
| 56 | } | 59 | }; |
| 57 | } | 60 | } |
| 58 | } | 61 | } |
src/all_types.hpp+4-1| ... | @@ -1044,6 +1044,7 @@ enum BuiltinFnId { | ... | @@ -1044,6 +1044,7 @@ enum BuiltinFnId { |
| 1044 | BuiltinFnIdClz, | 1044 | BuiltinFnIdClz, |
| 1045 | BuiltinFnIdImport, | 1045 | BuiltinFnIdImport, |
| 1046 | BuiltinFnIdCImport, | 1046 | BuiltinFnIdCImport, |
| 1047 | BuiltinFnIdErrName, | ||
| 1047 | }; | 1048 | }; |
| 1048 | 1049 | ||
| 1049 | struct BuiltinFnEntry { | 1050 | struct BuiltinFnEntry { |
| ... | @@ -1177,7 +1178,7 @@ struct CodeGen { | ... | @@ -1177,7 +1178,7 @@ struct CodeGen { |
| 1177 | LLVMValueRef trap_fn_val; | 1178 | LLVMValueRef trap_fn_val; |
| 1178 | bool error_during_imports; | 1179 | bool error_during_imports; |
| 1179 | uint32_t next_node_index; | 1180 | uint32_t next_node_index; |
| 1180 | uint32_t error_value_count; | 1181 | ZigList<AstNode *> error_decls; |
| 1181 | TypeTableEntry *err_tag_type; | 1182 | TypeTableEntry *err_tag_type; |
| 1182 | 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] | 1183 | 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] |
| 1183 | LLVMValueRef int_builtin_fns[2][4]; // [0-ctz,1-clz][0-8,1-16,2-32,3-64] | 1184 | LLVMValueRef int_builtin_fns[2][4]; // [0-ctz,1-clz][0-8,1-16,2-32,3-64] |
| ... | @@ -1189,6 +1190,8 @@ struct CodeGen { | ... | @@ -1189,6 +1190,8 @@ struct CodeGen { |
| 1189 | uint32_t test_fn_count; | 1190 | uint32_t test_fn_count; |
| 1190 | 1191 | ||
| 1191 | bool check_unused; | 1192 | bool check_unused; |
| 1193 | |||
| 1194 | bool generate_error_name_table; | ||
| 1192 | }; | 1195 | }; |
| 1193 | 1196 | ||
| 1194 | struct VariableTableEntry { | 1197 | struct VariableTableEntry { |
src/analyze.cpp+26-5| ... | @@ -1415,9 +1415,10 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) { | ... | @@ -1415,9 +1415,10 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) { |
| 1415 | // duplicate error definitions allowed and they get the same value | 1415 | // duplicate error definitions allowed and they get the same value |
| 1416 | err->value = existing_entry->value->value; | 1416 | err->value = existing_entry->value->value; |
| 1417 | } else { | 1417 | } else { |
| 1418 | assert(g->error_value_count < (((uint32_t)1) << (uint32_t)g->err_tag_type->data.integral.bit_count)); | 1418 | int error_value_count = g->error_decls.length; |
| 1419 | err->value = g->error_value_count; | 1419 | assert(error_value_count < (((uint32_t)1) << (uint32_t)g->err_tag_type->data.integral.bit_count)); |
| 1420 | g->error_value_count += 1; | 1420 | err->value = error_value_count; |
| 1421 | g->error_decls.append(node); | ||
| 1421 | g->error_table.put(&err->name, err); | 1422 | g->error_table.put(&err->name, err); |
| 1422 | } | 1423 | } |
| 1423 | 1424 | ||
| ... | @@ -4084,7 +4085,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -4084,7 +4085,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 4084 | wanted_type->id == TypeTableEntryIdInt) | 4085 | wanted_type->id == TypeTableEntryIdInt) |
| 4085 | { | 4086 | { |
| 4086 | BigNum bn; | 4087 | BigNum bn; |
| 4087 | bignum_init_unsigned(&bn, g->error_value_count); | 4088 | bignum_init_unsigned(&bn, g->error_decls.length); |
| 4088 | if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count, | 4089 | if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count, |
| 4089 | wanted_type->data.integral.is_signed)) | 4090 | wanted_type->data.integral.is_signed)) |
| 4090 | { | 4091 | { |
| ... | @@ -4242,6 +4243,25 @@ static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_imp | ... | @@ -4242,6 +4243,25 @@ static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_imp |
| 4242 | return resolve_expr_const_val_as_import(g, node, child_import); | 4243 | return resolve_expr_const_val_as_import(g, node, child_import); |
| 4243 | } | 4244 | } |
| 4244 | 4245 | ||
| 4246 | static 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 | |||
| 4245 | static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 4265 | static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 4246 | TypeTableEntry *expected_type, AstNode *node) | 4266 | TypeTableEntry *expected_type, AstNode *node) |
| 4247 | { | 4267 | { |
| ... | @@ -4570,7 +4590,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -4570,7 +4590,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 4570 | return analyze_import(g, import, context, node); | 4590 | return analyze_import(g, import, context, node); |
| 4571 | case BuiltinFnIdCImport: | 4591 | case BuiltinFnIdCImport: |
| 4572 | return analyze_c_import(g, import, context, node); | 4592 | return analyze_c_import(g, import, context, node); |
| 4573 | 4593 | case BuiltinFnIdErrName: | |
| 4594 | return analyze_err_name(g, import, context, node); | ||
| 4574 | } | 4595 | } |
| 4575 | zig_unreachable(); | 4596 | zig_unreachable(); |
| 4576 | } | 4597 | } |
src/codegen.cpp+14-1| ... | @@ -65,7 +65,9 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { | ... | @@ -65,7 +65,9 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { |
| 65 | g->generic_table.init(16); | 65 | g->generic_table.init(16); |
| 66 | g->is_release_build = false; | 66 | g->is_release_build = false; |
| 67 | g->is_test_build = false; | 67 | g->is_test_build = false; |
| 68 | g->error_value_count = 1; | 68 | |
| 69 | // the error.Ok value | ||
| 70 | g->error_decls.append(nullptr); | ||
| 69 | 71 | ||
| 70 | g->root_package = new_package(buf_ptr(root_source_dir), ""); | 72 | g->root_package = new_package(buf_ptr(root_source_dir), ""); |
| 71 | g->std_package = new_package(ZIG_STD_DIR, "index.zig"); | 73 | 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 | ... | @@ -328,6 +330,14 @@ static LLVMValueRef get_handle_value(CodeGen *g, AstNode *source_node, LLVMValue |
| 328 | } | 330 | } |
| 329 | } | 331 | } |
| 330 | 332 | ||
| 333 | static 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 | |||
| 331 | static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { | 341 | static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 332 | assert(node->type == NodeTypeFnCallExpr); | 342 | assert(node->type == NodeTypeFnCallExpr); |
| 333 | AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; | 343 | 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) { | ... | @@ -467,6 +477,8 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 467 | zig_unreachable(); | 477 | zig_unreachable(); |
| 468 | case BuiltinFnIdCompileVar: | 478 | case BuiltinFnIdCompileVar: |
| 469 | return nullptr; | 479 | return nullptr; |
| 480 | case BuiltinFnIdErrName: | ||
| 481 | return gen_err_name(g, node); | ||
| 470 | } | 482 | } |
| 471 | zig_unreachable(); | 483 | zig_unreachable(); |
| 472 | } | 484 | } |
| ... | @@ -3739,6 +3751,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -3739,6 +3751,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 3739 | create_builtin_fn_with_arg_count(g, BuiltinFnIdClz, "clz", 2); | 3751 | create_builtin_fn_with_arg_count(g, BuiltinFnIdClz, "clz", 2); |
| 3740 | create_builtin_fn_with_arg_count(g, BuiltinFnIdImport, "import", 1); | 3752 | create_builtin_fn_with_arg_count(g, BuiltinFnIdImport, "import", 1); |
| 3741 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCImport, "c_import", 1); | 3753 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCImport, "c_import", 1); |
| 3754 | create_builtin_fn_with_arg_count(g, BuiltinFnIdErrName, "err_name", 1); | ||
| 3742 | } | 3755 | } |
| 3743 | 3756 | ||
| 3744 | static void init(CodeGen *g, Buf *source_path) { | 3757 | static void init(CodeGen *g, Buf *source_path) { |
std/index.zig+21| ... | @@ -2,3 +2,24 @@ pub const Rand = @import("rand.zig").Rand; | ... | @@ -2,3 +2,24 @@ pub const Rand = @import("rand.zig").Rand; |
| 2 | pub const io = @import("io.zig"); | 2 | pub const io = @import("io.zig"); |
| 3 | pub const os = @import("os.zig"); | 3 | pub const os = @import("os.zig"); |
| 4 | pub const math = @import("math.zig"); | 4 | pub const math = @import("math.zig"); |
| 5 | |||
| 6 | pub fn assert(b: bool) { | ||
| 7 | if (!b) unreachable{} | ||
| 8 | } | ||
| 9 | |||
| 10 | pub const str_eql = slice_eql(u8); | ||
| 11 | |||
| 12 | pub 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") | ||
| 21 | fn 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; | ... | @@ -39,37 +39,51 @@ pub error NoSpaceLeft; |
| 39 | pub error BadPerm; | 39 | pub error BadPerm; |
| 40 | pub error PipeFail; | 40 | pub error PipeFail; |
| 41 | pub error BadFd; | 41 | pub error BadFd; |
| 42 | pub error IsDir; | ||
| 43 | pub error NotDir; | ||
| 44 | pub error SymLinkLoop; | ||
| 45 | pub error ProcessFdQuotaExceeded; | ||
| 46 | pub error SystemFdQuotaExceeded; | ||
| 47 | pub error NameTooLong; | ||
| 48 | pub error NoDevice; | ||
| 49 | pub error PathNotFound; | ||
| 50 | pub error NoMem; | ||
| 42 | 51 | ||
| 43 | const buffer_size = 4 * 1024; | 52 | const buffer_size = 4 * 1024; |
| 44 | const max_u64_base10_digits = 20; | 53 | const max_u64_base10_digits = 20; |
| 45 | const max_f64_digits = 65; | 54 | const max_f64_digits = 65; |
| 46 | 55 | ||
| 56 | pub const OpenRead = 0b0001; | ||
| 57 | pub const OpenWrite = 0b0010; | ||
| 58 | pub const OpenCreate = 0b0100; | ||
| 59 | pub const OpenTruncate = 0b1000; | ||
| 60 | |||
| 47 | pub struct OutStream { | 61 | pub struct OutStream { |
| 48 | fd: isize, | 62 | fd: isize, |
| 49 | buffer: [buffer_size]u8, | 63 | buffer: [buffer_size]u8, |
| 50 | index: isize, | 64 | index: isize, |
| 51 | 65 | ||
| 52 | pub fn print_str(os: &OutStream, str: []const u8) -> %isize { | 66 | pub fn write(os: &OutStream, bytes: []const u8) -> %isize { |
| 53 | var src_bytes_left = str.len; | 67 | var src_bytes_left = bytes.len; |
| 54 | var src_index: @typeof(str.len) = 0; | 68 | var src_index: @typeof(bytes.len) = 0; |
| 55 | const dest_space_left = os.buffer.len - os.index; | 69 | const dest_space_left = os.buffer.len - os.index; |
| 56 | 70 | ||
| 57 | while (src_bytes_left > 0) { | 71 | while (src_bytes_left > 0) { |
| 58 | const copy_amt = math.min_isize(dest_space_left, src_bytes_left); | 72 | 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); |
| 60 | os.index += copy_amt; | 74 | os.index += copy_amt; |
| 61 | if (os.index == os.buffer.len) { | 75 | if (os.index == os.buffer.len) { |
| 62 | %return os.flush(); | 76 | %return os.flush(); |
| 63 | } | 77 | } |
| 64 | src_bytes_left -= copy_amt; | 78 | src_bytes_left -= copy_amt; |
| 65 | } | 79 | } |
| 66 | return str.len; | 80 | return bytes.len; |
| 67 | } | 81 | } |
| 68 | 82 | ||
| 69 | /// Prints a byte buffer, flushes the buffer, then returns the number of | 83 | /// Prints a byte buffer, flushes the buffer, then returns the number of |
| 70 | /// bytes printed. The "f" is for "flush". | 84 | /// bytes printed. The "f" is for "flush". |
| 71 | pub fn printf(os: &OutStream, str: []const u8) -> %isize { | 85 | 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); |
| 73 | %return os.flush(); | 87 | %return os.flush(); |
| 74 | return byte_count; | 88 | return byte_count; |
| 75 | } | 89 | } |
| ... | @@ -138,6 +152,33 @@ pub struct OutStream { | ... | @@ -138,6 +152,33 @@ pub struct OutStream { |
| 138 | pub struct InStream { | 152 | pub struct InStream { |
| 139 | fd: isize, | 153 | fd: isize, |
| 140 | 154 | ||
| 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 | |||
| 141 | pub fn read(is: &InStream, buf: []u8) -> %isize { | 182 | pub fn read(is: &InStream, buf: []u8) -> %isize { |
| 142 | const amt_read = linux.read(is.fd, &buf[0], buf.len); | 183 | const amt_read = linux.read(is.fd, &buf[0], buf.len); |
| 143 | if (amt_read < 0) { | 184 | if (amt_read < 0) { |
std/linux.zig+45-250| ... | @@ -1,86 +1,6 @@ | ... | @@ -1,86 +1,6 @@ |
| 1 | const SYS_read = switch (@compile_var("arch")) { | 1 | const arch = switch (@compile_var("arch")) { |
| 2 | x86_64 => 0, | 2 | x86_64 => @import("linux_x86_64.zig"), |
| 3 | i386 => 3, | 3 | i386 => @import("linux_i386.zig"), |
| 4 | else => unreachable{}, | ||
| 5 | }; | ||
| 6 | const SYS_write = switch (@compile_var("arch")) { | ||
| 7 | x86_64 => 1, | ||
| 8 | i386 => 4, | ||
| 9 | else => unreachable{}, | ||
| 10 | }; | ||
| 11 | const SYS_open = switch (@compile_var("arch")) { | ||
| 12 | x86_64 => 2, | ||
| 13 | i386 => 5, | ||
| 14 | else => unreachable{}, | ||
| 15 | }; | ||
| 16 | const SYS_close = switch (@compile_var("arch")) { | ||
| 17 | x86_64 => 3, | ||
| 18 | i386 => 6, | ||
| 19 | else => unreachable{}, | ||
| 20 | }; | ||
| 21 | const SYS_creat = switch (@compile_var("arch")) { | ||
| 22 | x86_64 => 85, | ||
| 23 | i386 => 8, | ||
| 24 | else => unreachable{}, | ||
| 25 | }; | ||
| 26 | const SYS_lseek = switch (@compile_var("arch")) { | ||
| 27 | x86_64 => 8, | ||
| 28 | i386 => 19, | ||
| 29 | else => unreachable{}, | ||
| 30 | }; | ||
| 31 | const SYS_mmap = switch (@compile_var("arch")) { | ||
| 32 | x86_64 => 9, | ||
| 33 | i386 => 90, | ||
| 34 | else => unreachable{}, | ||
| 35 | }; | ||
| 36 | const SYS_munmap = switch (@compile_var("arch")) { | ||
| 37 | x86_64 => 11, | ||
| 38 | i386 => 91, | ||
| 39 | else => unreachable{}, | ||
| 40 | }; | ||
| 41 | const SYS_rt_sigprocmask = switch (@compile_var("arch")) { | ||
| 42 | x86_64 => 14, | ||
| 43 | i386 => 175, | ||
| 44 | else => unreachable{}, | ||
| 45 | }; | ||
| 46 | const SYS_exit = switch (@compile_var("arch")) { | ||
| 47 | x86_64 => 60, | ||
| 48 | i386 => 1, | ||
| 49 | else => unreachable{}, | ||
| 50 | }; | ||
| 51 | const SYS_kill = switch (@compile_var("arch")) { | ||
| 52 | x86_64 => 62, | ||
| 53 | i386 => 37, | ||
| 54 | else => unreachable{}, | ||
| 55 | }; | ||
| 56 | const SYS_getgid = switch (@compile_var("arch")) { | ||
| 57 | x86_64 => 104, | ||
| 58 | i386 => 47, | ||
| 59 | else => unreachable{}, | ||
| 60 | }; | ||
| 61 | const SYS_gettid = switch (@compile_var("arch")) { | ||
| 62 | x86_64 => 186, | ||
| 63 | i386 => 224, | ||
| 64 | else => unreachable{}, | ||
| 65 | }; | ||
| 66 | const SYS_tkill = switch (@compile_var("arch")) { | ||
| 67 | x86_64 => 200, | ||
| 68 | i386 => 238, | ||
| 69 | else => unreachable{}, | ||
| 70 | }; | ||
| 71 | const SYS_tgkill = switch (@compile_var("arch")) { | ||
| 72 | x86_64 => 234, | ||
| 73 | i386 => 270, | ||
| 74 | else => unreachable{}, | ||
| 75 | }; | ||
| 76 | const SYS_openat = switch (@compile_var("arch")) { | ||
| 77 | x86_64 => 257, | ||
| 78 | i386 => 295, | ||
| 79 | else => unreachable{}, | ||
| 80 | }; | ||
| 81 | const SYS_getrandom = switch (@compile_var("arch")) { | ||
| 82 | x86_64 => 318, | ||
| 83 | i386 => 355, | ||
| 84 | else => unreachable{}, | 4 | else => unreachable{}, |
| 85 | }; | 5 | }; |
| 86 | 6 | ||
| ... | @@ -95,15 +15,6 @@ pub const MMAP_MAP_PRIVATE = 2; | ... | @@ -95,15 +15,6 @@ pub const MMAP_MAP_PRIVATE = 2; |
| 95 | pub const MMAP_MAP_FIXED = 16; | 15 | pub const MMAP_MAP_FIXED = 16; |
| 96 | pub const MMAP_MAP_ANON = 32; | 16 | pub const MMAP_MAP_ANON = 32; |
| 97 | 17 | ||
| 98 | pub const O_RDONLY = 0x0; | ||
| 99 | pub const O_WRONLY = 0x1; | ||
| 100 | pub const O_RDWR = 0x2; | ||
| 101 | pub const O_CREAT = 0x40; | ||
| 102 | pub const O_EXCL = 0x80; | ||
| 103 | pub const O_TRUNC = 0x200; | ||
| 104 | pub const O_APPEND = 0x400; | ||
| 105 | pub const O_SYNC = 0x101000; | ||
| 106 | |||
| 107 | pub const SIGHUP = 1; | 18 | pub const SIGHUP = 1; |
| 108 | pub const SIGINT = 2; | 19 | pub const SIGINT = 2; |
| 109 | pub const SIGQUIT = 3; | 20 | pub const SIGQUIT = 3; |
| ... | @@ -139,209 +50,93 @@ pub const SIGPWR = 30; | ... | @@ -139,209 +50,93 @@ pub const SIGPWR = 30; |
| 139 | pub const SIGSYS = 31; | 50 | pub const SIGSYS = 31; |
| 140 | pub const SIGUNUSED = SIGSYS; | 51 | pub const SIGUNUSED = SIGSYS; |
| 141 | 52 | ||
| 53 | pub const O_RDONLY = 0o0; | ||
| 54 | pub const O_WRONLY = 0o1; | ||
| 55 | pub const O_RDWR = 0o2; | ||
| 56 | |||
| 57 | pub const O_CREAT = arch.O_CREAT; | ||
| 58 | pub const O_EXCL = arch.O_EXCL; | ||
| 59 | pub const O_NOCTTY = arch.O_NOCTTY; | ||
| 60 | pub const O_TRUNC = arch.O_TRUNC; | ||
| 61 | pub const O_APPEND = arch.O_APPEND; | ||
| 62 | pub const O_NONBLOCK = arch.O_NONBLOCK; | ||
| 63 | pub const O_DSYNC = arch.O_DSYNC; | ||
| 64 | pub const O_SYNC = arch.O_SYNC; | ||
| 65 | pub const O_RSYNC = arch.O_RSYNC; | ||
| 66 | pub const O_DIRECTORY = arch.O_DIRECTORY; | ||
| 67 | pub const O_NOFOLLOW = arch.O_NOFOLLOW; | ||
| 68 | pub const O_CLOEXEC = arch.O_CLOEXEC; | ||
| 69 | |||
| 70 | pub const O_ASYNC = arch.O_ASYNC; | ||
| 71 | pub const O_DIRECT = arch.O_DIRECT; | ||
| 72 | pub const O_LARGEFILE = arch.O_LARGEFILE; | ||
| 73 | pub const O_NOATIME = arch.O_NOATIME; | ||
| 74 | pub const O_PATH = arch.O_PATH; | ||
| 75 | pub const O_TMPFILE = arch.O_TMPFILE; | ||
| 76 | pub const O_NDELAY = arch.O_NDELAY; | ||
| 77 | |||
| 142 | const SIG_BLOCK = 0; | 78 | const SIG_BLOCK = 0; |
| 143 | const SIG_UNBLOCK = 1; | 79 | const SIG_UNBLOCK = 1; |
| 144 | const SIG_SETMASK = 2; | 80 | const SIG_SETMASK = 2; |
| 145 | 81 | ||
| 146 | const syscall0 = switch (@compile_var("arch")) { | ||
| 147 | x86_64 => x86_64_syscall0, | ||
| 148 | i386 => i386_syscall0, | ||
| 149 | else => unreachable{}, | ||
| 150 | }; | ||
| 151 | const syscall1 = switch (@compile_var("arch")) { | ||
| 152 | x86_64 => x86_64_syscall1, | ||
| 153 | i386 => i386_syscall1, | ||
| 154 | else => unreachable{}, | ||
| 155 | }; | ||
| 156 | const syscall2 = switch (@compile_var("arch")) { | ||
| 157 | x86_64 => x86_64_syscall2, | ||
| 158 | i386 => i386_syscall2, | ||
| 159 | else => unreachable{}, | ||
| 160 | }; | ||
| 161 | const syscall3 = switch (@compile_var("arch")) { | ||
| 162 | x86_64 => x86_64_syscall3, | ||
| 163 | i386 => i386_syscall3, | ||
| 164 | else => unreachable{}, | ||
| 165 | }; | ||
| 166 | const syscall4 = switch (@compile_var("arch")) { | ||
| 167 | x86_64 => x86_64_syscall4, | ||
| 168 | i386 => i386_syscall4, | ||
| 169 | else => unreachable{}, | ||
| 170 | }; | ||
| 171 | const syscall6 = switch (@compile_var("arch")) { | ||
| 172 | x86_64 => x86_64_syscall6, | ||
| 173 | i386 => i386_syscall6, | ||
| 174 | else => unreachable{}, | ||
| 175 | }; | ||
| 176 | |||
| 177 | fn x86_64_syscall0(number: isize) -> isize { | ||
| 178 | asm volatile ("syscall" | ||
| 179 | : [ret] "={rax}" (-> isize) | ||
| 180 | : [number] "{rax}" (number) | ||
| 181 | : "rcx", "r11") | ||
| 182 | } | ||
| 183 | |||
| 184 | fn 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 | |||
| 192 | fn 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 | |||
| 201 | fn 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 | |||
| 211 | fn 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 | |||
| 222 | fn 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 | |||
| 235 | fn i386_syscall0(number: isize) -> isize { | ||
| 236 | asm volatile ("int $0x80" | ||
| 237 | : [ret] "={eax}" (-> isize) | ||
| 238 | : [number] "{eax}" (number)) | ||
| 239 | } | ||
| 240 | |||
| 241 | fn 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 | |||
| 248 | fn 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 | |||
| 256 | fn 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 | |||
| 265 | fn 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 | |||
| 275 | fn 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 | |||
| 287 | pub fn mmap(address: ?&u8, length: isize, prot: isize, flags: isize, fd: isize, offset: isize) -> isize { | 82 | pub fn mmap(address: ?&u8, length: isize, prot: isize, flags: isize, fd: isize, offset: isize) -> isize { |
| 288 | // TODO ability to cast maybe pointer to isize | 83 | // TODO ability to cast maybe pointer to isize |
| 289 | const addr = if (const unwrapped ?= address) isize(unwrapped) else 0; | 84 | 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) |
| 291 | } | 86 | } |
| 292 | 87 | ||
| 293 | pub fn munmap(address: &u8, length: isize) -> isize { | 88 | pub fn munmap(address: &u8, length: isize) -> isize { |
| 294 | syscall2(SYS_munmap, isize(address), length) | 89 | arch.syscall2(arch.SYS_munmap, isize(address), length) |
| 295 | } | 90 | } |
| 296 | 91 | ||
| 297 | pub fn read(fd: isize, buf: &u8, count: isize) -> isize { | 92 | pub 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) |
| 299 | } | 94 | } |
| 300 | 95 | ||
| 301 | pub fn write(fd: isize, buf: &const u8, count: isize) -> isize { | 96 | pub 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) |
| 303 | } | 98 | } |
| 304 | 99 | ||
| 305 | pub fn open(path: []u8, flags: isize, perm: isize) -> isize { | 100 | pub fn open(path: []u8, flags: isize, perm: isize) -> isize { |
| 306 | var buf: [path.len + 1]u8 = undefined; | 101 | var buf: [path.len + 1]u8 = undefined; |
| 307 | @memcpy(&buf[0], &path[0], path.len); | 102 | @memcpy(&buf[0], &path[0], path.len); |
| 308 | buf[path.len] = 0; | 103 | buf[path.len] = 0; |
| 309 | syscall3(SYS_open, isize(&buf[0]), flags, perm) | 104 | arch.syscall3(arch.SYS_open, isize(&buf[0]), flags, perm) |
| 310 | } | 105 | } |
| 311 | 106 | ||
| 312 | pub fn create(path: []u8, perm: isize) -> isize { | 107 | pub fn create(path: []u8, perm: isize) -> isize { |
| 313 | var buf: [path.len + 1]u8 = undefined; | 108 | var buf: [path.len + 1]u8 = undefined; |
| 314 | @memcpy(&buf[0], &path[0], path.len); | 109 | @memcpy(&buf[0], &path[0], path.len); |
| 315 | buf[path.len] = 0; | 110 | buf[path.len] = 0; |
| 316 | syscall2(SYS_creat, isize(&buf[0]), perm) | 111 | arch.syscall2(arch.SYS_creat, isize(&buf[0]), perm) |
| 317 | } | 112 | } |
| 318 | 113 | ||
| 319 | pub fn openat(dirfd: isize, path: []u8, flags: isize, mode: isize) -> isize { | 114 | pub fn openat(dirfd: isize, path: []u8, flags: isize, mode: isize) -> isize { |
| 320 | var buf: [path.len + 1]u8 = undefined; | 115 | var buf: [path.len + 1]u8 = undefined; |
| 321 | @memcpy(&buf[0], &path[0], path.len); | 116 | @memcpy(&buf[0], &path[0], path.len); |
| 322 | buf[path.len] = 0; | 117 | 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) |
| 324 | } | 119 | } |
| 325 | 120 | ||
| 326 | pub fn close(fd: isize) -> isize { | 121 | pub fn close(fd: isize) -> isize { |
| 327 | syscall1(SYS_close, fd) | 122 | arch.syscall1(arch.SYS_close, fd) |
| 328 | } | 123 | } |
| 329 | 124 | ||
| 330 | pub fn lseek(fd: isize, offset: isize, ref_pos: isize) -> isize { | 125 | pub 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) |
| 332 | } | 127 | } |
| 333 | 128 | ||
| 334 | pub fn exit(status: i32) -> unreachable { | 129 | pub fn exit(status: i32) -> unreachable { |
| 335 | syscall1(SYS_exit, isize(status)); | 130 | arch.syscall1(arch.SYS_exit, isize(status)); |
| 336 | unreachable{} | 131 | unreachable{} |
| 337 | } | 132 | } |
| 338 | 133 | ||
| 339 | pub fn getrandom(buf: &u8, count: isize, flags: u32) -> isize { | 134 | pub 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)) |
| 341 | } | 136 | } |
| 342 | 137 | ||
| 343 | pub fn kill(pid: i32, sig: i32) -> i32 { | 138 | pub fn kill(pid: i32, sig: i32) -> i32 { |
| 344 | i32(syscall2(SYS_kill, pid, sig)) | 139 | i32(arch.syscall2(arch.SYS_kill, pid, sig)) |
| 345 | } | 140 | } |
| 346 | 141 | ||
| 347 | const NSIG = 65; | 142 | const NSIG = 65; |
| ... | @@ -352,20 +147,20 @@ const app_mask = []u8 { 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, }; | ... | @@ -352,20 +147,20 @@ const app_mask = []u8 { 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, }; |
| 352 | pub fn raise(sig: i32) -> i32 { | 147 | pub fn raise(sig: i32) -> i32 { |
| 353 | var set: sigset_t = undefined; | 148 | var set: sigset_t = undefined; |
| 354 | block_app_signals(&set); | 149 | block_app_signals(&set); |
| 355 | const tid = i32(syscall0(SYS_gettid)); | 150 | const tid = i32(arch.syscall0(arch.SYS_gettid)); |
| 356 | const ret = i32(syscall2(SYS_tkill, tid, sig)); | 151 | const ret = i32(arch.syscall2(arch.SYS_tkill, tid, sig)); |
| 357 | restore_signals(&set); | 152 | restore_signals(&set); |
| 358 | return ret; | 153 | return ret; |
| 359 | } | 154 | } |
| 360 | 155 | ||
| 361 | fn block_all_signals(set: &sigset_t) { | 156 | fn 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); |
| 363 | } | 158 | } |
| 364 | 159 | ||
| 365 | fn block_app_signals(set: &sigset_t) { | 160 | fn 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); |
| 367 | } | 162 | } |
| 368 | 163 | ||
| 369 | fn restore_signals(set: &sigset_t) { | 164 | fn 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); |
| 371 | } | 166 | } |
std/linux_i386.zig created+92| ... | @@ -0,0 +1,92 @@ | ||
| 1 | pub const O_CREAT = 0o100; | ||
| 2 | pub const O_EXCL = 0o200; | ||
| 3 | pub const O_NOCTTY = 0o400; | ||
| 4 | pub const O_TRUNC = 0o1000; | ||
| 5 | pub const O_APPEND = 0o2000; | ||
| 6 | pub const O_NONBLOCK = 0o4000; | ||
| 7 | pub const O_DSYNC = 0o10000; | ||
| 8 | pub const O_SYNC = 0o4010000; | ||
| 9 | pub const O_RSYNC = 0o4010000; | ||
| 10 | pub const O_DIRECTORY = 0o200000; | ||
| 11 | pub const O_NOFOLLOW = 0o400000; | ||
| 12 | pub const O_CLOEXEC = 0o2000000; | ||
| 13 | |||
| 14 | pub const O_ASYNC = 0o20000; | ||
| 15 | pub const O_DIRECT = 0o40000; | ||
| 16 | pub const O_LARGEFILE = 0o100000; | ||
| 17 | pub const O_NOATIME = 0o1000000; | ||
| 18 | pub const O_PATH = 0o10000000; | ||
| 19 | pub const O_TMPFILE = 0o20200000; | ||
| 20 | pub const O_NDELAY = O_NONBLOCK; | ||
| 21 | |||
| 22 | pub const F_DUPFD = 0; | ||
| 23 | pub const F_GETFD = 1; | ||
| 24 | pub const F_SETFD = 2; | ||
| 25 | pub const F_GETFL = 3; | ||
| 26 | pub const F_SETFL = 4; | ||
| 27 | |||
| 28 | pub const F_SETOWN = 8; | ||
| 29 | pub const F_GETOWN = 9; | ||
| 30 | pub const F_SETSIG = 10; | ||
| 31 | pub const F_GETSIG = 11; | ||
| 32 | |||
| 33 | pub const F_GETLK = 12; | ||
| 34 | pub const F_SETLK = 13; | ||
| 35 | pub const F_SETLKW = 14; | ||
| 36 | |||
| 37 | pub const F_SETOWN_EX = 15; | ||
| 38 | pub const F_GETOWN_EX = 16; | ||
| 39 | |||
| 40 | pub const F_GETOWNER_UIDS = 17; | ||
| 41 | |||
| 42 | pub fn syscall0(number: isize) -> isize { | ||
| 43 | asm volatile ("int $0x80" | ||
| 44 | : [ret] "={eax}" (-> isize) | ||
| 45 | : [number] "{eax}" (number)) | ||
| 46 | } | ||
| 47 | |||
| 48 | pub 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 | |||
| 55 | pub 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 | |||
| 63 | pub 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 | |||
| 72 | pub 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 | |||
| 82 | pub 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 @@ | ||
| 1 | pub const SYS_read = 0; | ||
| 2 | pub const SYS_write = 1; | ||
| 3 | pub const SYS_open = 2; | ||
| 4 | pub const SYS_close = 3; | ||
| 5 | pub const SYS_creat = 85; | ||
| 6 | pub const SYS_lseek = 8; | ||
| 7 | pub const SYS_mmap = 9; | ||
| 8 | pub const SYS_munmap = 11; | ||
| 9 | pub const SYS_rt_sigprocmask = 14; | ||
| 10 | pub const SYS_exit = 60; | ||
| 11 | pub const SYS_kill = 62; | ||
| 12 | pub const SYS_getgid = 104; | ||
| 13 | pub const SYS_gettid = 186; | ||
| 14 | pub const SYS_tkill = 200; | ||
| 15 | pub const SYS_tgkill = 234; | ||
| 16 | pub const SYS_openat = 257; | ||
| 17 | pub const SYS_getrandom = 318; | ||
| 18 | |||
| 19 | pub const O_CREAT = 0o100; | ||
| 20 | pub const O_EXCL = 0o200; | ||
| 21 | pub const O_NOCTTY = 0o400; | ||
| 22 | pub const O_TRUNC = 0o1000; | ||
| 23 | pub const O_APPEND = 0o2000; | ||
| 24 | pub const O_NONBLOCK = 0o4000; | ||
| 25 | pub const O_DSYNC = 0o10000; | ||
| 26 | pub const O_SYNC = 0o4010000; | ||
| 27 | pub const O_RSYNC = 0o4010000; | ||
| 28 | pub const O_DIRECTORY = 0o200000; | ||
| 29 | pub const O_NOFOLLOW = 0o400000; | ||
| 30 | pub const O_CLOEXEC = 0o2000000; | ||
| 31 | |||
| 32 | pub const O_ASYNC = 0o20000; | ||
| 33 | pub const O_DIRECT = 0o40000; | ||
| 34 | pub const O_LARGEFILE = 0; | ||
| 35 | pub const O_NOATIME = 0o1000000; | ||
| 36 | pub const O_PATH = 0o10000000; | ||
| 37 | pub const O_TMPFILE = 0o20200000; | ||
| 38 | pub const O_NDELAY = O_NONBLOCK; | ||
| 39 | |||
| 40 | pub const F_DUPFD = 0; | ||
| 41 | pub const F_GETFD = 1; | ||
| 42 | pub const F_SETFD = 2; | ||
| 43 | pub const F_GETFL = 3; | ||
| 44 | pub const F_SETFL = 4; | ||
| 45 | |||
| 46 | pub const F_SETOWN = 8; | ||
| 47 | pub const F_GETOWN = 9; | ||
| 48 | pub const F_SETSIG = 10; | ||
| 49 | pub const F_GETSIG = 11; | ||
| 50 | |||
| 51 | pub const F_GETLK = 5; | ||
| 52 | pub const F_SETLK = 6; | ||
| 53 | pub const F_SETLKW = 7; | ||
| 54 | |||
| 55 | pub const F_SETOWN_EX = 15; | ||
| 56 | pub const F_GETOWN_EX = 16; | ||
| 57 | |||
| 58 | pub const F_GETOWNER_UIDS = 17; | ||
| 59 | |||
| 60 | pub fn syscall0(number: isize) -> isize { | ||
| 61 | asm volatile ("syscall" | ||
| 62 | : [ret] "={rax}" (-> isize) | ||
| 63 | : [number] "{rax}" (number) | ||
| 64 | : "rcx", "r11") | ||
| 65 | } | ||
| 66 | |||
| 67 | pub 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 | |||
| 75 | pub 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 | |||
| 84 | pub 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 | |||
| 94 | pub 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 | |||
| 105 | pub 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; | ... | @@ -9,19 +9,19 @@ extern var zig_test_fn_list: []TestFn; |
| 9 | 9 | ||
| 10 | pub fn run_tests() -> %void { | 10 | pub fn run_tests() -> %void { |
| 11 | for (zig_test_fn_list) |test_fn, i| { | 11 | for (zig_test_fn_list) |test_fn, i| { |
| 12 | %%io.stderr.print_str("Test "); | 12 | %%io.stderr.write("Test "); |
| 13 | %%io.stderr.print_i64(i + 1); | 13 | %%io.stderr.print_i64(i + 1); |
| 14 | %%io.stderr.print_str("/"); | 14 | %%io.stderr.write("/"); |
| 15 | %%io.stderr.print_i64(zig_test_fn_list.len); | 15 | %%io.stderr.print_i64(zig_test_fn_list.len); |
| 16 | %%io.stderr.print_str(" "); | 16 | %%io.stderr.write(" "); |
| 17 | %%io.stderr.print_str(test_fn.name); | 17 | %%io.stderr.write(test_fn.name); |
| 18 | %%io.stderr.print_str("..."); | 18 | %%io.stderr.write("..."); |
| 19 | %%io.stderr.flush(); | 19 | %%io.stderr.flush(); |
| 20 | 20 | ||
| 21 | test_fn.func(); | 21 | test_fn.func(); |
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | %%io.stderr.print_str("OK\n"); | 24 | %%io.stderr.write("OK\n"); |
| 25 | %%io.stderr.flush(); | 25 | %%io.stderr.flush(); |
| 26 | } | 26 | } |
| 27 | } | 27 | } |
test/self_hosted.zig+1-12| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | // test std library | 1 | // test std library |
| 2 | const std = @import("std"); | 2 | use @import("std"); |
| 3 | 3 | ||
| 4 | #attribute("test") | 4 | #attribute("test") |
| 5 | fn empty_function() {} | 5 | fn empty_function() {} |
| ... | @@ -554,14 +554,3 @@ fn mem_alloc(T: type)(n: isize) -> %[]T { | ... | @@ -554,14 +554,3 @@ fn mem_alloc(T: type)(n: isize) -> %[]T { |
| 554 | fn mem_free(T: type)(mem: []T) { } | 554 | fn mem_free(T: type)(mem: []T) { } |
| 555 | 555 | ||
| 556 | 556 | ||
| 557 | fn assert(b: bool) { | ||
| 558 | if (!b) unreachable{} | ||
| 559 | } | ||
| 560 | |||
| 561 | fn 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 | } |