authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-23 18:28:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-23 18:35:21-07:00
logb40a8efb9a72e69cd7e9061fc4c08d5e705b0fbd
treeb62377262318b6f6d76a0b75d43dff106e553a2f
parent183ee0965fac6322651666834776d9832cc95ddd

stage2: implement `anyframe`, `anyframe->T` and fix assembly

* AstGen: implement `anyframe_literal` and `anyframe_type`. * Introduce `makeSubBlock` to avoid redundant AstGen code for GenZir scopes. Allows adding/removing a field without possibility of accidentally introducing a bug of forgetting to set the new field. * Add to GenZir `nosuspend_node` and `suspend_node` in preparation for implementing `suspend` blocks and `nosuspend` blocks. * AstGen: fix assembly to support clobbers, multiple outputs, and outputs without `->` syntax. - `asm` and `asm_volatile` move to `Extended` enum with `small` being repurposed for a few things. This frees up 2 ZIR tags, 1 of which is used in this commit and 1 is leftover. * AstGen: fix `simple_types` incorrectly having multiple conflicting values for "undefined" and "null". - Also add "anyframe" to `simple_types`. * Add `anyframe_type` to type.zig, value.zig and `Zir.Inst.Ref`. - Also add i128 and u128 types to `Zir.Inst.Ref` and `simple_types`. * Sema/Zir: Fix incorrect math causing the function body to be messed up for Extended-encoded functions. * Zir: support `i32` fields for "extra" payloads.

6 files changed, 513 insertions(+), 364 deletions(-)

src/AstGen.zig+154-264
...@@ -723,8 +723,12 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn...@@ -723,8 +723,12 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
723 },723 },
724 .enum_literal => return simpleStrTok(gz, scope, rl, main_tokens[node], node, .enum_literal),724 .enum_literal => return simpleStrTok(gz, scope, rl, main_tokens[node], node, .enum_literal),
725 .error_value => return simpleStrTok(gz, scope, rl, node_datas[node].rhs, node, .error_value),725 .error_value => return simpleStrTok(gz, scope, rl, node_datas[node].rhs, node, .error_value),
726 .anyframe_literal => return astgen.failNode(node, "async and related features are not yet supported", .{}),726 .anyframe_literal => return rvalue(gz, scope, rl, .anyframe_type, node),
727 .anyframe_type => return astgen.failNode(node, "async and related features are not yet supported", .{}),727 .anyframe_type => {
728 const return_type = try typeExpr(gz, scope, node_datas[node].rhs);
729 const result = try gz.addUnNode(.anyframe_type, return_type, node);
730 return rvalue(gz, scope, rl, result, node);
731 },
728 .@"catch" => {732 .@"catch" => {
729 const catch_token = main_tokens[node];733 const catch_token = main_tokens[node];
730 const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)734 const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
...@@ -1546,18 +1550,10 @@ fn labeledBlockExpr(...@@ -1546,18 +1550,10 @@ fn labeledBlockExpr(
1546 const block_inst = try gz.addBlock(zir_tag, block_node);1550 const block_inst = try gz.addBlock(zir_tag, block_node);
1547 try gz.instructions.append(astgen.gpa, block_inst);1551 try gz.instructions.append(astgen.gpa, block_inst);
15481552
1549 var block_scope: GenZir = .{1553 var block_scope = gz.makeSubBlock(parent_scope);
1550 .parent = parent_scope,1554 block_scope.label = GenZir.Label{
1551 .decl_node_index = gz.decl_node_index,1555 .token = label_token,
1552 .astgen = gz.astgen,1556 .block_inst = block_inst,
1553 .force_comptime = gz.force_comptime,
1554 .ref_start_index = gz.ref_start_index,
1555 .instructions = .{},
1556 // TODO @as here is working around a stage1 miscompilation bug :(
1557 .label = @as(?GenZir.Label, GenZir.Label{
1558 .token = label_token,
1559 .block_inst = block_inst,
1560 }),
1561 };1557 };
1562 block_scope.setBreakResultLoc(rl);1558 block_scope.setBreakResultLoc(rl);
1563 defer block_scope.instructions.deinit(astgen.gpa);1559 defer block_scope.instructions.deinit(astgen.gpa);
...@@ -1695,10 +1691,9 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner...@@ -1695,10 +1691,9 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
1695 .array_type_sentinel,1691 .array_type_sentinel,
1696 .elem_type,1692 .elem_type,
1697 .indexable_ptr_len,1693 .indexable_ptr_len,
1694 .anyframe_type,
1698 .as,1695 .as,
1699 .as_node,1696 .as_node,
1700 .@"asm",
1701 .asm_volatile,
1702 .bit_and,1697 .bit_and,
1703 .bitcast,1698 .bitcast,
1704 .bitcast_result_ptr,1699 .bitcast_result_ptr,
...@@ -2095,13 +2090,7 @@ fn varDecl(...@@ -2095,13 +2090,7 @@ fn varDecl(
20952090
2096 // Detect whether the initialization expression actually uses the2091 // Detect whether the initialization expression actually uses the
2097 // result location pointer.2092 // result location pointer.
2098 var init_scope: GenZir = .{2093 var init_scope = gz.makeSubBlock(scope);
2099 .parent = scope,
2100 .decl_node_index = gz.decl_node_index,
2101 .force_comptime = gz.force_comptime,
2102 .ref_start_index = gz.ref_start_index,
2103 .astgen = astgen,
2104 };
2105 defer init_scope.instructions.deinit(gpa);2094 defer init_scope.instructions.deinit(gpa);
21062095
2107 var resolve_inferred_alloc: Zir.Inst.Ref = .none;2096 var resolve_inferred_alloc: Zir.Inst.Ref = .none;
...@@ -3778,14 +3767,7 @@ fn tryExpr(...@@ -3778,14 +3767,7 @@ fn tryExpr(
3778 return astgen.failNode(node, "invalid 'try' outside function scope", .{});3767 return astgen.failNode(node, "invalid 'try' outside function scope", .{});
3779 };3768 };
37803769
3781 var block_scope: GenZir = .{3770 var block_scope = parent_gz.makeSubBlock(scope);
3782 .parent = scope,
3783 .decl_node_index = parent_gz.decl_node_index,
3784 .astgen = astgen,
3785 .force_comptime = parent_gz.force_comptime,
3786 .ref_start_index = parent_gz.ref_start_index,
3787 .instructions = .{},
3788 };
3789 block_scope.setBreakResultLoc(rl);3771 block_scope.setBreakResultLoc(rl);
3790 defer block_scope.instructions.deinit(astgen.gpa);3772 defer block_scope.instructions.deinit(astgen.gpa);
37913773
...@@ -3811,28 +3793,14 @@ fn tryExpr(...@@ -3811,28 +3793,14 @@ fn tryExpr(
3811 try parent_gz.instructions.append(astgen.gpa, block);3793 try parent_gz.instructions.append(astgen.gpa, block);
3812 try block_scope.setBlockBody(block);3794 try block_scope.setBlockBody(block);
38133795
3814 var then_scope: GenZir = .{3796 var then_scope = parent_gz.makeSubBlock(scope);
3815 .parent = scope,
3816 .decl_node_index = parent_gz.decl_node_index,
3817 .astgen = astgen,
3818 .force_comptime = block_scope.force_comptime,
3819 .ref_start_index = parent_gz.ref_start_index,
3820 .instructions = .{},
3821 };
3822 defer then_scope.instructions.deinit(astgen.gpa);3797 defer then_scope.instructions.deinit(astgen.gpa);
38233798
3824 const err_code = try then_scope.addUnNode(err_ops[1], operand, node);3799 const err_code = try then_scope.addUnNode(err_ops[1], operand, node);
3825 try genDefers(&then_scope, &fn_block.base, scope, err_code);3800 try genDefers(&then_scope, &fn_block.base, scope, err_code);
3826 const then_result = try then_scope.addUnNode(.ret_node, err_code, node);3801 const then_result = try then_scope.addUnNode(.ret_node, err_code, node);
38273802
3828 var else_scope: GenZir = .{3803 var else_scope = parent_gz.makeSubBlock(scope);
3829 .parent = scope,
3830 .decl_node_index = parent_gz.decl_node_index,
3831 .astgen = astgen,
3832 .force_comptime = block_scope.force_comptime,
3833 .ref_start_index = parent_gz.ref_start_index,
3834 .instructions = .{},
3835 };
3836 defer else_scope.instructions.deinit(astgen.gpa);3804 defer else_scope.instructions.deinit(astgen.gpa);
38373805
3838 block_scope.break_count += 1;3806 block_scope.break_count += 1;
...@@ -3878,14 +3846,7 @@ fn orelseCatchExpr(...@@ -3878,14 +3846,7 @@ fn orelseCatchExpr(
3878 const astgen = parent_gz.astgen;3846 const astgen = parent_gz.astgen;
3879 const tree = &astgen.file.tree;3847 const tree = &astgen.file.tree;
38803848
3881 var block_scope: GenZir = .{3849 var block_scope = parent_gz.makeSubBlock(scope);
3882 .parent = scope,
3883 .decl_node_index = parent_gz.decl_node_index,
3884 .astgen = astgen,
3885 .force_comptime = parent_gz.force_comptime,
3886 .ref_start_index = parent_gz.ref_start_index,
3887 .instructions = .{},
3888 };
3889 block_scope.setBreakResultLoc(rl);3850 block_scope.setBreakResultLoc(rl);
3890 defer block_scope.instructions.deinit(astgen.gpa);3851 defer block_scope.instructions.deinit(astgen.gpa);
38913852
...@@ -3906,14 +3867,7 @@ fn orelseCatchExpr(...@@ -3906,14 +3867,7 @@ fn orelseCatchExpr(
3906 try parent_gz.instructions.append(astgen.gpa, block);3867 try parent_gz.instructions.append(astgen.gpa, block);
3907 try block_scope.setBlockBody(block);3868 try block_scope.setBlockBody(block);
39083869
3909 var then_scope: GenZir = .{3870 var then_scope = parent_gz.makeSubBlock(scope);
3910 .parent = scope,
3911 .decl_node_index = parent_gz.decl_node_index,
3912 .astgen = astgen,
3913 .force_comptime = block_scope.force_comptime,
3914 .ref_start_index = parent_gz.ref_start_index,
3915 .instructions = .{},
3916 };
3917 defer then_scope.instructions.deinit(astgen.gpa);3871 defer then_scope.instructions.deinit(astgen.gpa);
39183872
3919 var err_val_scope: Scope.LocalVal = undefined;3873 var err_val_scope: Scope.LocalVal = undefined;
...@@ -3939,14 +3893,7 @@ fn orelseCatchExpr(...@@ -3939,14 +3893,7 @@ fn orelseCatchExpr(
3939 // instructions into place until we know whether to keep store_to_block_ptr3893 // instructions into place until we know whether to keep store_to_block_ptr
3940 // instructions or not.3894 // instructions or not.
39413895
3942 var else_scope: GenZir = .{3896 var else_scope = parent_gz.makeSubBlock(scope);
3943 .parent = scope,
3944 .decl_node_index = parent_gz.decl_node_index,
3945 .astgen = astgen,
3946 .force_comptime = block_scope.force_comptime,
3947 .ref_start_index = parent_gz.ref_start_index,
3948 .instructions = .{},
3949 };
3950 defer else_scope.instructions.deinit(astgen.gpa);3897 defer else_scope.instructions.deinit(astgen.gpa);
39513898
3952 // This could be a pointer or value depending on `unwrap_op`.3899 // This could be a pointer or value depending on `unwrap_op`.
...@@ -4140,13 +4087,7 @@ fn boolBinOp(...@@ -4140,13 +4087,7 @@ fn boolBinOp(
4140 const lhs = try expr(gz, scope, bool_rl, node_datas[node].lhs);4087 const lhs = try expr(gz, scope, bool_rl, node_datas[node].lhs);
4141 const bool_br = try gz.addBoolBr(zir_tag, lhs);4088 const bool_br = try gz.addBoolBr(zir_tag, lhs);
41424089
4143 var rhs_scope: GenZir = .{4090 var rhs_scope = gz.makeSubBlock(scope);
4144 .parent = scope,
4145 .decl_node_index = gz.decl_node_index,
4146 .astgen = gz.astgen,
4147 .force_comptime = gz.force_comptime,
4148 .ref_start_index = gz.ref_start_index,
4149 };
4150 defer rhs_scope.instructions.deinit(gz.astgen.gpa);4091 defer rhs_scope.instructions.deinit(gz.astgen.gpa);
4151 const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_rl, node_datas[node].rhs);4092 const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_rl, node_datas[node].rhs);
4152 _ = try rhs_scope.addBreak(.break_inline, bool_br, rhs);4093 _ = try rhs_scope.addBreak(.break_inline, bool_br, rhs);
...@@ -4167,14 +4108,7 @@ fn ifExpr(...@@ -4167,14 +4108,7 @@ fn ifExpr(
4167 const tree = &astgen.file.tree;4108 const tree = &astgen.file.tree;
4168 const token_tags = tree.tokens.items(.tag);4109 const token_tags = tree.tokens.items(.tag);
41694110
4170 var block_scope: GenZir = .{4111 var block_scope = parent_gz.makeSubBlock(scope);
4171 .parent = scope,
4172 .decl_node_index = parent_gz.decl_node_index,
4173 .astgen = astgen,
4174 .force_comptime = parent_gz.force_comptime,
4175 .ref_start_index = parent_gz.ref_start_index,
4176 .instructions = .{},
4177 };
4178 block_scope.setBreakResultLoc(rl);4112 block_scope.setBreakResultLoc(rl);
4179 defer block_scope.instructions.deinit(astgen.gpa);4113 defer block_scope.instructions.deinit(astgen.gpa);
41804114
...@@ -4218,14 +4152,7 @@ fn ifExpr(...@@ -4218,14 +4152,7 @@ fn ifExpr(
4218 try parent_gz.instructions.append(astgen.gpa, block);4152 try parent_gz.instructions.append(astgen.gpa, block);
4219 try block_scope.setBlockBody(block);4153 try block_scope.setBlockBody(block);
42204154
4221 var then_scope: GenZir = .{4155 var then_scope = parent_gz.makeSubBlock(scope);
4222 .parent = scope,
4223 .decl_node_index = parent_gz.decl_node_index,
4224 .astgen = astgen,
4225 .force_comptime = block_scope.force_comptime,
4226 .ref_start_index = parent_gz.ref_start_index,
4227 .instructions = .{},
4228 };
4229 defer then_scope.instructions.deinit(astgen.gpa);4156 defer then_scope.instructions.deinit(astgen.gpa);
42304157
4231 var payload_val_scope: Scope.LocalVal = undefined;4158 var payload_val_scope: Scope.LocalVal = undefined;
...@@ -4273,14 +4200,7 @@ fn ifExpr(...@@ -4273,14 +4200,7 @@ fn ifExpr(
4273 // instructions into place until we know whether to keep store_to_block_ptr4200 // instructions into place until we know whether to keep store_to_block_ptr
4274 // instructions or not.4201 // instructions or not.
42754202
4276 var else_scope: GenZir = .{4203 var else_scope = parent_gz.makeSubBlock(scope);
4277 .parent = scope,
4278 .decl_node_index = parent_gz.decl_node_index,
4279 .astgen = astgen,
4280 .force_comptime = block_scope.force_comptime,
4281 .ref_start_index = parent_gz.ref_start_index,
4282 .instructions = .{},
4283 };
4284 defer else_scope.instructions.deinit(astgen.gpa);4204 defer else_scope.instructions.deinit(astgen.gpa);
42854205
4286 const else_node = if_full.ast.else_expr;4206 const else_node = if_full.ast.else_expr;
...@@ -4424,25 +4344,11 @@ fn whileExpr(...@@ -4424,25 +4344,11 @@ fn whileExpr(
4424 const loop_block = try parent_gz.addBlock(loop_tag, node);4344 const loop_block = try parent_gz.addBlock(loop_tag, node);
4425 try parent_gz.instructions.append(astgen.gpa, loop_block);4345 try parent_gz.instructions.append(astgen.gpa, loop_block);
44264346
4427 var loop_scope: GenZir = .{4347 var loop_scope = parent_gz.makeSubBlock(scope);
4428 .parent = scope,
4429 .decl_node_index = parent_gz.decl_node_index,
4430 .astgen = astgen,
4431 .force_comptime = parent_gz.force_comptime,
4432 .ref_start_index = parent_gz.ref_start_index,
4433 .instructions = .{},
4434 };
4435 loop_scope.setBreakResultLoc(rl);4348 loop_scope.setBreakResultLoc(rl);
4436 defer loop_scope.instructions.deinit(astgen.gpa);4349 defer loop_scope.instructions.deinit(astgen.gpa);
44374350
4438 var continue_scope: GenZir = .{4351 var continue_scope = parent_gz.makeSubBlock(&loop_scope.base);
4439 .parent = &loop_scope.base,
4440 .decl_node_index = parent_gz.decl_node_index,
4441 .astgen = astgen,
4442 .force_comptime = loop_scope.force_comptime,
4443 .ref_start_index = parent_gz.ref_start_index,
4444 .instructions = .{},
4445 };
4446 defer continue_scope.instructions.deinit(astgen.gpa);4352 defer continue_scope.instructions.deinit(astgen.gpa);
44474353
4448 const payload_is_ref = if (while_full.payload_token) |payload_token|4354 const payload_is_ref = if (while_full.payload_token) |payload_token|
...@@ -4505,14 +4411,7 @@ fn whileExpr(...@@ -4505,14 +4411,7 @@ fn whileExpr(
4505 });4411 });
4506 }4412 }
45074413
4508 var then_scope: GenZir = .{4414 var then_scope = parent_gz.makeSubBlock(&continue_scope.base);
4509 .parent = &continue_scope.base,
4510 .decl_node_index = parent_gz.decl_node_index,
4511 .astgen = astgen,
4512 .force_comptime = continue_scope.force_comptime,
4513 .ref_start_index = parent_gz.ref_start_index,
4514 .instructions = .{},
4515 };
4516 defer then_scope.instructions.deinit(astgen.gpa);4415 defer then_scope.instructions.deinit(astgen.gpa);
45174416
4518 var payload_val_scope: Scope.LocalVal = undefined;4417 var payload_val_scope: Scope.LocalVal = undefined;
...@@ -4557,14 +4456,7 @@ fn whileExpr(...@@ -4557,14 +4456,7 @@ fn whileExpr(
4557 loop_scope.break_count += 1;4456 loop_scope.break_count += 1;
4558 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr);4457 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr);
45594458
4560 var else_scope: GenZir = .{4459 var else_scope = parent_gz.makeSubBlock(&continue_scope.base);
4561 .parent = &continue_scope.base,
4562 .decl_node_index = parent_gz.decl_node_index,
4563 .astgen = astgen,
4564 .force_comptime = continue_scope.force_comptime,
4565 .ref_start_index = parent_gz.ref_start_index,
4566 .instructions = .{},
4567 };
4568 defer else_scope.instructions.deinit(astgen.gpa);4460 defer else_scope.instructions.deinit(astgen.gpa);
45694461
4570 const else_node = while_full.ast.else_expr;4462 const else_node = while_full.ast.else_expr;
...@@ -4659,25 +4551,11 @@ fn forExpr(...@@ -4659,25 +4551,11 @@ fn forExpr(
4659 const loop_block = try parent_gz.addBlock(loop_tag, node);4551 const loop_block = try parent_gz.addBlock(loop_tag, node);
4660 try parent_gz.instructions.append(astgen.gpa, loop_block);4552 try parent_gz.instructions.append(astgen.gpa, loop_block);
46614553
4662 var loop_scope: GenZir = .{4554 var loop_scope = parent_gz.makeSubBlock(scope);
4663 .parent = scope,
4664 .decl_node_index = parent_gz.decl_node_index,
4665 .astgen = astgen,
4666 .force_comptime = parent_gz.force_comptime,
4667 .ref_start_index = parent_gz.ref_start_index,
4668 .instructions = .{},
4669 };
4670 loop_scope.setBreakResultLoc(rl);4555 loop_scope.setBreakResultLoc(rl);
4671 defer loop_scope.instructions.deinit(astgen.gpa);4556 defer loop_scope.instructions.deinit(astgen.gpa);
46724557
4673 var cond_scope: GenZir = .{4558 var cond_scope = parent_gz.makeSubBlock(&loop_scope.base);
4674 .parent = &loop_scope.base,
4675 .decl_node_index = parent_gz.decl_node_index,
4676 .astgen = astgen,
4677 .force_comptime = loop_scope.force_comptime,
4678 .ref_start_index = parent_gz.ref_start_index,
4679 .instructions = .{},
4680 };
4681 defer cond_scope.instructions.deinit(astgen.gpa);4559 defer cond_scope.instructions.deinit(astgen.gpa);
46824560
4683 // check condition i < array_expr.len4561 // check condition i < array_expr.len
...@@ -4714,14 +4592,7 @@ fn forExpr(...@@ -4714,14 +4592,7 @@ fn forExpr(
4714 });4592 });
4715 }4593 }
47164594
4717 var then_scope: GenZir = .{4595 var then_scope = parent_gz.makeSubBlock(&cond_scope.base);
4718 .parent = &cond_scope.base,
4719 .decl_node_index = parent_gz.decl_node_index,
4720 .astgen = astgen,
4721 .force_comptime = cond_scope.force_comptime,
4722 .ref_start_index = parent_gz.ref_start_index,
4723 .instructions = .{},
4724 };
4725 defer then_scope.instructions.deinit(astgen.gpa);4596 defer then_scope.instructions.deinit(astgen.gpa);
47264597
4727 var payload_val_scope: Scope.LocalVal = undefined;4598 var payload_val_scope: Scope.LocalVal = undefined;
...@@ -4773,14 +4644,7 @@ fn forExpr(...@@ -4773,14 +4644,7 @@ fn forExpr(
4773 loop_scope.break_count += 1;4644 loop_scope.break_count += 1;
4774 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, for_full.ast.then_expr);4645 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, for_full.ast.then_expr);
47754646
4776 var else_scope: GenZir = .{4647 var else_scope = parent_gz.makeSubBlock(&cond_scope.base);
4777 .parent = &cond_scope.base,
4778 .decl_node_index = parent_gz.decl_node_index,
4779 .astgen = astgen,
4780 .force_comptime = cond_scope.force_comptime,
4781 .ref_start_index = parent_gz.ref_start_index,
4782 .instructions = .{},
4783 };
4784 defer else_scope.instructions.deinit(astgen.gpa);4648 defer else_scope.instructions.deinit(astgen.gpa);
47854649
4786 const else_node = for_full.ast.else_expr;4650 const else_node = for_full.ast.else_expr;
...@@ -5076,14 +4940,7 @@ fn switchExpr(...@@ -5076,14 +4940,7 @@ fn switchExpr(
5076 var multi_cases_payload = ArrayListUnmanaged(u32){};4940 var multi_cases_payload = ArrayListUnmanaged(u32){};
5077 defer multi_cases_payload.deinit(gpa);4941 defer multi_cases_payload.deinit(gpa);
50784942
5079 var block_scope: GenZir = .{4943 var block_scope = parent_gz.makeSubBlock(scope);
5080 .parent = scope,
5081 .decl_node_index = parent_gz.decl_node_index,
5082 .astgen = astgen,
5083 .force_comptime = parent_gz.force_comptime,
5084 .ref_start_index = parent_gz.ref_start_index,
5085 .instructions = .{},
5086 };
5087 block_scope.setBreakResultLoc(rl);4944 block_scope.setBreakResultLoc(rl);
5088 defer block_scope.instructions.deinit(gpa);4945 defer block_scope.instructions.deinit(gpa);
50894946
...@@ -5091,14 +4948,7 @@ fn switchExpr(...@@ -5091,14 +4948,7 @@ fn switchExpr(
5091 const switch_block = try parent_gz.addBlock(undefined, switch_node);4948 const switch_block = try parent_gz.addBlock(undefined, switch_node);
50924949
5093 // We re-use this same scope for all cases, including the special prong, if any.4950 // We re-use this same scope for all cases, including the special prong, if any.
5094 var case_scope: GenZir = .{4951 var case_scope = parent_gz.makeSubBlock(&block_scope.base);
5095 .parent = &block_scope.base,
5096 .decl_node_index = parent_gz.decl_node_index,
5097 .astgen = astgen,
5098 .force_comptime = parent_gz.force_comptime,
5099 .ref_start_index = parent_gz.ref_start_index,
5100 .instructions = .{},
5101 };
5102 defer case_scope.instructions.deinit(gpa);4952 defer case_scope.instructions.deinit(gpa);
51034953
5104 // Do the else/`_` first because it goes first in the payload.4954 // Do the else/`_` first because it goes first in the payload.
...@@ -5846,57 +5696,109 @@ fn asmExpr(...@@ -5846,57 +5696,109 @@ fn asmExpr(
5846 const tree = &astgen.file.tree;5696 const tree = &astgen.file.tree;
5847 const main_tokens = tree.nodes.items(.main_token);5697 const main_tokens = tree.nodes.items(.main_token);
5848 const node_datas = tree.nodes.items(.data);5698 const node_datas = tree.nodes.items(.data);
5699 const token_tags = tree.tokens.items(.tag);
58495700
5850 const asm_source = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, full.ast.template);5701 const asm_source = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, full.ast.template);
58515702
5852 // See https://github.com/ziglang/zig/issues/215 and related issues discussing5703 // See https://github.com/ziglang/zig/issues/215 and related issues discussing
5853 // possible inline assembly improvements. Until this is settled, I am avoiding5704 // possible inline assembly improvements. Until then here is status quo AstGen
5854 // potentially wasting time implementing status quo assembly that is not used by5705 // for assembly syntax. It's used by std lib crypto aesni.zig.
5855 // any of the standard library.5706
5856 if (full.outputs.len > 1) {5707 if (full.outputs.len > 32) {
5857 return astgen.failNode(node, "TODO more than 1 asm output", .{});5708 return astgen.failNode(full.outputs[32], "too many asm outputs", .{});
5858 }5709 }
5859 const output: struct {5710 var outputs_buffer: [32]Zir.Inst.Asm.Output = undefined;
5860 ty: Zir.Inst.Ref = .none,5711 const outputs = outputs_buffer[0..full.outputs.len];
5861 constraint: u32 = 0,5712
5862 } = if (full.outputs.len == 0) .{} else blk: {5713 var output_type_bits: u32 = 0;
5863 const output_node = full.outputs[0];5714
5864 const out_type_node = node_datas[output_node].lhs;5715 for (full.outputs) |output_node, i| {
5865 if (out_type_node == 0) {5716 const symbolic_name = main_tokens[output_node];
5866 return astgen.failNode(out_type_node, "TODO asm with non -> output", .{});5717 const name = try gz.identAsString(symbolic_name);
5718 const constraint_token = symbolic_name + 2;
5719 const constraint = (try gz.strLitAsString(constraint_token)).index;
5720 const has_arrow = token_tags[symbolic_name + 4] == .arrow;
5721 if (has_arrow) {
5722 output_type_bits |= @as(u32, 1) << @intCast(u5, i);
5723 const out_type_node = node_datas[output_node].lhs;
5724 const out_type_inst = try typeExpr(gz, scope, out_type_node);
5725 outputs[i] = .{
5726 .name = name,
5727 .constraint = constraint,
5728 .operand = out_type_inst,
5729 };
5730 } else {
5731 const ident_token = symbolic_name + 4;
5732 const str_index = try gz.identAsString(ident_token);
5733 // TODO this needs extra code for local variables. Have a look at #215 and related
5734 // issues and decide how to handle outputs. Do we want this to be identifiers?
5735 // Or maybe we want to force this to be expressions with a pointer type.
5736 // Until that is figured out this is only hooked up for referencing Decls.
5737 const operand = try gz.addStrTok(.decl_ref, str_index, ident_token);
5738 outputs[i] = .{
5739 .name = name,
5740 .constraint = constraint,
5741 .operand = operand,
5742 };
5867 }5743 }
5868 const constraint_token = main_tokens[output_node] + 2;5744 }
5869 break :blk .{
5870 .ty = try typeExpr(gz, scope, out_type_node),
5871 .constraint = (try gz.strLitAsString(constraint_token)).index,
5872 };
5873 };
58745745
5875 const constraints = try arena.alloc(u32, full.inputs.len);5746 if (full.inputs.len > 32) {
5876 const args = try arena.alloc(Zir.Inst.Ref, full.inputs.len);5747 return astgen.failNode(full.inputs[32], "too many asm inputs", .{});
5748 }
5749 var inputs_buffer: [32]Zir.Inst.Asm.Input = undefined;
5750 const inputs = inputs_buffer[0..full.inputs.len];
5751
5752 for (full.inputs) |input_node, i| {
5753 const symbolic_name = main_tokens[input_node];
5754 const name = try gz.identAsString(symbolic_name);
5755 const constraint_token = symbolic_name + 2;
5756 const constraint = (try gz.strLitAsString(constraint_token)).index;
5757 const has_arrow = token_tags[symbolic_name + 4] == .arrow;
5758 const operand = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[input_node].lhs);
5759 inputs[i] = .{
5760 .name = name,
5761 .constraint = constraint,
5762 .operand = operand,
5763 };
5764 }
58775765
5878 for (full.inputs) |input, i| {5766 var clobbers_buffer: [32]u32 = undefined;
5879 const constraint_token = main_tokens[input] + 2;5767 var clobber_i: usize = 0;
5880 constraints[i] = (try gz.strLitAsString(constraint_token)).index;5768 if (full.first_clobber) |first_clobber| clobbers: {
5881 args[i] = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[input].lhs);5769 // asm ("foo" ::: "a", "b")
5770 // asm ("foo" ::: "a", "b",)
5771 var tok_i = first_clobber;
5772 while (true) : (tok_i += 1) {
5773 if (clobber_i >= clobbers_buffer.len) {
5774 return astgen.failTok(tok_i, "too many asm clobbers", .{});
5775 }
5776 clobbers_buffer[clobber_i] = (try gz.strLitAsString(tok_i)).index;
5777 clobber_i += 1;
5778 tok_i += 1;
5779 switch (token_tags[tok_i]) {
5780 .r_paren => break :clobbers,
5781 .comma => {
5782 if (token_tags[tok_i + 1] == .r_paren) {
5783 break :clobbers;
5784 } else {
5785 continue;
5786 }
5787 },
5788 else => unreachable,
5789 }
5790 }
5882 }5791 }
58835792
5884 const tag: Zir.Inst.Tag = if (full.volatile_token != null) .asm_volatile else .@"asm";5793 const result = try gz.addAsm(.{
5885 const result = try gz.addPlNode(tag, node, Zir.Inst.Asm{5794 .node = node,
5886 .asm_source = asm_source,5795 .asm_source = asm_source,
5887 .output_type = output.ty,5796 .is_volatile = full.volatile_token != null,
5888 .args_len = @intCast(u32, full.inputs.len),5797 .output_type_bits = output_type_bits,
5889 .clobbers_len = 0, // TODO implement asm clobbers5798 .outputs = outputs,
5799 .inputs = inputs,
5800 .clobbers = clobbers_buffer[0..clobber_i],
5890 });5801 });
5891
5892 try astgen.extra.ensureCapacity(astgen.gpa, astgen.extra.items.len +
5893 args.len + constraints.len + @boolToInt(output.ty != .none));
5894 if (output.ty != .none) {
5895 astgen.extra.appendAssumeCapacity(output.constraint);
5896 }
5897 astgen.appendRefsAssumeCapacity(args);
5898 astgen.extra.appendSliceAssumeCapacity(constraints);
5899
5900 return rvalue(gz, scope, rl, result, node);5802 return rvalue(gz, scope, rl, result, node);
5901}5803}
59025804
...@@ -5982,14 +5884,7 @@ fn asRlPtr(...@@ -5982,14 +5884,7 @@ fn asRlPtr(
5982 // as well as the store instruction, instead passing the result as an rvalue.5884 // as well as the store instruction, instead passing the result as an rvalue.
5983 const astgen = parent_gz.astgen;5885 const astgen = parent_gz.astgen;
59845886
5985 var as_scope: GenZir = .{5887 var as_scope = parent_gz.makeSubBlock(scope);
5986 .parent = scope,
5987 .decl_node_index = parent_gz.decl_node_index,
5988 .astgen = astgen,
5989 .force_comptime = parent_gz.force_comptime,
5990 .ref_start_index = parent_gz.ref_start_index,
5991 .instructions = .{},
5992 };
5993 defer as_scope.instructions.deinit(astgen.gpa);5888 defer as_scope.instructions.deinit(astgen.gpa);
59945889
5995 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);5890 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);
...@@ -6701,14 +6596,8 @@ fn cImport(...@@ -6701,14 +6596,8 @@ fn cImport(
6701 const astgen = gz.astgen;6596 const astgen = gz.astgen;
6702 const gpa = astgen.gpa;6597 const gpa = astgen.gpa;
67036598
6704 var block_scope: GenZir = .{6599 var block_scope = gz.makeSubBlock(scope);
6705 .parent = scope,6600 block_scope.force_comptime = true;
6706 .decl_node_index = gz.decl_node_index,
6707 .astgen = astgen,
6708 .force_comptime = true,
6709 .ref_start_index = gz.ref_start_index,
6710 .instructions = .{},
6711 };
6712 defer block_scope.instructions.deinit(gpa);6601 defer block_scope.instructions.deinit(gpa);
67136602
6714 const block_inst = try gz.addBlock(.c_import, node);6603 const block_inst = try gz.addBlock(.c_import, node);
...@@ -6802,43 +6691,44 @@ fn callExpr(...@@ -6802,43 +6691,44 @@ fn callExpr(
6802}6691}
68036692
6804pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{6693pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{
6805 .{ "u8", .u8_type },6694 .{ "anyerror", .anyerror_type },
6806 .{ "i8", .i8_type },6695 .{ "anyframe", .anyframe_type },
6807 .{ "u16", .u16_type },6696 .{ "bool", .bool_type },
6808 .{ "i16", .i16_type },
6809 .{ "u32", .u32_type },
6810 .{ "i32", .i32_type },
6811 .{ "u64", .u64_type },
6812 .{ "i64", .i64_type },
6813 .{ "usize", .usize_type },
6814 .{ "isize", .isize_type },
6815 .{ "c_short", .c_short_type },
6816 .{ "c_ushort", .c_ushort_type },
6817 .{ "c_int", .c_int_type },6697 .{ "c_int", .c_int_type },
6818 .{ "c_uint", .c_uint_type },
6819 .{ "c_long", .c_long_type },6698 .{ "c_long", .c_long_type },
6820 .{ "c_ulong", .c_ulong_type },6699 .{ "c_longdouble", .c_longdouble_type },
6821 .{ "c_longlong", .c_longlong_type },6700 .{ "c_longlong", .c_longlong_type },
6701 .{ "c_short", .c_short_type },
6702 .{ "c_uint", .c_uint_type },
6703 .{ "c_ulong", .c_ulong_type },
6822 .{ "c_ulonglong", .c_ulonglong_type },6704 .{ "c_ulonglong", .c_ulonglong_type },
6823 .{ "c_longdouble", .c_longdouble_type },6705 .{ "c_ushort", .c_ushort_type },
6706 .{ "c_void", .c_void_type },
6707 .{ "comptime_float", .comptime_float_type },
6708 .{ "comptime_int", .comptime_int_type },
6709 .{ "f128", .f128_type },
6824 .{ "f16", .f16_type },6710 .{ "f16", .f16_type },
6825 .{ "f32", .f32_type },6711 .{ "f32", .f32_type },
6826 .{ "f64", .f64_type },6712 .{ "f64", .f64_type },
6827 .{ "f128", .f128_type },6713 .{ "false", .bool_false },
6828 .{ "c_void", .c_void_type },6714 .{ "i16", .i16_type },
6829 .{ "bool", .bool_type },6715 .{ "i32", .i32_type },
6830 .{ "void", .void_type },6716 .{ "i64", .i64_type },
6831 .{ "type", .type_type },6717 .{ "i128", .i128_type },
6832 .{ "anyerror", .anyerror_type },6718 .{ "i8", .i8_type },
6833 .{ "comptime_int", .comptime_int_type },6719 .{ "isize", .isize_type },
6834 .{ "comptime_float", .comptime_float_type },
6835 .{ "noreturn", .noreturn_type },6720 .{ "noreturn", .noreturn_type },
6836 .{ "null", .null_type },
6837 .{ "undefined", .undefined_type },
6838 .{ "undefined", .undef },
6839 .{ "null", .null_value },6721 .{ "null", .null_value },
6840 .{ "true", .bool_true },6722 .{ "true", .bool_true },
6841 .{ "false", .bool_false },6723 .{ "type", .type_type },
6724 .{ "u16", .u16_type },
6725 .{ "u32", .u32_type },
6726 .{ "u64", .u64_type },
6727 .{ "u128", .u128_type },
6728 .{ "u8", .u8_type },
6729 .{ "undefined", .undef },
6730 .{ "usize", .usize_type },
6731 .{ "void", .void_type },
6842});6732});
68436733
6844fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index) bool {6734fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index) bool {
src/Module.zig+95-2
...@@ -1085,6 +1085,21 @@ pub const Scope = struct {...@@ -1085,6 +1085,21 @@ pub const Scope = struct {
1085 /// a result location pointer.1085 /// a result location pointer.
1086 labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{},1086 labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{},
10871087
1088 suspend_node: ast.Node.Index = 0,
1089 nosuspend_node: ast.Node.Index = 0,
1090
1091 pub fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {
1092 return .{
1093 .force_comptime = gz.force_comptime,
1094 .ref_start_index = gz.ref_start_index,
1095 .decl_node_index = gz.decl_node_index,
1096 .parent = scope,
1097 .astgen = gz.astgen,
1098 .suspend_node = gz.suspend_node,
1099 .nosuspend_node = gz.nosuspend_node,
1100 };
1101 }
1102
1088 pub const Label = struct {1103 pub const Label = struct {
1089 token: ast.TokenIndex,1104 token: ast.TokenIndex,
1090 block_inst: Zir.Inst.Index,1105 block_inst: Zir.Inst.Index,
...@@ -1674,9 +1689,9 @@ pub const Scope = struct {...@@ -1674,9 +1689,9 @@ pub const Scope = struct {
1674 @as(usize, @boolToInt(args.type_inst != .none)) +1689 @as(usize, @boolToInt(args.type_inst != .none)) +
1675 @as(usize, @boolToInt(args.align_inst != .none)),1690 @as(usize, @boolToInt(args.align_inst != .none)),
1676 );1691 );
1677 const payload_index = gz.astgen.addExtra(Zir.Inst.AllocExtended{1692 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.AllocExtended{
1678 .src_node = gz.nodeIndexToRelative(args.node),1693 .src_node = gz.nodeIndexToRelative(args.node),
1679 }) catch unreachable; // ensureUnusedCapacity above1694 });
1680 if (args.type_inst != .none) {1695 if (args.type_inst != .none) {
1681 astgen.extra.appendAssumeCapacity(@enumToInt(args.type_inst));1696 astgen.extra.appendAssumeCapacity(@enumToInt(args.type_inst));
1682 }1697 }
...@@ -1703,6 +1718,64 @@ pub const Scope = struct {...@@ -1703,6 +1718,64 @@ pub const Scope = struct {
1703 return gz.indexToRef(new_index);1718 return gz.indexToRef(new_index);
1704 }1719 }
17051720
1721 pub fn addAsm(
1722 gz: *GenZir,
1723 args: struct {
1724 /// Absolute node index. This function does the conversion to offset from Decl.
1725 node: ast.Node.Index,
1726 asm_source: Zir.Inst.Ref,
1727 output_type_bits: u32,
1728 is_volatile: bool,
1729 outputs: []const Zir.Inst.Asm.Output,
1730 inputs: []const Zir.Inst.Asm.Input,
1731 clobbers: []const u32,
1732 },
1733 ) !Zir.Inst.Ref {
1734 const astgen = gz.astgen;
1735 const gpa = astgen.gpa;
1736
1737 try gz.instructions.ensureUnusedCapacity(gpa, 1);
1738 try astgen.instructions.ensureUnusedCapacity(gpa, 1);
1739 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Asm).Struct.fields.len +
1740 args.outputs.len * @typeInfo(Zir.Inst.Asm.Output).Struct.fields.len +
1741 args.inputs.len * @typeInfo(Zir.Inst.Asm.Input).Struct.fields.len +
1742 args.clobbers.len);
1743
1744 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Asm{
1745 .src_node = gz.nodeIndexToRelative(args.node),
1746 .asm_source = args.asm_source,
1747 .output_type_bits = args.output_type_bits,
1748 });
1749 for (args.outputs) |output| {
1750 _ = gz.astgen.addExtraAssumeCapacity(output);
1751 }
1752 for (args.inputs) |input| {
1753 _ = gz.astgen.addExtraAssumeCapacity(input);
1754 }
1755 gz.astgen.extra.appendSliceAssumeCapacity(args.clobbers);
1756
1757 // * 0b00000000_000XXXXX - `outputs_len`.
1758 // * 0b000000XX_XXX00000 - `inputs_len`.
1759 // * 0b0XXXXX00_00000000 - `clobbers_len`.
1760 // * 0bX0000000_00000000 - is volatile
1761 const small: u16 = @intCast(u16, args.outputs.len) |
1762 @intCast(u16, args.inputs.len << 5) |
1763 @intCast(u16, args.clobbers.len << 10) |
1764 (@as(u16, @boolToInt(args.is_volatile)) << 15);
1765
1766 const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len);
1767 astgen.instructions.appendAssumeCapacity(.{
1768 .tag = .extended,
1769 .data = .{ .extended = .{
1770 .opcode = .@"asm",
1771 .small = small,
1772 .operand = payload_index,
1773 } },
1774 });
1775 gz.instructions.appendAssumeCapacity(new_index);
1776 return gz.indexToRef(new_index);
1777 }
1778
1706 /// Note that this returns a `Zir.Inst.Index` not a ref.1779 /// Note that this returns a `Zir.Inst.Index` not a ref.
1707 /// Does *not* append the block instruction to the scope.1780 /// Does *not* append the block instruction to the scope.
1708 /// Leaves the `payload_index` field undefined.1781 /// Leaves the `payload_index` field undefined.
...@@ -2209,6 +2282,18 @@ pub const SrcLoc = struct {...@@ -2209,6 +2282,18 @@ pub const SrcLoc = struct {
2209 const token_starts = tree.tokens.items(.start);2282 const token_starts = tree.tokens.items(.start);
2210 return token_starts[tok_index];2283 return token_starts[tok_index];
2211 },2284 },
2285
2286 .node_offset_anyframe_type => |node_off| {
2287 const tree = src_loc.file_scope.tree;
2288 const node_datas = tree.nodes.items(.data);
2289 const node_tags = tree.nodes.items(.tag);
2290 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2291 const node = node_datas[parent_node].rhs;
2292 const main_tokens = tree.nodes.items(.main_token);
2293 const tok_index = main_tokens[node];
2294 const token_starts = tree.tokens.items(.start);
2295 return token_starts[tok_index];
2296 },
2212 }2297 }
2213 }2298 }
2214};2299};
...@@ -2368,6 +2453,12 @@ pub const LazySrcLoc = union(enum) {...@@ -2368,6 +2453,12 @@ pub const LazySrcLoc = union(enum) {
2368 /// the return type node.2453 /// the return type node.
2369 /// The Decl is determined contextually.2454 /// The Decl is determined contextually.
2370 node_offset_fn_type_ret_ty: i32,2455 node_offset_fn_type_ret_ty: i32,
2456 /// The source location points to the type expression of an `anyframe->T`
2457 /// expression, found by taking this AST node index offset from the containing
2458 /// Decl AST node, which points to a `anyframe->T` expression AST node. Next, navigate
2459 /// to the type expression.
2460 /// The Decl is determined contextually.
2461 node_offset_anyframe_type: i32,
23712462
2372 /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.2463 /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.
2373 pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {2464 pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {
...@@ -2407,6 +2498,7 @@ pub const LazySrcLoc = union(enum) {...@@ -2407,6 +2498,7 @@ pub const LazySrcLoc = union(enum) {
2407 .node_offset_switch_range,2498 .node_offset_switch_range,
2408 .node_offset_fn_type_cc,2499 .node_offset_fn_type_cc,
2409 .node_offset_fn_type_ret_ty,2500 .node_offset_fn_type_ret_ty,
2501 .node_offset_anyframe_type,
2410 => .{2502 => .{
2411 .file_scope = scope.getFileScope(),2503 .file_scope = scope.getFileScope(),
2412 .parent_decl_node = scope.srcDecl().?.src_node,2504 .parent_decl_node = scope.srcDecl().?.src_node,
...@@ -2453,6 +2545,7 @@ pub const LazySrcLoc = union(enum) {...@@ -2453,6 +2545,7 @@ pub const LazySrcLoc = union(enum) {
2453 .node_offset_switch_range,2545 .node_offset_switch_range,
2454 .node_offset_fn_type_cc,2546 .node_offset_fn_type_cc,
2455 .node_offset_fn_type_ret_ty,2547 .node_offset_fn_type_ret_ty,
2548 .node_offset_anyframe_type,
2456 => .{2549 => .{
2457 .file_scope = decl.getFileScope(),2550 .file_scope = decl.getFileScope(),
2458 .parent_decl_node = decl.src_node,2551 .parent_decl_node = decl.src_node,
src/Sema.zig+59-26
...@@ -138,14 +138,13 @@ pub fn analyzeBody(...@@ -138,14 +138,13 @@ pub fn analyzeBody(
138 .alloc_inferred_comptime => try sema.zirAllocInferredComptime(block, inst),138 .alloc_inferred_comptime => try sema.zirAllocInferredComptime(block, inst),
139 .alloc_mut => try sema.zirAllocMut(block, inst),139 .alloc_mut => try sema.zirAllocMut(block, inst),
140 .alloc_comptime => try sema.zirAllocComptime(block, inst),140 .alloc_comptime => try sema.zirAllocComptime(block, inst),
141 .anyframe_type => try sema.zirAnyframeType(block, inst),
141 .array_cat => try sema.zirArrayCat(block, inst),142 .array_cat => try sema.zirArrayCat(block, inst),
142 .array_mul => try sema.zirArrayMul(block, inst),143 .array_mul => try sema.zirArrayMul(block, inst),
143 .array_type => try sema.zirArrayType(block, inst),144 .array_type => try sema.zirArrayType(block, inst),
144 .array_type_sentinel => try sema.zirArrayTypeSentinel(block, inst),145 .array_type_sentinel => try sema.zirArrayTypeSentinel(block, inst),
145 .as => try sema.zirAs(block, inst),146 .as => try sema.zirAs(block, inst),
146 .as_node => try sema.zirAsNode(block, inst),147 .as_node => try sema.zirAsNode(block, inst),
147 .@"asm" => try sema.zirAsm(block, inst, false),
148 .asm_volatile => try sema.zirAsm(block, inst, true),
149 .bit_and => try sema.zirBitwise(block, inst, .bit_and),148 .bit_and => try sema.zirBitwise(block, inst, .bit_and),
150 .bit_not => try sema.zirBitNot(block, inst),149 .bit_not => try sema.zirBitNot(block, inst),
151 .bit_or => try sema.zirBitwise(block, inst, .bit_or),150 .bit_or => try sema.zirBitwise(block, inst, .bit_or),
...@@ -518,6 +517,7 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro...@@ -518,6 +517,7 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
518 .frame_address => return sema.zirFrameAddress( block, extended),517 .frame_address => return sema.zirFrameAddress( block, extended),
519 .alloc => return sema.zirAllocExtended( block, extended),518 .alloc => return sema.zirAllocExtended( block, extended),
520 .builtin_extern => return sema.zirBuiltinExtern( block, extended),519 .builtin_extern => return sema.zirBuiltinExtern( block, extended),
520 .@"asm" => return sema.zirAsm( block, extended),
521 .c_undef => return sema.zirCUndef( block, extended),521 .c_undef => return sema.zirCUndef( block, extended),
522 .c_include => return sema.zirCInclude( block, extended),522 .c_include => return sema.zirCInclude( block, extended),
523 .c_define => return sema.zirCDefine( block, extended),523 .c_define => return sema.zirCDefine( block, extended),
...@@ -2173,6 +2173,19 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)...@@ -2173,6 +2173,19 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
2173 return sema.mod.constType(sema.arena, .unneeded, array_ty);2173 return sema.mod.constType(sema.arena, .unneeded, array_ty);
2174}2174}
21752175
2176fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
2177 const tracy = trace(@src());
2178 defer tracy.end();
2179
2180 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2181 const src = inst_data.src();
2182 const operand_src: LazySrcLoc = .{ .node_offset_anyframe_type = inst_data.src_node };
2183 const return_type = try sema.resolveType(block, operand_src, inst_data.operand);
2184 const anyframe_type = try Type.Tag.anyframe_T.create(sema.arena, return_type);
2185
2186 return sema.mod.constType(sema.arena, src, anyframe_type);
2187}
2188
2176fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {2189fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
2177 const tracy = trace(@src());2190 const tracy = trace(@src());
2178 defer tracy.end();2191 defer tracy.end();
...@@ -4394,42 +4407,62 @@ fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*I...@@ -4394,42 +4407,62 @@ fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*I
4394fn zirAsm(4407fn zirAsm(
4395 sema: *Sema,4408 sema: *Sema,
4396 block: *Scope.Block,4409 block: *Scope.Block,
4397 inst: Zir.Inst.Index,4410 extended: Zir.Inst.Extended.InstData,
4398 is_volatile: bool,
4399) InnerError!*Inst {4411) InnerError!*Inst {
4400 const tracy = trace(@src());4412 const tracy = trace(@src());
4401 defer tracy.end();4413 defer tracy.end();
44024414
4403 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;4415 const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);
4404 const src = inst_data.src();4416 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
4405 const asm_source_src: LazySrcLoc = .{ .node_offset_asm_source = inst_data.src_node };4417 const asm_source_src: LazySrcLoc = .{ .node_offset_asm_source = extra.data.src_node };
4406 const ret_ty_src: LazySrcLoc = .{ .node_offset_asm_ret_ty = inst_data.src_node };4418 const ret_ty_src: LazySrcLoc = .{ .node_offset_asm_ret_ty = extra.data.src_node };
4407 const extra = sema.code.extraData(Zir.Inst.Asm, inst_data.payload_index);
4408 const asm_source = try sema.resolveConstString(block, asm_source_src, extra.data.asm_source);4419 const asm_source = try sema.resolveConstString(block, asm_source_src, extra.data.asm_source);
4420 const outputs_len = @truncate(u5, extended.small);
4421 const inputs_len = @truncate(u5, extended.small >> 5);
4422 const clobbers_len = @truncate(u5, extended.small >> 10);
4423 const is_volatile = @truncate(u1, extended.small >> 15) != 0;
4424
4425 if (outputs_len > 1) {
4426 return sema.mod.fail(&block.base, src, "TODO implement Sema for asm with more than 1 output", .{});
4427 }
44094428
4410 var extra_i = extra.end;4429 var extra_i = extra.end;
4430 var output_type_bits = extra.data.output_type_bits;
4431
4411 const Output = struct { constraint: []const u8, ty: Type };4432 const Output = struct { constraint: []const u8, ty: Type };
4412 const output: ?Output = if (extra.data.output_type != .none) blk: {4433 const output: ?Output = if (outputs_len == 0) null else blk: {
4413 const constraint = sema.code.nullTerminatedString(sema.code.extra[extra_i]);4434 const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i);
4414 extra_i += 1;4435 extra_i = output.end;
4436
4437 const is_type = @truncate(u1, output_type_bits) != 0;
4438 output_type_bits >>= 1;
4439
4440 if (!is_type) {
4441 return sema.mod.fail(&block.base, src, "TODO implement Sema for asm with non `->` output", .{});
4442 }
4443
4444 const constraint = sema.code.nullTerminatedString(output.data.constraint);
4415 break :blk Output{4445 break :blk Output{
4416 .constraint = constraint,4446 .constraint = constraint,
4417 .ty = try sema.resolveType(block, ret_ty_src, extra.data.output_type),4447 .ty = try sema.resolveType(block, ret_ty_src, output.data.operand),
4418 };4448 };
4419 } else null;4449 };
44204450
4421 const args = try sema.arena.alloc(*Inst, extra.data.args_len);4451 const args = try sema.arena.alloc(*Inst, inputs_len);
4422 const inputs = try sema.arena.alloc([]const u8, extra.data.args_len);4452 const inputs = try sema.arena.alloc([]const u8, inputs_len);
4423 const clobbers = try sema.arena.alloc([]const u8, extra.data.clobbers_len);
44244453
4425 for (args) |*arg| {4454 for (args) |*arg, arg_i| {
4426 arg.* = try sema.resolveInst(@intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]));4455 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
4427 extra_i += 1;4456 extra_i = input.end;
4428 }4457
4429 for (inputs) |*name| {4458 const name = sema.code.nullTerminatedString(input.data.name);
4430 name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]);4459 _ = name; // TODO: use the name
4431 extra_i += 1;4460
4461 arg.* = try sema.resolveInst(input.data.operand);
4462 inputs[arg_i] = sema.code.nullTerminatedString(input.data.constraint);
4432 }4463 }
4464
4465 const clobbers = try sema.arena.alloc([]const u8, clobbers_len);
4433 for (clobbers) |*name| {4466 for (clobbers) |*name| {
4434 name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]);4467 name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]);
4435 extra_i += 1;4468 extra_i += 1;
...@@ -5408,7 +5441,7 @@ fn zirFuncExtended(...@@ -5408,7 +5441,7 @@ fn zirFuncExtended(
54085441
5409 var extra_index: usize = extra.end;5442 var extra_index: usize = extra.end;
5410 if (small.has_lib_name) {5443 if (small.has_lib_name) {
5411 const lib_name = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);5444 const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
5412 extra_index += 1;5445 extra_index += 1;
5413 return sema.mod.fail(&block.base, src, "TODO: implement Sema func lib name", .{});5446 return sema.mod.fail(&block.base, src, "TODO: implement Sema func lib name", .{});
5414 }5447 }
...@@ -5428,7 +5461,7 @@ fn zirFuncExtended(...@@ -5428,7 +5461,7 @@ fn zirFuncExtended(
5428 } else .Unspecified;5461 } else .Unspecified;
54295462
5430 const param_types = sema.code.refSlice(extra_index, extra.data.param_types_len);5463 const param_types = sema.code.refSlice(extra_index, extra.data.param_types_len);
5431 extra_index += 1;5464 extra_index += param_types.len;
54325465
5433 const body = sema.code.extra[extra_index..][0..extra.data.body_len];5466 const body = sema.code.extra[extra_index..][0..extra.data.body_len];
54345467
src/Zir.zig+153-57
...@@ -60,7 +60,8 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) struct { data: T, en...@@ -60,7 +60,8 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) struct { data: T, en
60 @field(result, field.name) = switch (field.field_type) {60 @field(result, field.name) = switch (field.field_type) {
61 u32 => code.extra[i],61 u32 => code.extra[i],
62 Inst.Ref => @intToEnum(Inst.Ref, code.extra[i]),62 Inst.Ref => @intToEnum(Inst.Ref, code.extra[i]),
63 else => unreachable,63 i32 => @bitCast(i32, code.extra[i]),
64 else => @compileError("bad field type"),
64 };65 };
65 i += 1;66 i += 1;
66 }67 }
...@@ -165,18 +166,15 @@ pub const Inst = struct {...@@ -165,18 +166,15 @@ pub const Inst = struct {
165 /// error if the indexable object is not indexable.166 /// error if the indexable object is not indexable.
166 /// Uses the `un_node` field. The AST node is the for loop node.167 /// Uses the `un_node` field. The AST node is the for loop node.
167 indexable_ptr_len,168 indexable_ptr_len,
169 /// Create a `anyframe->T` type.
170 /// Uses the `un_node` field.
171 anyframe_type,
168 /// Type coercion. No source location attached.172 /// Type coercion. No source location attached.
169 /// Uses the `bin` field.173 /// Uses the `bin` field.
170 as,174 as,
171 /// Type coercion to the function's return type.175 /// Type coercion to the function's return type.
172 /// Uses the `pl_node` field. Payload is `As`. AST node could be many things.176 /// Uses the `pl_node` field. Payload is `As`. AST node could be many things.
173 as_node,177 as_node,
174 /// Inline assembly. Non-volatile.
175 /// Uses the `pl_node` union field. Payload is `Asm`. AST node is the assembly node.
176 @"asm",
177 /// Inline assembly with the volatile attribute.
178 /// Uses the `pl_node` union field. Payload is `Asm`. AST node is the assembly node.
179 asm_volatile,
180 /// Bitwise AND. `&`178 /// Bitwise AND. `&`
181 bit_and,179 bit_and,
182 /// Bitcast a value to a different type.180 /// Bitcast a value to a different type.
...@@ -967,10 +965,9 @@ pub const Inst = struct {...@@ -967,10 +965,9 @@ pub const Inst = struct {
967 .array_type_sentinel,965 .array_type_sentinel,
968 .elem_type,966 .elem_type,
969 .indexable_ptr_len,967 .indexable_ptr_len,
968 .anyframe_type,
970 .as,969 .as,
971 .as_node,970 .as_node,
972 .@"asm",
973 .asm_volatile,
974 .bit_and,971 .bit_and,
975 .bitcast,972 .bitcast,
976 .bitcast_result_ptr,973 .bitcast_result_ptr,
...@@ -1259,6 +1256,14 @@ pub const Inst = struct {...@@ -1259,6 +1256,14 @@ pub const Inst = struct {
1259 /// The `@extern` builtin.1256 /// The `@extern` builtin.
1260 /// `operand` is payload index to `BinNode`.1257 /// `operand` is payload index to `BinNode`.
1261 builtin_extern,1258 builtin_extern,
1259 /// Inline assembly.
1260 /// `small`:
1261 /// * 0b00000000_000XXXXX - `outputs_len`.
1262 /// * 0b000000XX_XXX00000 - `inputs_len`.
1263 /// * 0b0XXXXX00_00000000 - `clobbers_len`.
1264 /// * 0bX0000000_00000000 - is volatile
1265 /// `operand` is payload index to `Asm`.
1266 @"asm",
1262 /// `operand` is payload index to `UnNode`.1267 /// `operand` is payload index to `UnNode`.
1263 c_undef,1268 c_undef,
1264 /// `operand` is payload index to `UnNode`.1269 /// `operand` is payload index to `UnNode`.
...@@ -1313,6 +1318,8 @@ pub const Inst = struct {...@@ -1313,6 +1318,8 @@ pub const Inst = struct {
1313 i32_type,1318 i32_type,
1314 u64_type,1319 u64_type,
1315 i64_type,1320 i64_type,
1321 u128_type,
1322 i128_type,
1316 usize_type,1323 usize_type,
1317 isize_type,1324 isize_type,
1318 c_short_type,1325 c_short_type,
...@@ -1336,17 +1343,10 @@ pub const Inst = struct {...@@ -1336,17 +1343,10 @@ pub const Inst = struct {
1336 comptime_int_type,1343 comptime_int_type,
1337 comptime_float_type,1344 comptime_float_type,
1338 noreturn_type,1345 noreturn_type,
1346 anyframe_type,
1339 null_type,1347 null_type,
1340 undefined_type,1348 undefined_type,
1341 fn_noreturn_no_args_type,
1342 fn_void_no_args_type,
1343 fn_naked_noreturn_no_args_type,
1344 fn_ccc_void_no_args_type,
1345 single_const_pointer_to_comptime_int_type,
1346 const_slice_u8_type,
1347 enum_literal_type,1349 enum_literal_type,
1348 manyptr_u8_type,
1349 manyptr_const_u8_type,
1350 atomic_ordering_type,1350 atomic_ordering_type,
1351 atomic_rmw_op_type,1351 atomic_rmw_op_type,
1352 calling_convention_type,1352 calling_convention_type,
...@@ -1355,6 +1355,14 @@ pub const Inst = struct {...@@ -1355,6 +1355,14 @@ pub const Inst = struct {
1355 call_options_type,1355 call_options_type,
1356 export_options_type,1356 export_options_type,
1357 extern_options_type,1357 extern_options_type,
1358 manyptr_u8_type,
1359 manyptr_const_u8_type,
1360 fn_noreturn_no_args_type,
1361 fn_void_no_args_type,
1362 fn_naked_noreturn_no_args_type,
1363 fn_ccc_void_no_args_type,
1364 single_const_pointer_to_comptime_int_type,
1365 const_slice_u8_type,
13581366
1359 /// `undefined` (untyped)1367 /// `undefined` (untyped)
1360 undef,1368 undef,
...@@ -1418,6 +1426,14 @@ pub const Inst = struct {...@@ -1418,6 +1426,14 @@ pub const Inst = struct {
1418 .ty = Type.initTag(.type),1426 .ty = Type.initTag(.type),
1419 .val = Value.initTag(.i64_type),1427 .val = Value.initTag(.i64_type),
1420 },1428 },
1429 .u128_type = .{
1430 .ty = Type.initTag(.type),
1431 .val = Value.initTag(.u128_type),
1432 },
1433 .i128_type = .{
1434 .ty = Type.initTag(.type),
1435 .val = Value.initTag(.i128_type),
1436 },
1421 .usize_type = .{1437 .usize_type = .{
1422 .ty = Type.initTag(.type),1438 .ty = Type.initTag(.type),
1423 .val = Value.initTag(.usize_type),1439 .val = Value.initTag(.usize_type),
...@@ -1510,6 +1526,10 @@ pub const Inst = struct {...@@ -1510,6 +1526,10 @@ pub const Inst = struct {
1510 .ty = Type.initTag(.type),1526 .ty = Type.initTag(.type),
1511 .val = Value.initTag(.noreturn_type),1527 .val = Value.initTag(.noreturn_type),
1512 },1528 },
1529 .anyframe_type = .{
1530 .ty = Type.initTag(.type),
1531 .val = Value.initTag(.anyframe_type),
1532 },
1513 .null_type = .{1533 .null_type = .{
1514 .ty = Type.initTag(.type),1534 .ty = Type.initTag(.type),
1515 .val = Value.initTag(.null_type),1535 .val = Value.initTag(.null_type),
...@@ -1806,17 +1826,35 @@ pub const Inst = struct {...@@ -1806,17 +1826,35 @@ pub const Inst = struct {
1806 }1826 }
1807 };1827 };
18081828
1809 /// Stored in extra. Trailing is:1829 /// Trailing:
1810 /// * output_constraint: u32 // index into string_bytes (null terminated) if output is present1830 /// 0. Output for every outputs_len
1811 /// * arg: Ref // for every args_len.1831 /// 1. Input for every inputs_len
1812 /// * constraint: u32 // index into string_bytes (null terminated) for every args_len.1832 /// 2. clobber: u32 // index into string_bytes (null terminated) for every clobbers_len.
1813 /// * clobber: u32 // index into string_bytes (null terminated) for every clobbers_len.
1814 pub const Asm = struct {1833 pub const Asm = struct {
1834 src_node: i32,
1815 asm_source: Ref,1835 asm_source: Ref,
1816 /// May be omitted.1836 /// 1 bit for each outputs_len: whether it uses `-> T` or not.
1817 output_type: Ref,1837 /// 0b0 - operand is a pointer to where to store the output.
1818 args_len: u32,1838 /// 0b1 - operand is a type; asm expression has the output as the result.
1819 clobbers_len: u32,1839 /// 0b0X is the first output, 0bX0 is the second, etc.
1840 output_type_bits: u32,
1841
1842 pub const Output = struct {
1843 /// index into string_bytes (null terminated)
1844 name: u32,
1845 /// index into string_bytes (null terminated)
1846 constraint: u32,
1847 /// How to interpret this is determined by `output_type_bits`.
1848 operand: Ref,
1849 };
1850
1851 pub const Input = struct {
1852 /// index into string_bytes (null terminated)
1853 name: u32,
1854 /// index into string_bytes (null terminated)
1855 constraint: u32,
1856 operand: Ref,
1857 };
1820 };1858 };
18211859
1822 /// Trailing:1860 /// Trailing:
...@@ -2298,6 +2336,7 @@ const Writer = struct {...@@ -2298,6 +2336,7 @@ const Writer = struct {
2298 .alloc_mut,2336 .alloc_mut,
2299 .alloc_comptime,2337 .alloc_comptime,
2300 .indexable_ptr_len,2338 .indexable_ptr_len,
2339 .anyframe_type,
2301 .bit_not,2340 .bit_not,
2302 .bool_not,2341 .bool_not,
2303 .negate,2342 .negate,
...@@ -2430,10 +2469,6 @@ const Writer = struct {...@@ -2430,10 +2469,6 @@ const Writer = struct {
2430 .builtin_async_call,2469 .builtin_async_call,
2431 => try self.writePlNode(stream, inst),2470 => try self.writePlNode(stream, inst),
24322471
2433 .@"asm",
2434 .asm_volatile,
2435 => try self.writePlNodeAsm(stream, inst),
2436
2437 .error_set_decl => try self.writePlNodeErrorSetDecl(stream, inst),2472 .error_set_decl => try self.writePlNodeErrorSetDecl(stream, inst),
24382473
2439 .add_with_overflow,2474 .add_with_overflow,
...@@ -2603,7 +2638,9 @@ const Writer = struct {...@@ -2603,7 +2638,9 @@ const Writer = struct {
2603 .builtin_src,2638 .builtin_src,
2604 => try self.writeExtNode(stream, extended),2639 => try self.writeExtNode(stream, extended),
26052640
2606 .func,2641 .@"asm" => try self.writeAsm(stream, extended),
2642 .func => try self.writeFuncExtended(stream, extended),
2643
2607 .alloc,2644 .alloc,
2608 .builtin_extern,2645 .builtin_extern,
2609 .c_undef,2646 .c_undef,
...@@ -2794,49 +2831,74 @@ const Writer = struct {...@@ -2794,49 +2831,74 @@ const Writer = struct {
2794 try self.writeSrc(stream, inst_data.src());2831 try self.writeSrc(stream, inst_data.src());
2795 }2832 }
27962833
2797 fn writePlNodeAsm(self: *Writer, stream: anytype, inst: Inst.Index) !void {2834 fn writeAsm(self: *Writer, stream: anytype, extended: Inst.Extended.InstData) !void {
2798 const inst_data = self.code.instructions.items(.data)[inst].pl_node;2835 const extra = self.code.extraData(Inst.Asm, extended.operand);
2799 const extra = self.code.extraData(Inst.Asm, inst_data.payload_index);2836 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
2800 var extra_i: usize = extra.end;2837 const outputs_len = @truncate(u5, extended.small);
2838 const inputs_len = @truncate(u5, extended.small >> 5);
2839 const clobbers_len = @truncate(u5, extended.small >> 10);
2840 const is_volatile = @truncate(u1, extended.small >> 15) != 0;
28012841
2802 if (extra.data.output_type != .none) {2842 try self.writeFlag(stream, "volatile, ", is_volatile);
2803 const constraint_str_index = self.code.extra[extra_i];2843 try self.writeInstRef(stream, extra.data.asm_source);
2804 extra_i += 1;2844 try stream.writeAll(", ");
2805 const constraint = self.code.nullTerminatedString(constraint_str_index);2845
2806 try stream.print("\"{}\"->", .{std.zig.fmtEscapes(constraint)});2846 var extra_i: usize = extra.end;
2807 try self.writeInstRef(stream, extra.data.output_type);2847 var output_type_bits = extra.data.output_type_bits;
2808 try stream.writeAll(", ");
2809 }
2810 {2848 {
2811 var i: usize = 0;2849 var i: usize = 0;
2812 while (i < extra.data.args_len) : (i += 1) {2850 while (i < outputs_len) : (i += 1) {
2813 const arg = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_i]);2851 const output = self.code.extraData(Inst.Asm.Output, extra_i);
2814 extra_i += 1;2852 extra_i = output.end;
2815 try self.writeInstRef(stream, arg);2853
2816 try stream.writeAll(", ");2854 const is_type = @truncate(u1, output_type_bits) != 0;
2855 output_type_bits >>= 1;
2856
2857 const name = self.code.nullTerminatedString(output.data.name);
2858 const constraint = self.code.nullTerminatedString(output.data.constraint);
2859 try stream.print("output({}, \"{}\", ", .{
2860 std.zig.fmtId(name), std.zig.fmtEscapes(constraint),
2861 });
2862 try self.writeFlag(stream, "->", is_type);
2863 try self.writeInstRef(stream, output.data.operand);
2864 try stream.writeAll(")");
2865 if (i + 1 < outputs_len) {
2866 try stream.writeAll("), ");
2867 }
2817 }2868 }
2818 }2869 }
2819 {2870 {
2820 var i: usize = 0;2871 var i: usize = 0;
2821 while (i < extra.data.args_len) : (i += 1) {2872 while (i < inputs_len) : (i += 1) {
2822 const str_index = self.code.extra[extra_i];2873 const input = self.code.extraData(Inst.Asm.Input, extra_i);
2823 extra_i += 1;2874 extra_i = input.end;
2824 const constraint = self.code.nullTerminatedString(str_index);2875
2825 try stream.print("\"{}\", ", .{std.zig.fmtEscapes(constraint)});2876 const name = self.code.nullTerminatedString(input.data.name);
2877 const constraint = self.code.nullTerminatedString(input.data.constraint);
2878 try stream.print("input({}, \"{}\", ", .{
2879 std.zig.fmtId(name), std.zig.fmtEscapes(constraint),
2880 });
2881 try self.writeInstRef(stream, input.data.operand);
2882 try stream.writeAll(")");
2883 if (i + 1 < inputs_len) {
2884 try stream.writeAll(", ");
2885 }
2826 }2886 }
2827 }2887 }
2828 {2888 {
2829 var i: usize = 0;2889 var i: usize = 0;
2830 while (i < extra.data.clobbers_len) : (i += 1) {2890 while (i < clobbers_len) : (i += 1) {
2831 const str_index = self.code.extra[extra_i];2891 const str_index = self.code.extra[extra_i];
2832 extra_i += 1;2892 extra_i += 1;
2833 const clobber = self.code.nullTerminatedString(str_index);2893 const clobber = self.code.nullTerminatedString(str_index);
2834 try stream.print("{}, ", .{std.zig.fmtId(clobber)});2894 try stream.print("{}", .{std.zig.fmtId(clobber)});
2895 if (i + 1 < clobbers_len) {
2896 try stream.writeAll(", ");
2897 }
2835 }2898 }
2836 }2899 }
2837 try self.writeInstRef(stream, extra.data.asm_source);
2838 try stream.writeAll(") ");2900 try stream.writeAll(") ");
2839 try self.writeSrc(stream, inst_data.src());2901 try self.writeSrc(stream, src);
2840 }2902 }
28412903
2842 fn writePlNodeOverflowArithmetic(self: *Writer, stream: anytype, inst: Inst.Index) !void {2904 fn writePlNodeOverflowArithmetic(self: *Writer, stream: anytype, inst: Inst.Index) !void {
...@@ -3467,6 +3529,40 @@ const Writer = struct {...@@ -3467,6 +3529,40 @@ const Writer = struct {
3467 );3529 );
3468 }3530 }
34693531
3532 fn writeFuncExtended(self: *Writer, stream: anytype, extended: Inst.Extended.InstData) !void {
3533 const extra = self.code.extraData(Inst.ExtendedFunc, extended.operand);
3534 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
3535 const small = @bitCast(Inst.ExtendedFunc.Small, extended.small);
3536
3537 var extra_index: usize = extra.end;
3538 if (small.has_lib_name) {
3539 const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
3540 extra_index += 1;
3541 try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)});
3542 }
3543 const cc: Inst.Ref = if (!small.has_cc) .none else blk: {
3544 const cc = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
3545 extra_index += 1;
3546 break :blk cc;
3547 };
3548
3549 const param_types = self.code.refSlice(extra_index, extra.data.param_types_len);
3550 extra_index += param_types.len;
3551
3552 const body = self.code.extra[extra_index..][0..extra.data.body_len];
3553
3554 return self.writeFuncCommon(
3555 stream,
3556 param_types,
3557 extra.data.return_type,
3558 small.is_inferred_error,
3559 small.is_var_args,
3560 cc,
3561 body,
3562 src,
3563 );
3564 }
3565
3470 fn writeBoolBr(self: *Writer, stream: anytype, inst: Inst.Index) !void {3566 fn writeBoolBr(self: *Writer, stream: anytype, inst: Inst.Index) !void {
3471 const inst_data = self.code.instructions.items(.data)[inst].bool_br;3567 const inst_data = self.code.instructions.items(.data)[inst].bool_br;
3472 const extra = self.code.extraData(Inst.Block, inst_data.payload_index);3568 const extra = self.code.extraData(Inst.Block, inst_data.payload_index);
src/type.zig+37-7
...@@ -95,6 +95,8 @@ pub const Type = extern union {...@@ -95,6 +95,8 @@ pub const Type = extern union {
9595
96 .anyerror_void_error_union, .error_union => return .ErrorUnion,96 .anyerror_void_error_union, .error_union => return .ErrorUnion,
9797
98 .anyframe_T, .@"anyframe" => return .AnyFrame,
99
98 .empty_struct,100 .empty_struct,
99 .empty_struct_literal,101 .empty_struct_literal,
100 .@"struct",102 .@"struct",
...@@ -620,6 +622,7 @@ pub const Type = extern union {...@@ -620,6 +622,7 @@ pub const Type = extern union {
620 .call_options,622 .call_options,
621 .export_options,623 .export_options,
622 .extern_options,624 .extern_options,
625 .@"anyframe",
623 => unreachable,626 => unreachable,
624627
625 .array_u8,628 .array_u8,
...@@ -637,6 +640,7 @@ pub const Type = extern union {...@@ -637,6 +640,7 @@ pub const Type = extern union {
637 .optional,640 .optional,
638 .optional_single_mut_pointer,641 .optional_single_mut_pointer,
639 .optional_single_const_pointer,642 .optional_single_const_pointer,
643 .anyframe_T,
640 => return self.copyPayloadShallow(allocator, Payload.ElemType),644 => return self.copyPayloadShallow(allocator, Payload.ElemType),
641645
642 .int_signed,646 .int_signed,
...@@ -754,6 +758,7 @@ pub const Type = extern union {...@@ -754,6 +758,7 @@ pub const Type = extern union {
754 .void,758 .void,
755 .type,759 .type,
756 .anyerror,760 .anyerror,
761 .@"anyframe",
757 .comptime_int,762 .comptime_int,
758 .comptime_float,763 .comptime_float,
759 .noreturn,764 .noreturn,
...@@ -820,6 +825,12 @@ pub const Type = extern union {...@@ -820,6 +825,12 @@ pub const Type = extern union {
820 continue;825 continue;
821 },826 },
822827
828 .anyframe_T => {
829 const return_type = ty.castTag(.anyframe_T).?.data;
830 try writer.print("anyframe->", .{});
831 ty = return_type;
832 continue;
833 },
823 .array_u8 => {834 .array_u8 => {
824 const len = ty.castTag(.array_u8).?.data;835 const len = ty.castTag(.array_u8).?.data;
825 return writer.print("[{d}]u8", .{len});836 return writer.print("[{d}]u8", .{len});
...@@ -994,6 +1005,7 @@ pub const Type = extern union {...@@ -994,6 +1005,7 @@ pub const Type = extern union {
994 .void => return Value.initTag(.void_type),1005 .void => return Value.initTag(.void_type),
995 .type => return Value.initTag(.type_type),1006 .type => return Value.initTag(.type_type),
996 .anyerror => return Value.initTag(.anyerror_type),1007 .anyerror => return Value.initTag(.anyerror_type),
1008 .@"anyframe" => return Value.initTag(.anyframe_type),
997 .comptime_int => return Value.initTag(.comptime_int_type),1009 .comptime_int => return Value.initTag(.comptime_int_type),
998 .comptime_float => return Value.initTag(.comptime_float_type),1010 .comptime_float => return Value.initTag(.comptime_float_type),
999 .noreturn => return Value.initTag(.noreturn_type),1011 .noreturn => return Value.initTag(.noreturn_type),
...@@ -1075,6 +1087,8 @@ pub const Type = extern union {...@@ -1075,6 +1087,8 @@ pub const Type = extern union {
1075 .call_options,1087 .call_options,
1076 .export_options,1088 .export_options,
1077 .extern_options,1089 .extern_options,
1090 .@"anyframe",
1091 .anyframe_T,
1078 => true,1092 => true,
10791093
1080 .@"struct" => {1094 .@"struct" => {
...@@ -1223,6 +1237,8 @@ pub const Type = extern union {...@@ -1223,6 +1237,8 @@ pub const Type = extern union {
1223 .pointer,1237 .pointer,
1224 .manyptr_u8,1238 .manyptr_u8,
1225 .manyptr_const_u8,1239 .manyptr_const_u8,
1240 .@"anyframe",
1241 .anyframe_T,
1226 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),1242 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
12271243
1228 .c_short => return @divExact(CType.short.sizeInBits(target), 8),1244 .c_short => return @divExact(CType.short.sizeInBits(target), 8),
...@@ -1388,7 +1404,11 @@ pub const Type = extern union {...@@ -1388,7 +1404,11 @@ pub const Type = extern union {
1388 .i64, .u64 => return 8,1404 .i64, .u64 => return 8,
1389 .u128, .i128 => return 16,1405 .u128, .i128 => return 16,
13901406
1391 .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8),1407 .isize,
1408 .usize,
1409 .@"anyframe",
1410 .anyframe_T,
1411 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
13921412
1393 .const_slice,1413 .const_slice,
1394 .mut_slice,1414 .mut_slice,
...@@ -1536,7 +1556,11 @@ pub const Type = extern union {...@@ -1536,7 +1556,11 @@ pub const Type = extern union {
1536 .i64, .u64, .f64 => 64,1556 .i64, .u64, .f64 => 64,
1537 .u128, .i128, .f128 => 128,1557 .u128, .i128, .f128 => 128,
15381558
1539 .isize, .usize => target.cpu.arch.ptrBitWidth(),1559 .isize,
1560 .usize,
1561 .@"anyframe",
1562 .anyframe_T,
1563 => target.cpu.arch.ptrBitWidth(),
15401564
1541 .const_slice,1565 .const_slice,
1542 .mut_slice,1566 .mut_slice,
...@@ -2256,6 +2280,8 @@ pub const Type = extern union {...@@ -2256,6 +2280,8 @@ pub const Type = extern union {
2256 .call_options,2280 .call_options,
2257 .export_options,2281 .export_options,
2258 .extern_options,2282 .extern_options,
2283 .@"anyframe",
2284 .anyframe_T,
2259 => return null,2285 => return null,
22602286
2261 .@"struct" => {2287 .@"struct" => {
...@@ -2666,9 +2692,10 @@ pub const Type = extern union {...@@ -2666,9 +2692,10 @@ pub const Type = extern union {
2666 comptime_int,2692 comptime_int,
2667 comptime_float,2693 comptime_float,
2668 noreturn,2694 noreturn,
2695 @"anyframe",
2696 @"null",
2697 @"undefined",
2669 enum_literal,2698 enum_literal,
2670 manyptr_u8,
2671 manyptr_const_u8,
2672 atomic_ordering,2699 atomic_ordering,
2673 atomic_rmw_op,2700 atomic_rmw_op,
2674 calling_convention,2701 calling_convention,
...@@ -2677,15 +2704,15 @@ pub const Type = extern union {...@@ -2677,15 +2704,15 @@ pub const Type = extern union {
2677 call_options,2704 call_options,
2678 export_options,2705 export_options,
2679 extern_options,2706 extern_options,
2680 @"null",2707 manyptr_u8,
2681 @"undefined",2708 manyptr_const_u8,
2682 fn_noreturn_no_args,2709 fn_noreturn_no_args,
2683 fn_void_no_args,2710 fn_void_no_args,
2684 fn_naked_noreturn_no_args,2711 fn_naked_noreturn_no_args,
2685 fn_ccc_void_no_args,2712 fn_ccc_void_no_args,
2686 single_const_pointer_to_comptime_int,2713 single_const_pointer_to_comptime_int,
2687 anyerror_void_error_union,
2688 const_slice_u8,2714 const_slice_u8,
2715 anyerror_void_error_union,
2689 /// This is a special type for variadic parameters of a function call.2716 /// This is a special type for variadic parameters of a function call.
2690 /// Casts to it will validate that the type can be passed to a c calling convetion function.2717 /// Casts to it will validate that the type can be passed to a c calling convetion function.
2691 var_args_param,2718 var_args_param,
...@@ -2719,6 +2746,7 @@ pub const Type = extern union {...@@ -2719,6 +2746,7 @@ pub const Type = extern union {
2719 optional_single_mut_pointer,2746 optional_single_mut_pointer,
2720 optional_single_const_pointer,2747 optional_single_const_pointer,
2721 error_union,2748 error_union,
2749 anyframe_T,
2722 error_set,2750 error_set,
2723 error_set_single,2751 error_set_single,
2724 empty_struct,2752 empty_struct,
...@@ -2790,6 +2818,7 @@ pub const Type = extern union {...@@ -2790,6 +2818,7 @@ pub const Type = extern union {
2790 .call_options,2818 .call_options,
2791 .export_options,2819 .export_options,
2792 .extern_options,2820 .extern_options,
2821 .@"anyframe",
2793 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),2822 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
27942823
2795 .array_u8,2824 .array_u8,
...@@ -2807,6 +2836,7 @@ pub const Type = extern union {...@@ -2807,6 +2836,7 @@ pub const Type = extern union {
2807 .optional,2836 .optional,
2808 .optional_single_mut_pointer,2837 .optional_single_mut_pointer,
2809 .optional_single_const_pointer,2838 .optional_single_const_pointer,
2839 .anyframe_T,
2810 => Payload.ElemType,2840 => Payload.ElemType,
28112841
2812 .int_signed,2842 .int_signed,
src/value.zig+15-8
...@@ -55,17 +55,10 @@ pub const Value = extern union {...@@ -55,17 +55,10 @@ pub const Value = extern union {
55 comptime_int_type,55 comptime_int_type,
56 comptime_float_type,56 comptime_float_type,
57 noreturn_type,57 noreturn_type,
58 anyframe_type,
58 null_type,59 null_type,
59 undefined_type,60 undefined_type,
60 fn_noreturn_no_args_type,
61 fn_void_no_args_type,
62 fn_naked_noreturn_no_args_type,
63 fn_ccc_void_no_args_type,
64 single_const_pointer_to_comptime_int_type,
65 const_slice_u8_type,
66 enum_literal_type,61 enum_literal_type,
67 manyptr_u8_type,
68 manyptr_const_u8_type,
69 atomic_ordering_type,62 atomic_ordering_type,
70 atomic_rmw_op_type,63 atomic_rmw_op_type,
71 calling_convention_type,64 calling_convention_type,
...@@ -74,6 +67,14 @@ pub const Value = extern union {...@@ -74,6 +67,14 @@ pub const Value = extern union {
74 call_options_type,67 call_options_type,
75 export_options_type,68 export_options_type,
76 extern_options_type,69 extern_options_type,
70 manyptr_u8_type,
71 manyptr_const_u8_type,
72 fn_noreturn_no_args_type,
73 fn_void_no_args_type,
74 fn_naked_noreturn_no_args_type,
75 fn_ccc_void_no_args_type,
76 single_const_pointer_to_comptime_int_type,
77 const_slice_u8_type,
7778
78 undef,79 undef,
79 zero,80 zero,
...@@ -166,6 +167,7 @@ pub const Value = extern union {...@@ -166,6 +167,7 @@ pub const Value = extern union {
166 .fn_naked_noreturn_no_args_type,167 .fn_naked_noreturn_no_args_type,
167 .fn_ccc_void_no_args_type,168 .fn_ccc_void_no_args_type,
168 .single_const_pointer_to_comptime_int_type,169 .single_const_pointer_to_comptime_int_type,
170 .anyframe_type,
169 .const_slice_u8_type,171 .const_slice_u8_type,
170 .enum_literal_type,172 .enum_literal_type,
171 .undef,173 .undef,
...@@ -334,6 +336,7 @@ pub const Value = extern union {...@@ -334,6 +336,7 @@ pub const Value = extern union {
334 .fn_naked_noreturn_no_args_type,336 .fn_naked_noreturn_no_args_type,
335 .fn_ccc_void_no_args_type,337 .fn_ccc_void_no_args_type,
336 .single_const_pointer_to_comptime_int_type,338 .single_const_pointer_to_comptime_int_type,
339 .anyframe_type,
337 .const_slice_u8_type,340 .const_slice_u8_type,
338 .enum_literal_type,341 .enum_literal_type,
339 .undef,342 .undef,
...@@ -502,6 +505,7 @@ pub const Value = extern union {...@@ -502,6 +505,7 @@ pub const Value = extern union {
502 .fn_naked_noreturn_no_args_type => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),505 .fn_naked_noreturn_no_args_type => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),
503 .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),506 .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),
504 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),507 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
508 .anyframe_type => return out_stream.writeAll("anyframe"),
505 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),509 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),
506 .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),510 .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),
507 .manyptr_u8_type => return out_stream.writeAll("[*]u8"),511 .manyptr_u8_type => return out_stream.writeAll("[*]u8"),
...@@ -633,6 +637,7 @@ pub const Value = extern union {...@@ -633,6 +637,7 @@ pub const Value = extern union {
633 .fn_naked_noreturn_no_args_type => Type.initTag(.fn_naked_noreturn_no_args),637 .fn_naked_noreturn_no_args_type => Type.initTag(.fn_naked_noreturn_no_args),
634 .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),638 .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),
635 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),639 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
640 .anyframe_type => Type.initTag(.@"anyframe"),
636 .const_slice_u8_type => Type.initTag(.const_slice_u8),641 .const_slice_u8_type => Type.initTag(.const_slice_u8),
637 .enum_literal_type => Type.initTag(.enum_literal),642 .enum_literal_type => Type.initTag(.enum_literal),
638 .manyptr_u8_type => Type.initTag(.manyptr_u8),643 .manyptr_u8_type => Type.initTag(.manyptr_u8),
...@@ -1070,6 +1075,7 @@ pub const Value = extern union {...@@ -1070,6 +1075,7 @@ pub const Value = extern union {
1070 .fn_naked_noreturn_no_args_type,1075 .fn_naked_noreturn_no_args_type,
1071 .fn_ccc_void_no_args_type,1076 .fn_ccc_void_no_args_type,
1072 .single_const_pointer_to_comptime_int_type,1077 .single_const_pointer_to_comptime_int_type,
1078 .anyframe_type,
1073 .const_slice_u8_type,1079 .const_slice_u8_type,
1074 .enum_literal_type,1080 .enum_literal_type,
1075 .ty,1081 .ty,
...@@ -1338,6 +1344,7 @@ pub const Value = extern union {...@@ -1338,6 +1344,7 @@ pub const Value = extern union {
1338 .fn_naked_noreturn_no_args_type,1344 .fn_naked_noreturn_no_args_type,
1339 .fn_ccc_void_no_args_type,1345 .fn_ccc_void_no_args_type,
1340 .single_const_pointer_to_comptime_int_type,1346 .single_const_pointer_to_comptime_int_type,
1347 .anyframe_type,
1341 .const_slice_u8_type,1348 .const_slice_u8_type,
1342 .enum_literal_type,1349 .enum_literal_type,
1343 .manyptr_u8_type,1350 .manyptr_u8_type,