authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-31 17:10:29-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-31 17:10:29-05:00
log69132bdeda9f9ee672d883fd442b6158d8725422
tree29b1bfd8acbab82442f83bbad2d06d0eea0d7f35
parent5f89393acb0e3626d942302ca24de14349850040

IR: progress toward compiling standard library

* comptime fn call * is_comptime doesn't count as an instruction dependency * update more std code to latest zig

18 files changed, 101 insertions(+), 81 deletions(-)

doc/langref.md+1-1
...@@ -123,7 +123,7 @@ MultiplyOperator = "*" | "/" | "%" | "**" | "*%"...@@ -123,7 +123,7 @@ MultiplyOperator = "*" | "/" | "%" | "**" | "*%"
123123
124PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression124PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression
125125
126SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)126SuffixOpExpression = option("inline") PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
127127
128FieldAccessExpression = "." Symbol128FieldAccessExpression = "." Symbol
129129
src/all_types.hpp+2-1
...@@ -445,6 +445,7 @@ struct AstNodeFnCallExpr {...@@ -445,6 +445,7 @@ struct AstNodeFnCallExpr {
445 AstNode *fn_ref_expr;445 AstNode *fn_ref_expr;
446 ZigList<AstNode *> params;446 ZigList<AstNode *> params;
447 bool is_builtin;447 bool is_builtin;
448 bool is_comptime;
448};449};
449450
450struct AstNodeArrayAccessExpr {451struct AstNodeArrayAccessExpr {
...@@ -1669,7 +1670,7 @@ struct IrInstructionCall {...@@ -1669,7 +1670,7 @@ struct IrInstructionCall {
1669 FnTableEntry *fn_entry;1670 FnTableEntry *fn_entry;
1670 size_t arg_count;1671 size_t arg_count;
1671 IrInstruction **args;1672 IrInstruction **args;
1672 bool is_inline;1673 bool is_comptime;
1673 LLVMValueRef tmp_ptr;1674 LLVMValueRef tmp_ptr;
1674};1675};
16751676
src/ir.cpp+26-17
...@@ -808,13 +808,15 @@ static IrInstruction *ir_build_enum_field_ptr_from(IrBuilder *irb, IrInstruction...@@ -808,13 +808,15 @@ static IrInstruction *ir_build_enum_field_ptr_from(IrBuilder *irb, IrInstruction
808}808}
809809
810static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,810static 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 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);814 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);
814 call_instruction->fn_entry = fn_entry;815 call_instruction->fn_entry = fn_entry;
815 call_instruction->fn_ref = fn_ref;816 call_instruction->fn_ref = fn_ref;
816 call_instruction->arg_count = arg_count;817 call_instruction->is_comptime = is_comptime;
817 call_instruction->args = args;818 call_instruction->args = args;
819 call_instruction->arg_count = arg_count;
818820
819 if (fn_ref)821 if (fn_ref)
820 ir_ref_instruction(fn_ref);822 ir_ref_instruction(fn_ref);
...@@ -825,10 +827,11 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc...@@ -825,10 +827,11 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
825}827}
826828
827static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,829static 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 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope,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 ir_link_new_instruction(new_instruction, old_instruction);835 ir_link_new_instruction(new_instruction, old_instruction);
833 return new_instruction;836 return new_instruction;
834}837}
...@@ -1950,16 +1953,12 @@ static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode...@@ -1950,16 +1953,12 @@ static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode
1950}1953}
19511954
1952static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {1955static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {
1953 switch (index) {1956 return nullptr;
1954 case 0: return instruction->is_comptime;
1955 default: return nullptr;
1956 }
1957}1957}
19581958
1959static IrInstruction *ir_instruction_condbr_get_dep(IrInstructionCondBr *instruction, size_t index) {1959static IrInstruction *ir_instruction_condbr_get_dep(IrInstructionCondBr *instruction, size_t index) {
1960 switch (index) {1960 switch (index) {
1961 case 0: return instruction->condition;1961 case 0: return instruction->condition;
1962 case 1: return instruction->is_comptime;
1963 default: return nullptr;1962 default: return nullptr;
1964 }1963 }
1965}1964}
...@@ -1967,7 +1966,6 @@ static IrInstruction *ir_instruction_condbr_get_dep(IrInstructionCondBr *instruc...@@ -1967,7 +1966,6 @@ static IrInstruction *ir_instruction_condbr_get_dep(IrInstructionCondBr *instruc
1967static IrInstruction *ir_instruction_switchbr_get_dep(IrInstructionSwitchBr *instruction, size_t index) {1966static IrInstruction *ir_instruction_switchbr_get_dep(IrInstructionSwitchBr *instruction, size_t index) {
1968 switch (index) {1967 switch (index) {
1969 case 0: return instruction->target_value;1968 case 0: return instruction->target_value;
1970 case 1: return instruction->is_comptime;
1971 }1969 }
1972 size_t case_index = index - 2;1970 size_t case_index = index - 2;
1973 if (case_index < instruction->case_count) return instruction->cases[case_index].value;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,7 +3885,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
3887 args[i] = ir_gen_node(irb, arg_node, scope);3885 args[i] = ir_gen_node(irb, arg_node, scope);
3888 }3886 }
38893887
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}
38923891
3893static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) {3892static 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,6 +5600,8 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {
5601 IrInstruction *dep_instruction = ir_instruction_get_dep(instruction, dep_i);5600 IrInstruction *dep_instruction = ir_instruction_get_dep(instruction, dep_i);
5602 if (dep_instruction == nullptr)5601 if (dep_instruction == nullptr)
5603 break;5602 break;
5603 if (dep_instruction->owner_bb == old_bb)
5604 continue;
5604 ir_get_new_bb(ira, dep_instruction->owner_bb);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,6 +6538,14 @@ static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) {
6537 return true;6538 return true;
6538}6539}
65396540
6541static 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
6540static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) {6549static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) {
6541 if (value->value.type->id == TypeTableEntryIdInvalid)6550 if (value->value.type->id == TypeTableEntryIdInvalid)
6542 return false;6551 return false;
...@@ -7521,7 +7530,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -7521,7 +7530,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
75217530
7522 size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count;7531 size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count;
7523 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,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);
75257534
7526 TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type;7535 TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type;
7527 ir_add_alloca(ira, new_call_instruction, return_type);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,7 +7583,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
7574 return ira->codegen->builtin_types.entry_invalid;7583 return ira->codegen->builtin_types.entry_invalid;
75757584
7576 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,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);
75787587
7579 ir_add_alloca(ira, new_call_instruction, return_type);7588 ir_add_alloca(ira, new_call_instruction, return_type);
7580 return ir_finish_anal(ira, return_type);7589 return ir_finish_anal(ira, return_type);
...@@ -7585,7 +7594,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -7585,7 +7594,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
7585 if (fn_ref->value.type->id == TypeTableEntryIdInvalid)7594 if (fn_ref->value.type->id == TypeTableEntryIdInvalid)
7586 return ira->codegen->builtin_types.entry_invalid;7595 return ira->codegen->builtin_types.entry_invalid;
75877596
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);
75897598
7590 if (is_inline || fn_ref->value.special != ConstValSpecialRuntime) {7599 if (is_inline || fn_ref->value.special != ConstValSpecialRuntime) {
7591 if (fn_ref->value.type->id == TypeTableEntryIdMetaType) {7600 if (fn_ref->value.type->id == TypeTableEntryIdMetaType) {
...@@ -7862,7 +7871,7 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr...@@ -7862,7 +7871,7 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr
7862 IrBasicBlock *old_dest_block = br_instruction->dest_block;7871 IrBasicBlock *old_dest_block = br_instruction->dest_block;
78637872
7864 bool is_comptime;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 return ir_unreach_error(ira);7875 return ir_unreach_error(ira);
78677876
7868 if (is_comptime || old_dest_block->ref_count == 1)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,7 +7888,7 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct
7879 return ir_unreach_error(ira);7888 return ir_unreach_error(ira);
78807889
7881 bool is_comptime;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 return ir_unreach_error(ira);7892 return ir_unreach_error(ira);
78847893
7885 if (is_comptime || instr_is_comptime(condition)) {7894 if (is_comptime || instr_is_comptime(condition)) {
...@@ -9129,7 +9138,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,...@@ -9129,7 +9138,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
9129 size_t case_count = switch_br_instruction->case_count;9138 size_t case_count = switch_br_instruction->case_count;
91309139
9131 bool is_comptime;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 return ira->codegen->builtin_types.entry_invalid;9142 return ira->codegen->builtin_types.entry_invalid;
91349143
9135 if (is_comptime || instr_is_comptime(target_value)) {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,7 +837,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, size_t *token_inde
837}837}
838838
839/*839/*
840SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)840SuffixOpExpression = option("inline") PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
841FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)841FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)
842ArrayAccessExpression : token(LBracket) Expression token(RBracket)842ArrayAccessExpression : token(LBracket) Expression token(RBracket)
843SliceExpression : token(LBracket) Expression token(Ellipsis) option(Expression) token(RBracket) option(token(Const))843SliceExpression : token(LBracket) Expression token(Ellipsis) option(Expression) token(RBracket) option(token(Const))
...@@ -845,8 +845,22 @@ FieldAccessExpression : token(Dot) token(Symbol)...@@ -845,8 +845,22 @@ FieldAccessExpression : token(Dot) token(Symbol)
845StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression845StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression
846*/846*/
847static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {847static 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 AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory);859 AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory);
849 if (!primary_expr) {860 if (!primary_expr) {
861 if (is_comptime) {
862 *token_index -= 1;
863 }
850 return nullptr;864 return nullptr;
851 }865 }
852866
...@@ -857,6 +871,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,...@@ -857,6 +871,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,
857871
858 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token);872 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token);
859 node->data.fn_call_expr.fn_ref_expr = primary_expr;873 node->data.fn_call_expr.fn_ref_expr = primary_expr;
874 node->data.fn_call_expr.is_comptime = is_comptime;
860 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);875 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);
861876
862 primary_expr = node;877 primary_expr = node;
std/compiler_rt.zig+2-2
...@@ -214,7 +214,7 @@...@@ -214,7 +214,7 @@
214//}214//}
215//215//
216//fn test_umoddi3() {216//fn test_umoddi3() {
217// @setFnTest(this, true);217// @setFnTest(this);
218//218//
219// test_one_umoddi3(0, 1, 0);219// test_one_umoddi3(0, 1, 0);
220// test_one_umoddi3(2, 1, 0);220// test_one_umoddi3(2, 1, 0);
...@@ -229,7 +229,7 @@...@@ -229,7 +229,7 @@
229//}229//}
230//230//
231//fn test_udivmoddi4() {231//fn test_udivmoddi4() {
232// @setFnTest(this, true);232// @setFnTest(this);
233//233//
234// const cases = [][4]du_int {234// const cases = [][4]du_int {
235// []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000},235// []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000},
std/cstr.zig+9-9
...@@ -15,12 +15,12 @@ pub fn len(ptr: &const u8) -> usize {...@@ -15,12 +15,12 @@ pub fn len(ptr: &const u8) -> usize {
15pub fn cmp(a: &const u8, b: &const u8) -> i8 {15pub fn cmp(a: &const u8, b: &const u8) -> i8 {
16 var index: usize = 0;16 var index: usize = 0;
17 while (a[index] == b[index] && a[index] != 0; index += 1) {}17 while (a[index] == b[index] && a[index] != 0; index += 1) {}
18 return if (a[index] > b[index]) {18 if (a[index] > b[index]) {
19 119 return 1;
20 } else if (a[index] < b[index]) {20 } else if (a[index] < b[index]) {
21 -121 return -1;
22 } else {22 } else {
23 023 return 0;
24 };24 };
25}25}
2626
...@@ -127,7 +127,7 @@ pub const CBuf = struct {...@@ -127,7 +127,7 @@ pub const CBuf = struct {
127};127};
128128
129fn testSimpleCBuf() {129fn testSimpleCBuf() {
130 @setFnTest(this, true);130 @setFnTest(this);
131131
132 var buf = %%CBuf.initEmpty(&debug.global_allocator);132 var buf = %%CBuf.initEmpty(&debug.global_allocator);
133 assert(buf.len() == 0);133 assert(buf.len() == 0);
...@@ -148,13 +148,13 @@ fn testSimpleCBuf() {...@@ -148,13 +148,13 @@ fn testSimpleCBuf() {
148}148}
149149
150fn testCompileTimeStrCmp() {150fn testCompileTimeStrCmp() {
151 @setFnTest(this, true);151 @setFnTest(this);
152152
153 assert(@constEval(cmp(c"aoeu", c"aoez") == -1));153 assert(@staticEval(cmp(c"aoeu", c"aoez") == -1));
154}154}
155155
156fn testCompileTimeStrLen() {156fn testCompileTimeStrLen() {
157 @setFnTest(this, true);157 @setFnTest(this);
158158
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,7 +35,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {
35 defer st.self_exe_stream.close() %% {};35 defer st.self_exe_stream.close() %% {};
3636
37 %return st.elf.openStream(&global_allocator, &st.self_exe_stream);37 %return st.elf.openStream(&global_allocator, &st.self_exe_stream);
38 defer %return st.elf.close();38 defer st.elf.close();
3939
40 st.debug_info = (%return st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo;40 st.debug_info = (%return st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo;
41 st.debug_abbrev = (%return st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;41 st.debug_abbrev = (%return st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;
...@@ -154,7 +154,7 @@ const Die = struct {...@@ -154,7 +154,7 @@ const Die = struct {
154 fn getAttrAddr(self: &const Die, id: u64) -> %u64 {154 fn getAttrAddr(self: &const Die, id: u64) -> %u64 {
155 const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;155 const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;
156 return switch (*form_value) {156 return switch (*form_value) {
157 Address => |value| value,157 FormValue.Address => |value| value,
158 else => error.InvalidDebugInfo,158 else => error.InvalidDebugInfo,
159 };159 };
160 }160 }
...@@ -162,7 +162,7 @@ const Die = struct {...@@ -162,7 +162,7 @@ const Die = struct {
162 fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 {162 fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 {
163 const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;163 const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;
164 return switch (*form_value) {164 return switch (*form_value) {
165 Const => |value| value.asUnsignedLe(),165 FormValue.Const => |value| value.asUnsignedLe(),
166 else => error.InvalidDebugInfo,166 else => error.InvalidDebugInfo,
167 };167 };
168 }168 }
...@@ -170,8 +170,8 @@ const Die = struct {...@@ -170,8 +170,8 @@ const Die = struct {
170 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) -> %[]u8 {170 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) -> %[]u8 {
171 const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;171 const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;
172 return switch (*form_value) {172 return switch (*form_value) {
173 String => |value| value,173 FormValue.String => |value| value,
174 StrPtr => |offset| getString(st, offset),174 FormValue.StrPtr => |offset| getString(st, offset),
175 else => error.InvalidDebugInfo,175 else => error.InvalidDebugInfo,
176 }176 }
177 }177 }
...@@ -406,8 +406,8 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {...@@ -406,8 +406,8 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
406406
407 const high_pc_value = compile_unit_die.getAttr(DW.AT_high_pc) ?? return error.MissingDebugInfo;407 const high_pc_value = compile_unit_die.getAttr(DW.AT_high_pc) ?? return error.MissingDebugInfo;
408 const pc_end = switch (*high_pc_value) {408 const pc_end = switch (*high_pc_value) {
409 Address => |value| value,409 FormValue.Address => |value| value,
410 Const => |value| {410 FormValue.Const => |value| {
411 const offset = %return value.asUnsignedLe();411 const offset = %return value.asUnsignedLe();
412 low_pc + offset412 low_pc + offset
413 },413 },
std/elf.zig+8-4
...@@ -230,9 +230,11 @@ pub const Elf = struct {...@@ -230,9 +230,11 @@ pub const Elf = struct {
230 }230 }
231 }231 }
232232
233 pub fn close(elf: &Elf) -> %void {233 pub fn close(elf: &Elf) {
234 elf.allocator.free(SectionHeader, elf.section_headers);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 }
237239
238 pub fn findSection(elf: &Elf, name: []u8) -> %?&SectionHeader {240 pub fn findSection(elf: &Elf, name: []u8) -> %?&SectionHeader {
...@@ -247,8 +249,10 @@ pub const Elf = struct {...@@ -247,8 +249,10 @@ pub const Elf = struct {
247 if (target_c == 0 || expected_c != target_c) goto next_section;249 if (target_c == 0 || expected_c != target_c) goto next_section;
248 }250 }
249251
250 const null_byte = %return elf.in_stream.readByte();252 {
251 if (null_byte == 0) return (?&SectionHeader)(section);253 const null_byte = %return elf.in_stream.readByte();
254 if (null_byte == 0) return (?&SectionHeader)(section);
255 }
252256
253 next_section: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,7 +216,7 @@ pub fn HashMap(inline K: type, inline V: type, inline hash: fn(key: K)->u32,
216}216}
217217
218fn basicHashMapTest() {218fn basicHashMapTest() {
219 @setFnTest(this, true);219 @setFnTest(this);
220220
221 var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined;221 var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined;
222 map.init(&debug.global_allocator);222 map.init(&debug.global_allocator);
std/io.zig+12-19
...@@ -137,19 +137,12 @@ pub const OutStream = struct {...@@ -137,19 +137,12 @@ pub const OutStream = struct {
137 }137 }
138 }138 }
139139
140 pub fn close(self: &OutStream) -> %void {140 pub fn close(self: &OutStream) {
141 while (true) {141 while (true) {
142 const close_ret = system.close(self.fd);142 const close_ret = system.close(self.fd);
143 const close_err = system.getErrno(close_ret);143 const close_err = system.getErrno(close_ret);
144 if (close_err > 0) {144 if (close_err > 0 && close_err == errno.EINTR)
145 return switch (close_err) {145 continue;
146 errno.EINTR => continue,
147
148 errno.EIO => error.Io,
149 errno.EBADF => error.BadFd,
150 else => error.Unexpected,
151 }
152 }
153 return;146 return;
154 }147 }
155 }148 }
...@@ -163,7 +156,7 @@ pub const InStream = struct {...@@ -163,7 +156,7 @@ pub const InStream = struct {
163 /// Call close to clean up.156 /// Call close to clean up.
164 pub fn open(is: &InStream, path: []const u8) -> %void {157 pub fn open(is: &InStream, path: []const u8) -> %void {
165 switch (@compileVar("os")) {158 switch (@compileVar("os")) {
166 linux, darwin => {159 Os.linux, Os.darwin => {
167 while (true) {160 while (true) {
168 const result = system.open(path, system.O_LARGEFILE|system.O_RDONLY, 0);161 const result = system.open(path, system.O_LARGEFILE|system.O_RDONLY, 0);
169 const err = system.getErrno(result);162 const err = system.getErrno(result);
...@@ -202,7 +195,7 @@ pub const InStream = struct {...@@ -202,7 +195,7 @@ pub const InStream = struct {
202 /// you must use the open() function.195 /// you must use the open() function.
203 pub fn close(is: &InStream) -> %void {196 pub fn close(is: &InStream) -> %void {
204 switch (@compileVar("os")) {197 switch (@compileVar("os")) {
205 linux, darwin => {198 Os.linux, Os.darwin => {
206 while (true) {199 while (true) {
207 const close_ret = system.close(is.fd);200 const close_ret = system.close(is.fd);
208 const close_err = system.getErrno(close_ret);201 const close_err = system.getErrno(close_ret);
...@@ -226,7 +219,7 @@ pub const InStream = struct {...@@ -226,7 +219,7 @@ pub const InStream = struct {
226 /// the stream reached End Of File.219 /// the stream reached End Of File.
227 pub fn read(is: &InStream, buf: []u8) -> %usize {220 pub fn read(is: &InStream, buf: []u8) -> %usize {
228 switch (@compileVar("os")) {221 switch (@compileVar("os")) {
229 linux, darwin => {222 Os.linux, Os.darwin => {
230 var index: usize = 0;223 var index: usize = 0;
231 while (index < buf.len) {224 while (index < buf.len) {
232 const amt_read = system.read(is.fd, &buf[index], buf.len - index);225 const amt_read = system.read(is.fd, &buf[index], buf.len - index);
...@@ -288,7 +281,7 @@ pub const InStream = struct {...@@ -288,7 +281,7 @@ pub const InStream = struct {
288281
289 pub fn seekForward(is: &InStream, amount: usize) -> %void {282 pub fn seekForward(is: &InStream, amount: usize) -> %void {
290 switch (@compileVar("os")) {283 switch (@compileVar("os")) {
291 linux, darwin => {284 Os.linux, Os.darwin => {
292 const result = system.lseek(is.fd, amount, system.SEEK_CUR);285 const result = system.lseek(is.fd, amount, system.SEEK_CUR);
293 const err = system.getErrno(result);286 const err = system.getErrno(result);
294 if (err > 0) {287 if (err > 0) {
...@@ -308,7 +301,7 @@ pub const InStream = struct {...@@ -308,7 +301,7 @@ pub const InStream = struct {
308301
309 pub fn seekTo(is: &InStream, pos: usize) -> %void {302 pub fn seekTo(is: &InStream, pos: usize) -> %void {
310 switch (@compileVar("os")) {303 switch (@compileVar("os")) {
311 linux, darwin => {304 Os.linux, Os.darwin => {
312 const result = system.lseek(is.fd, pos, system.SEEK_SET);305 const result = system.lseek(is.fd, pos, system.SEEK_SET);
313 const err = system.getErrno(result);306 const err = system.getErrno(result);
314 if (err > 0) {307 if (err > 0) {
...@@ -328,7 +321,7 @@ pub const InStream = struct {...@@ -328,7 +321,7 @@ pub const InStream = struct {
328321
329 pub fn getPos(is: &InStream) -> %usize {322 pub fn getPos(is: &InStream) -> %usize {
330 switch (@compileVar("os")) {323 switch (@compileVar("os")) {
331 linux, darwin => {324 Os.linux, Os.darwin => {
332 const result = system.lseek(is.fd, 0, system.SEEK_CUR);325 const result = system.lseek(is.fd, 0, system.SEEK_CUR);
333 const err = system.getErrno(result);326 const err = system.getErrno(result);
334 if (err > 0) {327 if (err > 0) {
...@@ -424,7 +417,7 @@ fn bufPrintUnsigned(inline T: type, out_buf: []u8, x: T) -> usize {...@@ -424,7 +417,7 @@ fn bufPrintUnsigned(inline T: type, out_buf: []u8, x: T) -> usize {
424}417}
425418
426fn parseU64DigitTooBig() {419fn parseU64DigitTooBig() {
427 @setFnTest(this, true);420 @setFnTest(this);
428421
429 parseUnsigned(u64, "123a", 10) %% |err| {422 parseUnsigned(u64, "123a", 10) %% |err| {
430 if (err == error.InvalidChar) return;423 if (err == error.InvalidChar) return;
...@@ -435,10 +428,10 @@ fn parseU64DigitTooBig() {...@@ -435,10 +428,10 @@ fn parseU64DigitTooBig() {
435428
436pub fn openSelfExe(stream: &InStream) -> %void {429pub fn openSelfExe(stream: &InStream) -> %void {
437 switch (@compileVar("os")) {430 switch (@compileVar("os")) {
438 linux => {431 Os.linux => {
439 %return stream.open("/proc/self/exe");432 %return stream.open("/proc/self/exe");
440 },433 },
441 darwin => {434 Os.darwin => {
442 %%stderr.printf("TODO: openSelfExe on Darwin\n");435 %%stderr.printf("TODO: openSelfExe on Darwin\n");
443 os.abort();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,7 +261,7 @@ pub fn open_c(path: &const u8, flags: usize, perm: usize) -> usize {
261}261}
262262
263pub fn open(path: []const u8, flags: usize, perm: usize) -> usize {263pub 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 @memcpy(&buf[0], &path[0], path.len);265 @memcpy(&buf[0], &path[0], path.len);
266 buf[path.len] = 0;266 buf[path.len] = 0;
267 return open_c(buf.ptr, flags, perm);267 return open_c(buf.ptr, flags, perm);
...@@ -272,7 +272,7 @@ pub fn create_c(path: &const u8, perm: usize) -> usize {...@@ -272,7 +272,7 @@ pub fn create_c(path: &const u8, perm: usize) -> usize {
272}272}
273273
274pub fn create(path: []const u8, perm: usize) -> usize {274pub 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 @memcpy(&buf[0], &path[0], path.len);276 @memcpy(&buf[0], &path[0], path.len);
277 buf[path.len] = 0;277 buf[path.len] = 0;
278 return create_c(buf.ptr, perm);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,7 +283,7 @@ pub fn openat_c(dirfd: i32, path: &const u8, flags: usize, mode: usize) -> usize
283}283}
284284
285pub fn openat(dirfd: i32, path: []const u8, flags: usize, mode: usize) -> usize {285pub 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 @memcpy(&buf[0], &path[0], path.len);287 @memcpy(&buf[0], &path[0], path.len);
288 buf[path.len] = 0;288 buf[path.len] = 0;
289 return openat_c(dirfd, buf.ptr, flags, mode);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,7 +52,7 @@ pub fn List(inline T: type) -> type{
52}52}
5353
54fn basicListTest() {54fn basicListTest() {
55 @setFnTest(this, true);55 @setFnTest(this);
5656
57 var list = List(i32).init(&debug.global_allocator);57 var list = List(i32).init(&debug.global_allocator);
58 defer list.deinit();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,7 +83,7 @@ pub fn sliceAsInt(buf: []u8, is_be: bool, inline T: type) -> T {
83}83}
8484
85fn testSliceAsInt() {85fn testSliceAsInt() {
86 @setFnTest(this, true);86 @setFnTest(this);
87 {87 {
88 const buf = []u8{0x00, 0x00, 0x12, 0x34};88 const buf = []u8{0x00, 0x00, 0x12, 0x34};
89 const answer = sliceAsInt(buf[0...], true, u64);89 const answer = sliceAsInt(buf[0...], true, u64);
std/net.zig+3-5
...@@ -181,8 +181,6 @@ error JunkAtEnd;...@@ -181,8 +181,6 @@ error JunkAtEnd;
181error Incomplete;181error Incomplete;
182182
183fn parseIp6(buf: []const u8) -> %Address {183fn parseIp6(buf: []const u8) -> %Address {
184 @setFnStaticEval(this, false);
185
186 var result: Address = undefined;184 var result: Address = undefined;
187 result.family = linux.AF_INET6;185 result.family = linux.AF_INET6;
188 result.scope_id = 0;186 result.scope_id = 0;
...@@ -320,7 +318,7 @@ fn parseIp4(buf: []const u8) -> %u32 {...@@ -320,7 +318,7 @@ fn parseIp4(buf: []const u8) -> %u32 {
320318
321319
322fn testParseIp4() {320fn testParseIp4() {
323 @setFnTest(this, true);321 @setFnTest(this);
324322
325 assert(%%parseIp4("127.0.0.1") == endian.swapIfLe(u32, 0x7f000001));323 assert(%%parseIp4("127.0.0.1") == endian.swapIfLe(u32, 0x7f000001));
326 switch (parseIp4("256.0.0.1")) { Overflow => {}, else => @unreachable(), }324 switch (parseIp4("256.0.0.1")) { Overflow => {}, else => @unreachable(), }
...@@ -331,7 +329,7 @@ fn testParseIp4() {...@@ -331,7 +329,7 @@ fn testParseIp4() {
331}329}
332330
333fn testParseIp6() {331fn testParseIp6() {
334 @setFnTest(this, true);332 @setFnTest(this);
335333
336 {334 {
337 const addr = %%parseIp6("FF01:0:0:0:0:0:0:FB");335 const addr = %%parseIp6("FF01:0:0:0:0:0:0:FB");
...@@ -342,7 +340,7 @@ fn testParseIp6() {...@@ -342,7 +340,7 @@ fn testParseIp6() {
342}340}
343341
344fn testLookupSimpleIp() {342fn testLookupSimpleIp() {
345 @setFnTest(this, true);343 @setFnTest(this);
346344
347 {345 {
348 var addrs_buf: [5]Address = undefined;346 var addrs_buf: [5]Address = undefined;
std/os.zig+3-3
...@@ -10,8 +10,8 @@ error Unexpected;...@@ -10,8 +10,8 @@ error Unexpected;
10pub fn getRandomBytes(buf: []u8) -> %void {10pub fn getRandomBytes(buf: []u8) -> %void {
11 while (true) {11 while (true) {
12 const ret = switch (@compileVar("os")) {12 const ret = switch (@compileVar("os")) {
13 linux => system.getrandom(buf.ptr, buf.len, 0),13 Os.linux => system.getrandom(buf.ptr, buf.len, 0),
14 darwin => system.getrandom(buf.ptr, buf.len),14 Os.darwin => system.getrandom(buf.ptr, buf.len),
15 else => @compileError("unsupported os"),15 else => @compileError("unsupported os"),
16 };16 };
17 const err = system.getErrno(ret);17 const err = system.getErrno(ret);
...@@ -29,7 +29,7 @@ pub fn getRandomBytes(buf: []u8) -> %void {...@@ -29,7 +29,7 @@ pub fn getRandomBytes(buf: []u8) -> %void {
2929
30pub coldcc fn abort() -> unreachable {30pub coldcc fn abort() -> unreachable {
31 switch (@compileVar("os")) {31 switch (@compileVar("os")) {
32 linux, darwin => {32 Os.linux, Os.darwin => {
33 system.raise(system.SIGABRT);33 system.raise(system.SIGABRT);
34 system.raise(system.SIGKILL);34 system.raise(system.SIGKILL);
35 while (true) {}35 while (true) {}
std/rand.zig+4-4
...@@ -87,7 +87,7 @@ pub const Rand = struct {...@@ -87,7 +87,7 @@ pub const Rand = struct {
87 } else if (T == f64) {87 } else if (T == f64) {
88 900719925474099288 9007199254740992
89 } else {89 } else {
90 @compileError("unknown floating point type" ++ @typeName(T))90 @compileError("unknown floating point type")
91 };91 };
92 return T(r.rangeUnsigned(int_type, 0, precision)) / T(precision);92 return T(r.rangeUnsigned(int_type, 0, precision)) / T(precision);
93 }93 }
...@@ -156,7 +156,7 @@ fn MersenneTwister(...@@ -156,7 +156,7 @@ fn MersenneTwister(
156}156}
157157
158fn testFloat32() {158fn testFloat32() {
159 @setFnTest(this, true);159 @setFnTest(this);
160160
161 var r: Rand = undefined;161 var r: Rand = undefined;
162 r.init(42);162 r.init(42);
...@@ -169,7 +169,7 @@ fn testFloat32() {...@@ -169,7 +169,7 @@ fn testFloat32() {
169}169}
170170
171fn testMT19937_64() {171fn testMT19937_64() {
172 @setFnTest(this, true);172 @setFnTest(this);
173173
174 var rng: MT19937_64 = undefined;174 var rng: MT19937_64 = undefined;
175 rng.init(rand_test.mt64_seed);175 rng.init(rand_test.mt64_seed);
...@@ -179,7 +179,7 @@ fn testMT19937_64() {...@@ -179,7 +179,7 @@ fn testMT19937_64() {
179}179}
180180
181fn testMT19937_32() {181fn testMT19937_32() {
182 @setFnTest(this, true);182 @setFnTest(this);
183183
184 var rng: MT19937_32 = undefined;184 var rng: MT19937_32 = undefined;
185 rng.init(rand_test.mt32_seed);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,7 +13,7 @@ pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool {
13}13}
1414
15fn testStringEquality() {15fn testStringEquality() {
16 @setFnTest(this, true);16 @setFnTest(this);
1717
18 assert(eql("abcd", "abcd"));18 assert(eql("abcd", "abcd"));
19 assert(!eql("abcdef", "abZdef"));19 assert(!eql("abcdef", "abZdef"));
test/cases/math.zig+1-1
...@@ -167,7 +167,7 @@ const DivResult = struct {...@@ -167,7 +167,7 @@ const DivResult = struct {
167fn binaryNot() {167fn binaryNot() {
168 @setFnTest(this);168 @setFnTest(this);
169169
170 assert(~u16(0b1010101010101010) == 0b0101010101010101);170 assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101));
171 testBinaryNot(0b1010101010101010);171 testBinaryNot(0b1010101010101010);
172}172}
173173