diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-04-23 18:28:46 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-23 18:35:21 -0700 |
| commit | b40a8efb9a72e69cd7e9061fc4c08d5e705b0fbd (patch) | |
| tree | b62377262318b6f6d76a0b75d43dff106e553a2f /src/Sema.zig | |
| parent | 183ee0965fac6322651666834776d9832cc95ddd (diff) | |
| download | zig-b40a8efb9a72e69cd7e9061fc4c08d5e705b0fbd.tar.gz zig-b40a8efb9a72e69cd7e9061fc4c08d5e705b0fbd.zip | |
stage2: implement `anyframe`, `anyframe->T` and fix assembly
* AstGen: implement `anyframe_literal` and `anyframe_type`.
* Introduce `makeSubBlock` to avoid redundant AstGen code for GenZir
scopes. Allows adding/removing a field without possibility of
accidentally introducing a bug of forgetting to set the new field.
* Add to GenZir `nosuspend_node` and `suspend_node` in preparation for
implementing `suspend` blocks and `nosuspend` blocks.
* AstGen: fix assembly to support clobbers, multiple outputs, and
outputs without `->` syntax.
- `asm` and `asm_volatile` move to `Extended` enum with `small` being
repurposed for a few things. This frees up 2 ZIR tags, 1 of which
is used in this commit and 1 is leftover.
* AstGen: fix `simple_types` incorrectly having multiple conflicting
values for "undefined" and "null".
- Also add "anyframe" to `simple_types`.
* Add `anyframe_type` to type.zig, value.zig and `Zir.Inst.Ref`.
- Also add i128 and u128 types to `Zir.Inst.Ref` and `simple_types`.
* Sema/Zir: Fix incorrect math causing the function body to be messed
up for Extended-encoded functions.
* Zir: support `i32` fields for "extra" payloads.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 85 |
1 files changed, 59 insertions, 26 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 6b9bf5cc1e..fd9bc39fd9 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -138,14 +138,13 @@ pub fn analyzeBody( .alloc_inferred_comptime => try sema.zirAllocInferredComptime(block, inst), .alloc_mut => try sema.zirAllocMut(block, inst), .alloc_comptime => try sema.zirAllocComptime(block, inst), + .anyframe_type => try sema.zirAnyframeType(block, inst), .array_cat => try sema.zirArrayCat(block, inst), .array_mul => try sema.zirArrayMul(block, inst), .array_type => try sema.zirArrayType(block, inst), .array_type_sentinel => try sema.zirArrayTypeSentinel(block, inst), .as => try sema.zirAs(block, inst), .as_node => try sema.zirAsNode(block, inst), - .@"asm" => try sema.zirAsm(block, inst, false), - .asm_volatile => try sema.zirAsm(block, inst, true), .bit_and => try sema.zirBitwise(block, inst, .bit_and), .bit_not => try sema.zirBitNot(block, inst), .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 .frame_address => return sema.zirFrameAddress( block, extended), .alloc => return sema.zirAllocExtended( block, extended), .builtin_extern => return sema.zirBuiltinExtern( block, extended), + .@"asm" => return sema.zirAsm( block, extended), .c_undef => return sema.zirCUndef( block, extended), .c_include => return sema.zirCInclude( block, extended), .c_define => return sema.zirCDefine( block, extended), @@ -2173,6 +2173,19 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) return sema.mod.constType(sema.arena, .unneeded, array_ty); } +fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { + const tracy = trace(@src()); + defer tracy.end(); + + const inst_data = sema.code.instructions.items(.data)[inst].un_node; + const src = inst_data.src(); + const operand_src: LazySrcLoc = .{ .node_offset_anyframe_type = inst_data.src_node }; + const return_type = try sema.resolveType(block, operand_src, inst_data.operand); + const anyframe_type = try Type.Tag.anyframe_T.create(sema.arena, return_type); + + return sema.mod.constType(sema.arena, src, anyframe_type); +} + fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { const tracy = trace(@src()); defer tracy.end(); @@ -4394,42 +4407,62 @@ fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*I fn zirAsm( sema: *Sema, block: *Scope.Block, - inst: Zir.Inst.Index, - is_volatile: bool, + extended: Zir.Inst.Extended.InstData, ) InnerError!*Inst { const tracy = trace(@src()); defer tracy.end(); - const inst_data = sema.code.instructions.items(.data)[inst].pl_node; - const src = inst_data.src(); - const asm_source_src: LazySrcLoc = .{ .node_offset_asm_source = inst_data.src_node }; - const ret_ty_src: LazySrcLoc = .{ .node_offset_asm_ret_ty = inst_data.src_node }; - const extra = sema.code.extraData(Zir.Inst.Asm, inst_data.payload_index); + const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand); + const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; + const asm_source_src: LazySrcLoc = .{ .node_offset_asm_source = extra.data.src_node }; + const ret_ty_src: LazySrcLoc = .{ .node_offset_asm_ret_ty = extra.data.src_node }; const asm_source = try sema.resolveConstString(block, asm_source_src, extra.data.asm_source); + const outputs_len = @truncate(u5, extended.small); + const inputs_len = @truncate(u5, extended.small >> 5); + const clobbers_len = @truncate(u5, extended.small >> 10); + const is_volatile = @truncate(u1, extended.small >> 15) != 0; + + if (outputs_len > 1) { + return sema.mod.fail(&block.base, src, "TODO implement Sema for asm with more than 1 output", .{}); + } var extra_i = extra.end; + var output_type_bits = extra.data.output_type_bits; + const Output = struct { constraint: []const u8, ty: Type }; - const output: ?Output = if (extra.data.output_type != .none) blk: { - const constraint = sema.code.nullTerminatedString(sema.code.extra[extra_i]); - extra_i += 1; + const output: ?Output = if (outputs_len == 0) null else blk: { + const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i); + extra_i = output.end; + + const is_type = @truncate(u1, output_type_bits) != 0; + output_type_bits >>= 1; + + if (!is_type) { + return sema.mod.fail(&block.base, src, "TODO implement Sema for asm with non `->` output", .{}); + } + + const constraint = sema.code.nullTerminatedString(output.data.constraint); break :blk Output{ .constraint = constraint, - .ty = try sema.resolveType(block, ret_ty_src, extra.data.output_type), + .ty = try sema.resolveType(block, ret_ty_src, output.data.operand), }; - } else null; + }; - const args = try sema.arena.alloc(*Inst, extra.data.args_len); - const inputs = try sema.arena.alloc([]const u8, extra.data.args_len); - const clobbers = try sema.arena.alloc([]const u8, extra.data.clobbers_len); + const args = try sema.arena.alloc(*Inst, inputs_len); + const inputs = try sema.arena.alloc([]const u8, inputs_len); - for (args) |*arg| { - arg.* = try sema.resolveInst(@intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i])); - extra_i += 1; - } - for (inputs) |*name| { - name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]); - extra_i += 1; + for (args) |*arg, arg_i| { + const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i); + extra_i = input.end; + + const name = sema.code.nullTerminatedString(input.data.name); + _ = name; // TODO: use the name + + arg.* = try sema.resolveInst(input.data.operand); + inputs[arg_i] = sema.code.nullTerminatedString(input.data.constraint); } + + const clobbers = try sema.arena.alloc([]const u8, clobbers_len); for (clobbers) |*name| { name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]); extra_i += 1; @@ -5408,7 +5441,7 @@ fn zirFuncExtended( var extra_index: usize = extra.end; if (small.has_lib_name) { - const lib_name = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); + const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]); extra_index += 1; return sema.mod.fail(&block.base, src, "TODO: implement Sema func lib name", .{}); } @@ -5428,7 +5461,7 @@ fn zirFuncExtended( } else .Unspecified; const param_types = sema.code.refSlice(extra_index, extra.data.param_types_len); - extra_index += 1; + extra_index += param_types.len; const body = sema.code.extra[extra_index..][0..extra.data.body_len]; |
