| author | |
| committer | |
| log | b40a8efb9a72e69cd7e9061fc4c08d5e705b0fbd |
| tree | b62377262318b6f6d76a0b75d43dff106e553a2f |
| parent | 183ee0965fac6322651666834776d9832cc95ddd |
* 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); |
| 1548 | 1552 | ||
| 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( |
| 2095 | 2090 | ||
| 2096 | // Detect whether the initialization expression actually uses the | 2091 | // 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); |
| 2106 | 2095 | ||
| 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 | }; |
| 3780 | 3769 | ||
| 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); |
| 3791 | 3773 | ||
| ... | @@ -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); |
| 3813 | 3795 | ||
| 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); |
| 3823 | 3798 | ||
| 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); |
| 3827 | 3802 | ||
| 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); |
| 3837 | 3805 | ||
| 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; |
| 3880 | 3848 | ||
| 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); |
| 3891 | 3852 | ||
| ... | @@ -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); |
| 3908 | 3869 | ||
| 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); |
| 3918 | 3872 | ||
| 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_ptr | 3893 | // instructions into place until we know whether to keep store_to_block_ptr |
| 3940 | // instructions or not. | 3894 | // instructions or not. |
| 3941 | 3895 | ||
| 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); |
| 3951 | 3898 | ||
| 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); |
| 4142 | 4089 | ||
| 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); |
| 4169 | 4110 | ||
| 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); |
| 4180 | 4114 | ||
| ... | @@ -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); |
| 4220 | 4154 | ||
| 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); |
| 4230 | 4157 | ||
| 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_ptr | 4200 | // instructions into place until we know whether to keep store_to_block_ptr |
| 4274 | // instructions or not. | 4201 | // instructions or not. |
| 4275 | 4202 | ||
| 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); |
| 4285 | 4205 | ||
| 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); |
| 4426 | 4346 | ||
| 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); |
| 4437 | 4350 | ||
| 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); |
| 4447 | 4353 | ||
| 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 | } |
| 4507 | 4413 | ||
| 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); |
| 4517 | 4416 | ||
| 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); |
| 4559 | 4458 | ||
| 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); |
| 4569 | 4461 | ||
| 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); |
| 4661 | 4553 | ||
| 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); |
| 4672 | 4557 | ||
| 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); |
| 4682 | 4560 | ||
| 4683 | // check condition i < array_expr.len | 4561 | // check condition i < array_expr.len |
| ... | @@ -4714,14 +4592,7 @@ fn forExpr( | ... | @@ -4714,14 +4592,7 @@ fn forExpr( |
| 4714 | }); | 4592 | }); |
| 4715 | } | 4593 | } |
| 4716 | 4594 | ||
| 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); |
| 4726 | 4597 | ||
| 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); |
| 4775 | 4646 | ||
| 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); |
| 4785 | 4649 | ||
| 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); |
| 5078 | 4942 | ||
| 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); |
| 5089 | 4946 | ||
| ... | @@ -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); |
| 5092 | 4949 | ||
| 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); |
| 5103 | 4953 | ||
| 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); | ||
| 5849 | 5700 | ||
| 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); |
| 5851 | 5702 | ||
| 5852 | // See https://github.com/ziglang/zig/issues/215 and related issues discussing | 5703 | // See https://github.com/ziglang/zig/issues/215 and related issues discussing |
| 5853 | // possible inline assembly improvements. Until this is settled, I am avoiding | 5704 | // possible inline assembly improvements. Until then here is status quo AstGen |
| 5854 | // potentially wasting time implementing status quo assembly that is not used by | 5705 | // 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 | }; | ||
| 5874 | 5745 | ||
| 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 | } | ||
| 5877 | 5765 | ||
| 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 | } |
| 5883 | 5792 | ||
| 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 clobbers | 5798 | .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 | } |
| 5902 | 5804 | ||
| ... | @@ -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; |
| 5984 | 5886 | ||
| 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); |
| 5994 | 5889 | ||
| 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; |
| 6703 | 6598 | ||
| 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); |
| 6713 | 6602 | ||
| 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 | } |
| 6803 | 6692 | ||
| 6804 | pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{ | 6693 | pub 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 | }); |
| 6843 | 6733 | ||
| 6844 | fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index) bool { | 6734 | fn 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) = .{}, |
| 1087 | 1087 | ||
| 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 above | 1694 | }); |
| 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 | } |
| 1705 | 1720 | ||
| 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, | ||
| 2371 | 2462 | ||
| 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 | } |
| 2175 | 2175 | ||
| 2176 | fn 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 | |||
| 2176 | fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | 2189 | fn 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 |
| 4394 | fn zirAsm( | 4407 | fn 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(); |
| 4402 | 4414 | ||
| 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 | } | ||
| 4409 | 4428 | ||
| 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 | }; |
| 4420 | 4450 | ||
| 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); | ||
| 4424 | 4453 | ||
| 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( |
| 5408 | 5441 | ||
| 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; |
| 5429 | 5462 | ||
| 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; |
| 5432 | 5465 | ||
| 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]; |
| 5434 | 5467 |
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, | ||
| 1358 | 1366 | ||
| 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 | }; |
| 1808 | 1828 | ||
| 1809 | /// Stored in extra. Trailing is: | 1829 | /// Trailing: |
| 1810 | /// * output_constraint: u32 // index into string_bytes (null terminated) if output is present | 1830 | /// 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 | }; |
| 1821 | 1859 | ||
| 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), |
| 2432 | 2471 | ||
| 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), |
| 2438 | 2473 | ||
| 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), |
| 2605 | 2640 | ||
| 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 | } |
| 2796 | 2833 | ||
| 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; | ||
| 2801 | 2841 | ||
| 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 | } |
| 2841 | 2903 | ||
| 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 | } |
| 3469 | 3531 | ||
| 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 { |
| 95 | 95 | ||
| 96 | .anyerror_void_error_union, .error_union => return .ErrorUnion, | 96 | .anyerror_void_error_union, .error_union => return .ErrorUnion, |
| 97 | 97 | ||
| 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, |
| 624 | 627 | ||
| 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), |
| 641 | 645 | ||
| 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 | }, |
| 822 | 827 | ||
| 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, |
| 1079 | 1093 | ||
| 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), |
| 1227 | 1243 | ||
| 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, |
| 1390 | 1406 | ||
| 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), | ||
| 1392 | 1412 | ||
| 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, |
| 1538 | 1558 | ||
| 1539 | .isize, .usize => target.cpu.arch.ptrBitWidth(), | 1559 | .isize, |
| 1560 | .usize, | ||
| 1561 | .@"anyframe", | ||
| 1562 | .anyframe_T, | ||
| 1563 | => target.cpu.arch.ptrBitWidth(), | ||
| 1540 | 1564 | ||
| 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, |
| 2260 | 2286 | ||
| 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"), |
| 2794 | 2823 | ||
| 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, |
| 2811 | 2841 | ||
| 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, | ||
| 77 | 78 | ||
| 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, |