| author | |
| committer | |
| log | 69132bdeda9f9ee672d883fd442b6158d8725422 |
| tree | 29b1bfd8acbab82442f83bbad2d06d0eea0d7f35 |
| parent | 5f89393acb0e3626d942302ca24de14349850040 |
* comptime fn call
* is_comptime doesn't count as an instruction dependency
* update more std code to latest zig18 files changed, 101 insertions(+), 81 deletions(-)
doc/langref.md+1-1| ... | ... | @@ -123,7 +123,7 @@ MultiplyOperator = "*" | "/" | "%" | "**" | "*%" |
| 123 | 123 | |
| 124 | 124 | PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression |
| 125 | 125 | |
| 126 | SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) | |
| 126 | SuffixOpExpression = option("inline") PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) | |
| 127 | 127 | |
| 128 | 128 | FieldAccessExpression = "." Symbol |
| 129 | 129 |
src/all_types.hpp+2-1| ... | ... | @@ -445,6 +445,7 @@ struct AstNodeFnCallExpr { |
| 445 | 445 | AstNode *fn_ref_expr; |
| 446 | 446 | ZigList<AstNode *> params; |
| 447 | 447 | bool is_builtin; |
| 448 | bool is_comptime; | |
| 448 | 449 | }; |
| 449 | 450 | |
| 450 | 451 | struct AstNodeArrayAccessExpr { |
| ... | ... | @@ -1669,7 +1670,7 @@ struct IrInstructionCall { |
| 1669 | 1670 | FnTableEntry *fn_entry; |
| 1670 | 1671 | size_t arg_count; |
| 1671 | 1672 | IrInstruction **args; |
| 1672 | bool is_inline; | |
| 1673 | bool is_comptime; | |
| 1673 | 1674 | LLVMValueRef tmp_ptr; |
| 1674 | 1675 | }; |
| 1675 | 1676 |
src/ir.cpp+26-17| ... | ... | @@ -808,13 +808,15 @@ static IrInstruction *ir_build_enum_field_ptr_from(IrBuilder *irb, IrInstruction |
| 808 | 808 | } |
| 809 | 809 | |
| 810 | 810 | static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 811 | FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args) | |
| 811 | FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, | |
| 812 | bool is_comptime) | |
| 812 | 813 | { |
| 813 | 814 | IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); |
| 814 | 815 | call_instruction->fn_entry = fn_entry; |
| 815 | 816 | call_instruction->fn_ref = fn_ref; |
| 816 | call_instruction->arg_count = arg_count; | |
| 817 | call_instruction->is_comptime = is_comptime; | |
| 817 | 818 | call_instruction->args = args; |
| 819 | call_instruction->arg_count = arg_count; | |
| 818 | 820 | |
| 819 | 821 | if (fn_ref) |
| 820 | 822 | ir_ref_instruction(fn_ref); |
| ... | ... | @@ -825,10 +827,11 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 825 | 827 | } |
| 826 | 828 | |
| 827 | 829 | static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction, |
| 828 | FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args) | |
| 830 | FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, | |
| 831 | bool is_comptime) | |
| 829 | 832 | { |
| 830 | 833 | IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope, |
| 831 | old_instruction->source_node, fn_entry, fn_ref, arg_count, args); | |
| 834 | old_instruction->source_node, fn_entry, fn_ref, arg_count, args, is_comptime); | |
| 832 | 835 | ir_link_new_instruction(new_instruction, old_instruction); |
| 833 | 836 | return new_instruction; |
| 834 | 837 | } |
| ... | ... | @@ -1950,16 +1953,12 @@ static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode |
| 1950 | 1953 | } |
| 1951 | 1954 | |
| 1952 | 1955 | static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) { |
| 1953 | switch (index) { | |
| 1954 | case 0: return instruction->is_comptime; | |
| 1955 | default: return nullptr; | |
| 1956 | } | |
| 1956 | return nullptr; | |
| 1957 | 1957 | } |
| 1958 | 1958 | |
| 1959 | 1959 | static IrInstruction *ir_instruction_condbr_get_dep(IrInstructionCondBr *instruction, size_t index) { |
| 1960 | 1960 | switch (index) { |
| 1961 | 1961 | case 0: return instruction->condition; |
| 1962 | case 1: return instruction->is_comptime; | |
| 1963 | 1962 | default: return nullptr; |
| 1964 | 1963 | } |
| 1965 | 1964 | } |
| ... | ... | @@ -1967,7 +1966,6 @@ static IrInstruction *ir_instruction_condbr_get_dep(IrInstructionCondBr *instruc |
| 1967 | 1966 | static IrInstruction *ir_instruction_switchbr_get_dep(IrInstructionSwitchBr *instruction, size_t index) { |
| 1968 | 1967 | switch (index) { |
| 1969 | 1968 | case 0: return instruction->target_value; |
| 1970 | case 1: return instruction->is_comptime; | |
| 1971 | 1969 | } |
| 1972 | 1970 | size_t case_index = index - 2; |
| 1973 | 1971 | if (case_index < instruction->case_count) return instruction->cases[case_index].value; |
| ... | ... | @@ -3887,7 +3885,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 3887 | 3885 | args[i] = ir_gen_node(irb, arg_node, scope); |
| 3888 | 3886 | } |
| 3889 | 3887 | |
| 3890 | return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args); | |
| 3888 | bool is_comptime = node->data.fn_call_expr.is_comptime; | |
| 3889 | return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, is_comptime); | |
| 3891 | 3890 | } |
| 3892 | 3891 | |
| 3893 | 3892 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -5601,6 +5600,8 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 5601 | 5600 | IrInstruction *dep_instruction = ir_instruction_get_dep(instruction, dep_i); |
| 5602 | 5601 | if (dep_instruction == nullptr) |
| 5603 | 5602 | break; |
| 5603 | if (dep_instruction->owner_bb == old_bb) | |
| 5604 | continue; | |
| 5604 | 5605 | ir_get_new_bb(ira, dep_instruction->owner_bb); |
| 5605 | 5606 | } |
| 5606 | 5607 | } |
| ... | ... | @@ -6537,6 +6538,14 @@ static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { |
| 6537 | 6538 | return true; |
| 6538 | 6539 | } |
| 6539 | 6540 | |
| 6541 | static bool ir_resolve_comptime(IrAnalyze *ira, IrInstruction *value, bool *out) { | |
| 6542 | if (!value) { | |
| 6543 | *out = false; | |
| 6544 | return true; | |
| 6545 | } | |
| 6546 | return ir_resolve_bool(ira, value, out); | |
| 6547 | } | |
| 6548 | ||
| 6540 | 6549 | static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) { |
| 6541 | 6550 | if (value->value.type->id == TypeTableEntryIdInvalid) |
| 6542 | 6551 | return false; |
| ... | ... | @@ -7521,7 +7530,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 7521 | 7530 | |
| 7522 | 7531 | size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count; |
| 7523 | 7532 | IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, |
| 7524 | impl_fn, nullptr, impl_param_count, casted_args); | |
| 7533 | impl_fn, nullptr, impl_param_count, casted_args, false); | |
| 7525 | 7534 | |
| 7526 | 7535 | TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type; |
| 7527 | 7536 | ir_add_alloca(ira, new_call_instruction, return_type); |
| ... | ... | @@ -7574,7 +7583,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 7574 | 7583 | return ira->codegen->builtin_types.entry_invalid; |
| 7575 | 7584 | |
| 7576 | 7585 | IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, |
| 7577 | fn_entry, fn_ref, call_param_count, casted_args); | |
| 7586 | fn_entry, fn_ref, call_param_count, casted_args, false); | |
| 7578 | 7587 | |
| 7579 | 7588 | ir_add_alloca(ira, new_call_instruction, return_type); |
| 7580 | 7589 | return ir_finish_anal(ira, return_type); |
| ... | ... | @@ -7585,7 +7594,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction |
| 7585 | 7594 | if (fn_ref->value.type->id == TypeTableEntryIdInvalid) |
| 7586 | 7595 | return ira->codegen->builtin_types.entry_invalid; |
| 7587 | 7596 | |
| 7588 | bool is_inline = call_instruction->is_inline || ir_should_inline(&ira->new_irb); | |
| 7597 | bool is_inline = call_instruction->is_comptime || ir_should_inline(&ira->new_irb); | |
| 7589 | 7598 | |
| 7590 | 7599 | if (is_inline || fn_ref->value.special != ConstValSpecialRuntime) { |
| 7591 | 7600 | if (fn_ref->value.type->id == TypeTableEntryIdMetaType) { |
| ... | ... | @@ -7862,7 +7871,7 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 7862 | 7871 | IrBasicBlock *old_dest_block = br_instruction->dest_block; |
| 7863 | 7872 | |
| 7864 | 7873 | bool is_comptime; |
| 7865 | if (!ir_resolve_bool(ira, br_instruction->is_comptime->other, &is_comptime)) | |
| 7874 | if (!ir_resolve_comptime(ira, br_instruction->is_comptime->other, &is_comptime)) | |
| 7866 | 7875 | return ir_unreach_error(ira); |
| 7867 | 7876 | |
| 7868 | 7877 | if (is_comptime || old_dest_block->ref_count == 1) |
| ... | ... | @@ -7879,7 +7888,7 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct |
| 7879 | 7888 | return ir_unreach_error(ira); |
| 7880 | 7889 | |
| 7881 | 7890 | bool is_comptime; |
| 7882 | if (!ir_resolve_bool(ira, cond_br_instruction->is_comptime->other, &is_comptime)) | |
| 7891 | if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->other, &is_comptime)) | |
| 7883 | 7892 | return ir_unreach_error(ira); |
| 7884 | 7893 | |
| 7885 | 7894 | if (is_comptime || instr_is_comptime(condition)) { |
| ... | ... | @@ -9129,7 +9138,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 9129 | 9138 | size_t case_count = switch_br_instruction->case_count; |
| 9130 | 9139 | |
| 9131 | 9140 | bool is_comptime; |
| 9132 | if (!ir_resolve_bool(ira, switch_br_instruction->is_comptime->other, &is_comptime)) | |
| 9141 | if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->other, &is_comptime)) | |
| 9133 | 9142 | return ira->codegen->builtin_types.entry_invalid; |
| 9134 | 9143 | |
| 9135 | 9144 | if (is_comptime || instr_is_comptime(target_value)) { |
src/parser.cpp+16-1| ... | ... | @@ -837,7 +837,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, size_t *token_inde |
| 837 | 837 | } |
| 838 | 838 | |
| 839 | 839 | /* |
| 840 | SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) | |
| 840 | SuffixOpExpression = option("inline") PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) | |
| 841 | 841 | FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen) |
| 842 | 842 | ArrayAccessExpression : token(LBracket) Expression token(RBracket) |
| 843 | 843 | SliceExpression : token(LBracket) Expression token(Ellipsis) option(Expression) token(RBracket) option(token(Const)) |
| ... | ... | @@ -845,8 +845,22 @@ FieldAccessExpression : token(Dot) token(Symbol) |
| 845 | 845 | StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression |
| 846 | 846 | */ |
| 847 | 847 | static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 848 | Token *inline_token = &pc->tokens->at(*token_index); | |
| 849 | bool is_comptime; | |
| 850 | if (inline_token->id == TokenIdKeywordInline) { | |
| 851 | // TODO make it an error if something other than function call has the comptime keyword | |
| 852 | is_comptime = true; | |
| 853 | *token_index += 1; | |
| 854 | } else { | |
| 855 | is_comptime = false; | |
| 856 | } | |
| 857 | ||
| 858 | ||
| 848 | 859 | AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory); |
| 849 | 860 | if (!primary_expr) { |
| 861 | if (is_comptime) { | |
| 862 | *token_index -= 1; | |
| 863 | } | |
| 850 | 864 | return nullptr; |
| 851 | 865 | } |
| 852 | 866 | |
| ... | ... | @@ -857,6 +871,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, |
| 857 | 871 | |
| 858 | 872 | AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token); |
| 859 | 873 | node->data.fn_call_expr.fn_ref_expr = primary_expr; |
| 874 | node->data.fn_call_expr.is_comptime = is_comptime; | |
| 860 | 875 | ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params); |
| 861 | 876 | |
| 862 | 877 | primary_expr = node; |
std/compiler_rt.zig+2-2| ... | ... | @@ -214,7 +214,7 @@ |
| 214 | 214 | //} |
| 215 | 215 | // |
| 216 | 216 | //fn test_umoddi3() { |
| 217 | // @setFnTest(this, true); | |
| 217 | // @setFnTest(this); | |
| 218 | 218 | // |
| 219 | 219 | // test_one_umoddi3(0, 1, 0); |
| 220 | 220 | // test_one_umoddi3(2, 1, 0); |
| ... | ... | @@ -229,7 +229,7 @@ |
| 229 | 229 | //} |
| 230 | 230 | // |
| 231 | 231 | //fn test_udivmoddi4() { |
| 232 | // @setFnTest(this, true); | |
| 232 | // @setFnTest(this); | |
| 233 | 233 | // |
| 234 | 234 | // const cases = [][4]du_int { |
| 235 | 235 | // []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000}, |
std/cstr.zig+9-9| ... | ... | @@ -15,12 +15,12 @@ pub fn len(ptr: &const u8) -> usize { |
| 15 | 15 | pub fn cmp(a: &const u8, b: &const u8) -> i8 { |
| 16 | 16 | var index: usize = 0; |
| 17 | 17 | while (a[index] == b[index] && a[index] != 0; index += 1) {} |
| 18 | return if (a[index] > b[index]) { | |
| 19 | 1 | |
| 18 | if (a[index] > b[index]) { | |
| 19 | return 1; | |
| 20 | 20 | } else if (a[index] < b[index]) { |
| 21 | -1 | |
| 21 | return -1; | |
| 22 | 22 | } else { |
| 23 | 0 | |
| 23 | return 0; | |
| 24 | 24 | }; |
| 25 | 25 | } |
| 26 | 26 | |
| ... | ... | @@ -127,7 +127,7 @@ pub const CBuf = struct { |
| 127 | 127 | }; |
| 128 | 128 | |
| 129 | 129 | fn testSimpleCBuf() { |
| 130 | @setFnTest(this, true); | |
| 130 | @setFnTest(this); | |
| 131 | 131 | |
| 132 | 132 | var buf = %%CBuf.initEmpty(&debug.global_allocator); |
| 133 | 133 | assert(buf.len() == 0); |
| ... | ... | @@ -148,13 +148,13 @@ fn testSimpleCBuf() { |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 | fn testCompileTimeStrCmp() { |
| 151 | @setFnTest(this, true); | |
| 151 | @setFnTest(this); | |
| 152 | 152 | |
| 153 | assert(@constEval(cmp(c"aoeu", c"aoez") == -1)); | |
| 153 | assert(@staticEval(cmp(c"aoeu", c"aoez") == -1)); | |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | 156 | fn testCompileTimeStrLen() { |
| 157 | @setFnTest(this, true); | |
| 157 | @setFnTest(this); | |
| 158 | 158 | |
| 159 | assert(@constEval(len(c"123456789") == 9)); | |
| 159 | assert(@staticEval(len(c"123456789") == 9)); | |
| 160 | 160 | } |
std/debug.zig+7-7| ... | ... | @@ -35,7 +35,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void { |
| 35 | 35 | defer st.self_exe_stream.close() %% {}; |
| 36 | 36 | |
| 37 | 37 | %return st.elf.openStream(&global_allocator, &st.self_exe_stream); |
| 38 | defer %return st.elf.close(); | |
| 38 | defer st.elf.close(); | |
| 39 | 39 | |
| 40 | 40 | st.debug_info = (%return st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo; |
| 41 | 41 | st.debug_abbrev = (%return st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo; |
| ... | ... | @@ -154,7 +154,7 @@ const Die = struct { |
| 154 | 154 | fn getAttrAddr(self: &const Die, id: u64) -> %u64 { |
| 155 | 155 | const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo; |
| 156 | 156 | return switch (*form_value) { |
| 157 | Address => |value| value, | |
| 157 | FormValue.Address => |value| value, | |
| 158 | 158 | else => error.InvalidDebugInfo, |
| 159 | 159 | }; |
| 160 | 160 | } |
| ... | ... | @@ -162,7 +162,7 @@ const Die = struct { |
| 162 | 162 | fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 { |
| 163 | 163 | const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo; |
| 164 | 164 | return switch (*form_value) { |
| 165 | Const => |value| value.asUnsignedLe(), | |
| 165 | FormValue.Const => |value| value.asUnsignedLe(), | |
| 166 | 166 | else => error.InvalidDebugInfo, |
| 167 | 167 | }; |
| 168 | 168 | } |
| ... | ... | @@ -170,8 +170,8 @@ const Die = struct { |
| 170 | 170 | fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) -> %[]u8 { |
| 171 | 171 | const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo; |
| 172 | 172 | return switch (*form_value) { |
| 173 | String => |value| value, | |
| 174 | StrPtr => |offset| getString(st, offset), | |
| 173 | FormValue.String => |value| value, | |
| 174 | FormValue.StrPtr => |offset| getString(st, offset), | |
| 175 | 175 | else => error.InvalidDebugInfo, |
| 176 | 176 | } |
| 177 | 177 | } |
| ... | ... | @@ -406,8 +406,8 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { |
| 406 | 406 | |
| 407 | 407 | const high_pc_value = compile_unit_die.getAttr(DW.AT_high_pc) ?? return error.MissingDebugInfo; |
| 408 | 408 | const pc_end = switch (*high_pc_value) { |
| 409 | Address => |value| value, | |
| 410 | Const => |value| { | |
| 409 | FormValue.Address => |value| value, | |
| 410 | FormValue.Const => |value| { | |
| 411 | 411 | const offset = %return value.asUnsignedLe(); |
| 412 | 412 | low_pc + offset |
| 413 | 413 | }, |
std/elf.zig+8-4| ... | ... | @@ -230,9 +230,11 @@ pub const Elf = struct { |
| 230 | 230 | } |
| 231 | 231 | } |
| 232 | 232 | |
| 233 | pub fn close(elf: &Elf) -> %void { | |
| 233 | pub fn close(elf: &Elf) { | |
| 234 | 234 | elf.allocator.free(SectionHeader, elf.section_headers); |
| 235 | if (elf.auto_close_stream) %return elf.in_stream.close(); | |
| 235 | ||
| 236 | if (elf.auto_close_stream) | |
| 237 | elf.in_stream.close(); | |
| 236 | 238 | } |
| 237 | 239 | |
| 238 | 240 | pub fn findSection(elf: &Elf, name: []u8) -> %?&SectionHeader { |
| ... | ... | @@ -247,8 +249,10 @@ pub const Elf = struct { |
| 247 | 249 | if (target_c == 0 || expected_c != target_c) goto next_section; |
| 248 | 250 | } |
| 249 | 251 | |
| 250 | const null_byte = %return elf.in_stream.readByte(); | |
| 251 | if (null_byte == 0) return (?&SectionHeader)(section); | |
| 252 | { | |
| 253 | const null_byte = %return elf.in_stream.readByte(); | |
| 254 | if (null_byte == 0) return (?&SectionHeader)(section); | |
| 255 | } | |
| 252 | 256 | |
| 253 | 257 | next_section: |
| 254 | 258 | } |
std/hash_map.zig+1-1| ... | ... | @@ -216,7 +216,7 @@ pub fn HashMap(inline K: type, inline V: type, inline hash: fn(key: K)->u32, |
| 216 | 216 | } |
| 217 | 217 | |
| 218 | 218 | fn basicHashMapTest() { |
| 219 | @setFnTest(this, true); | |
| 219 | @setFnTest(this); | |
| 220 | 220 | |
| 221 | 221 | var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined; |
| 222 | 222 | map.init(&debug.global_allocator); |
std/io.zig+12-19| ... | ... | @@ -137,19 +137,12 @@ pub const OutStream = struct { |
| 137 | 137 | } |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | pub fn close(self: &OutStream) -> %void { | |
| 140 | pub fn close(self: &OutStream) { | |
| 141 | 141 | while (true) { |
| 142 | 142 | const close_ret = system.close(self.fd); |
| 143 | 143 | const close_err = system.getErrno(close_ret); |
| 144 | if (close_err > 0) { | |
| 145 | return switch (close_err) { | |
| 146 | errno.EINTR => continue, | |
| 147 | ||
| 148 | errno.EIO => error.Io, | |
| 149 | errno.EBADF => error.BadFd, | |
| 150 | else => error.Unexpected, | |
| 151 | } | |
| 152 | } | |
| 144 | if (close_err > 0 && close_err == errno.EINTR) | |
| 145 | continue; | |
| 153 | 146 | return; |
| 154 | 147 | } |
| 155 | 148 | } |
| ... | ... | @@ -163,7 +156,7 @@ pub const InStream = struct { |
| 163 | 156 | /// Call close to clean up. |
| 164 | 157 | pub fn open(is: &InStream, path: []const u8) -> %void { |
| 165 | 158 | switch (@compileVar("os")) { |
| 166 | linux, darwin => { | |
| 159 | Os.linux, Os.darwin => { | |
| 167 | 160 | while (true) { |
| 168 | 161 | const result = system.open(path, system.O_LARGEFILE|system.O_RDONLY, 0); |
| 169 | 162 | const err = system.getErrno(result); |
| ... | ... | @@ -202,7 +195,7 @@ pub const InStream = struct { |
| 202 | 195 | /// you must use the open() function. |
| 203 | 196 | pub fn close(is: &InStream) -> %void { |
| 204 | 197 | switch (@compileVar("os")) { |
| 205 | linux, darwin => { | |
| 198 | Os.linux, Os.darwin => { | |
| 206 | 199 | while (true) { |
| 207 | 200 | const close_ret = system.close(is.fd); |
| 208 | 201 | const close_err = system.getErrno(close_ret); |
| ... | ... | @@ -226,7 +219,7 @@ pub const InStream = struct { |
| 226 | 219 | /// the stream reached End Of File. |
| 227 | 220 | pub fn read(is: &InStream, buf: []u8) -> %usize { |
| 228 | 221 | switch (@compileVar("os")) { |
| 229 | linux, darwin => { | |
| 222 | Os.linux, Os.darwin => { | |
| 230 | 223 | var index: usize = 0; |
| 231 | 224 | while (index < buf.len) { |
| 232 | 225 | const amt_read = system.read(is.fd, &buf[index], buf.len - index); |
| ... | ... | @@ -288,7 +281,7 @@ pub const InStream = struct { |
| 288 | 281 | |
| 289 | 282 | pub fn seekForward(is: &InStream, amount: usize) -> %void { |
| 290 | 283 | switch (@compileVar("os")) { |
| 291 | linux, darwin => { | |
| 284 | Os.linux, Os.darwin => { | |
| 292 | 285 | const result = system.lseek(is.fd, amount, system.SEEK_CUR); |
| 293 | 286 | const err = system.getErrno(result); |
| 294 | 287 | if (err > 0) { |
| ... | ... | @@ -308,7 +301,7 @@ pub const InStream = struct { |
| 308 | 301 | |
| 309 | 302 | pub fn seekTo(is: &InStream, pos: usize) -> %void { |
| 310 | 303 | switch (@compileVar("os")) { |
| 311 | linux, darwin => { | |
| 304 | Os.linux, Os.darwin => { | |
| 312 | 305 | const result = system.lseek(is.fd, pos, system.SEEK_SET); |
| 313 | 306 | const err = system.getErrno(result); |
| 314 | 307 | if (err > 0) { |
| ... | ... | @@ -328,7 +321,7 @@ pub const InStream = struct { |
| 328 | 321 | |
| 329 | 322 | pub fn getPos(is: &InStream) -> %usize { |
| 330 | 323 | switch (@compileVar("os")) { |
| 331 | linux, darwin => { | |
| 324 | Os.linux, Os.darwin => { | |
| 332 | 325 | const result = system.lseek(is.fd, 0, system.SEEK_CUR); |
| 333 | 326 | const err = system.getErrno(result); |
| 334 | 327 | if (err > 0) { |
| ... | ... | @@ -424,7 +417,7 @@ fn bufPrintUnsigned(inline T: type, out_buf: []u8, x: T) -> usize { |
| 424 | 417 | } |
| 425 | 418 | |
| 426 | 419 | fn parseU64DigitTooBig() { |
| 427 | @setFnTest(this, true); | |
| 420 | @setFnTest(this); | |
| 428 | 421 | |
| 429 | 422 | parseUnsigned(u64, "123a", 10) %% |err| { |
| 430 | 423 | if (err == error.InvalidChar) return; |
| ... | ... | @@ -435,10 +428,10 @@ fn parseU64DigitTooBig() { |
| 435 | 428 | |
| 436 | 429 | pub fn openSelfExe(stream: &InStream) -> %void { |
| 437 | 430 | switch (@compileVar("os")) { |
| 438 | linux => { | |
| 431 | Os.linux => { | |
| 439 | 432 | %return stream.open("/proc/self/exe"); |
| 440 | 433 | }, |
| 441 | darwin => { | |
| 434 | Os.darwin => { | |
| 442 | 435 | %%stderr.printf("TODO: openSelfExe on Darwin\n"); |
| 443 | 436 | os.abort(); |
| 444 | 437 | }, |
std/linux.zig+3-3| ... | ... | @@ -261,7 +261,7 @@ pub fn open_c(path: &const u8, flags: usize, perm: usize) -> usize { |
| 261 | 261 | } |
| 262 | 262 | |
| 263 | 263 | pub fn open(path: []const u8, flags: usize, perm: usize) -> usize { |
| 264 | var buf: [path.len + 1]u8 = undefined; | |
| 264 | const buf = @alloca(u8, path.len + 1); | |
| 265 | 265 | @memcpy(&buf[0], &path[0], path.len); |
| 266 | 266 | buf[path.len] = 0; |
| 267 | 267 | return open_c(buf.ptr, flags, perm); |
| ... | ... | @@ -272,7 +272,7 @@ pub fn create_c(path: &const u8, perm: usize) -> usize { |
| 272 | 272 | } |
| 273 | 273 | |
| 274 | 274 | pub fn create(path: []const u8, perm: usize) -> usize { |
| 275 | var buf: [path.len + 1]u8 = undefined; | |
| 275 | const buf = @alloca(u8, path.len + 1); | |
| 276 | 276 | @memcpy(&buf[0], &path[0], path.len); |
| 277 | 277 | buf[path.len] = 0; |
| 278 | 278 | return create_c(buf.ptr, perm); |
| ... | ... | @@ -283,7 +283,7 @@ pub fn openat_c(dirfd: i32, path: &const u8, flags: usize, mode: usize) -> usize |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | pub fn openat(dirfd: i32, path: []const u8, flags: usize, mode: usize) -> usize { |
| 286 | var buf: [path.len + 1]u8 = undefined; | |
| 286 | const buf = @alloca(u8, path.len + 1); | |
| 287 | 287 | @memcpy(&buf[0], &path[0], path.len); |
| 288 | 288 | buf[path.len] = 0; |
| 289 | 289 | return openat_c(dirfd, buf.ptr, flags, mode); |
std/list.zig+1-1| ... | ... | @@ -52,7 +52,7 @@ pub fn List(inline T: type) -> type{ |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | fn basicListTest() { |
| 55 | @setFnTest(this, true); | |
| 55 | @setFnTest(this); | |
| 56 | 56 | |
| 57 | 57 | var list = List(i32).init(&debug.global_allocator); |
| 58 | 58 | defer list.deinit(); |
std/mem.zig+1-1| ... | ... | @@ -83,7 +83,7 @@ pub fn sliceAsInt(buf: []u8, is_be: bool, inline T: type) -> T { |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | 85 | fn testSliceAsInt() { |
| 86 | @setFnTest(this, true); | |
| 86 | @setFnTest(this); | |
| 87 | 87 | { |
| 88 | 88 | const buf = []u8{0x00, 0x00, 0x12, 0x34}; |
| 89 | 89 | const answer = sliceAsInt(buf[0...], true, u64); |
std/net.zig+3-5| ... | ... | @@ -181,8 +181,6 @@ error JunkAtEnd; |
| 181 | 181 | error Incomplete; |
| 182 | 182 | |
| 183 | 183 | fn parseIp6(buf: []const u8) -> %Address { |
| 184 | @setFnStaticEval(this, false); | |
| 185 | ||
| 186 | 184 | var result: Address = undefined; |
| 187 | 185 | result.family = linux.AF_INET6; |
| 188 | 186 | result.scope_id = 0; |
| ... | ... | @@ -320,7 +318,7 @@ fn parseIp4(buf: []const u8) -> %u32 { |
| 320 | 318 | |
| 321 | 319 | |
| 322 | 320 | fn testParseIp4() { |
| 323 | @setFnTest(this, true); | |
| 321 | @setFnTest(this); | |
| 324 | 322 | |
| 325 | 323 | assert(%%parseIp4("127.0.0.1") == endian.swapIfLe(u32, 0x7f000001)); |
| 326 | 324 | switch (parseIp4("256.0.0.1")) { Overflow => {}, else => @unreachable(), } |
| ... | ... | @@ -331,7 +329,7 @@ fn testParseIp4() { |
| 331 | 329 | } |
| 332 | 330 | |
| 333 | 331 | fn testParseIp6() { |
| 334 | @setFnTest(this, true); | |
| 332 | @setFnTest(this); | |
| 335 | 333 | |
| 336 | 334 | { |
| 337 | 335 | const addr = %%parseIp6("FF01:0:0:0:0:0:0:FB"); |
| ... | ... | @@ -342,7 +340,7 @@ fn testParseIp6() { |
| 342 | 340 | } |
| 343 | 341 | |
| 344 | 342 | fn testLookupSimpleIp() { |
| 345 | @setFnTest(this, true); | |
| 343 | @setFnTest(this); | |
| 346 | 344 | |
| 347 | 345 | { |
| 348 | 346 | var addrs_buf: [5]Address = undefined; |
std/os.zig+3-3| ... | ... | @@ -10,8 +10,8 @@ error Unexpected; |
| 10 | 10 | pub fn getRandomBytes(buf: []u8) -> %void { |
| 11 | 11 | while (true) { |
| 12 | 12 | const ret = switch (@compileVar("os")) { |
| 13 | linux => system.getrandom(buf.ptr, buf.len, 0), | |
| 14 | darwin => system.getrandom(buf.ptr, buf.len), | |
| 13 | Os.linux => system.getrandom(buf.ptr, buf.len, 0), | |
| 14 | Os.darwin => system.getrandom(buf.ptr, buf.len), | |
| 15 | 15 | else => @compileError("unsupported os"), |
| 16 | 16 | }; |
| 17 | 17 | const err = system.getErrno(ret); |
| ... | ... | @@ -29,7 +29,7 @@ pub fn getRandomBytes(buf: []u8) -> %void { |
| 29 | 29 | |
| 30 | 30 | pub coldcc fn abort() -> unreachable { |
| 31 | 31 | switch (@compileVar("os")) { |
| 32 | linux, darwin => { | |
| 32 | Os.linux, Os.darwin => { | |
| 33 | 33 | system.raise(system.SIGABRT); |
| 34 | 34 | system.raise(system.SIGKILL); |
| 35 | 35 | while (true) {} |
std/rand.zig+4-4| ... | ... | @@ -87,7 +87,7 @@ pub const Rand = struct { |
| 87 | 87 | } else if (T == f64) { |
| 88 | 88 | 9007199254740992 |
| 89 | 89 | } else { |
| 90 | @compileError("unknown floating point type" ++ @typeName(T)) | |
| 90 | @compileError("unknown floating point type") | |
| 91 | 91 | }; |
| 92 | 92 | return T(r.rangeUnsigned(int_type, 0, precision)) / T(precision); |
| 93 | 93 | } |
| ... | ... | @@ -156,7 +156,7 @@ fn MersenneTwister( |
| 156 | 156 | } |
| 157 | 157 | |
| 158 | 158 | fn testFloat32() { |
| 159 | @setFnTest(this, true); | |
| 159 | @setFnTest(this); | |
| 160 | 160 | |
| 161 | 161 | var r: Rand = undefined; |
| 162 | 162 | r.init(42); |
| ... | ... | @@ -169,7 +169,7 @@ fn testFloat32() { |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | 171 | fn testMT19937_64() { |
| 172 | @setFnTest(this, true); | |
| 172 | @setFnTest(this); | |
| 173 | 173 | |
| 174 | 174 | var rng: MT19937_64 = undefined; |
| 175 | 175 | rng.init(rand_test.mt64_seed); |
| ... | ... | @@ -179,7 +179,7 @@ fn testMT19937_64() { |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | 181 | fn testMT19937_32() { |
| 182 | @setFnTest(this, true); | |
| 182 | @setFnTest(this); | |
| 183 | 183 | |
| 184 | 184 | var rng: MT19937_32 = undefined; |
| 185 | 185 | rng.init(rand_test.mt32_seed); |
std/str.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn testStringEquality() { |
| 16 | @setFnTest(this, true); | |
| 16 | @setFnTest(this); | |
| 17 | 17 | |
| 18 | 18 | assert(eql("abcd", "abcd")); |
| 19 | 19 | assert(!eql("abcdef", "abZdef")); |
test/cases/math.zig+1-1| ... | ... | @@ -167,7 +167,7 @@ const DivResult = struct { |
| 167 | 167 | fn binaryNot() { |
| 168 | 168 | @setFnTest(this); |
| 169 | 169 | |
| 170 | assert(~u16(0b1010101010101010) == 0b0101010101010101); | |
| 170 | assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101)); | |
| 171 | 171 | testBinaryNot(0b1010101010101010); |
| 172 | 172 | } |
| 173 | 173 |