From 15922069651ce964b6d12b9ad83ae02aa2266e89 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 24 Apr 2021 14:39:44 -0700 Subject: [PATCH] AstGen: implement await and resume based on @Vexu's code from before --- src/AstGen.zig | 24 ++++++++++++++++++++++-- src/Sema.zig | 20 ++++++++++++++++++++ src/Zir.zig | 10 ++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/AstGen.zig b/src/AstGen.zig index 69ef73dc4a..1954b10089 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -959,7 +959,19 @@ pub fn awaitExpr( node: ast.Node.Index, ) InnerError!Zir.Inst.Ref { const astgen = gz.astgen; - return astgen.failNode(node, "TODO AstGen awaitExpr", .{}); + const tree = &astgen.file.tree; + const node_datas = tree.nodes.items(.data); + const rhs_node = node_datas[node].lhs; + + if (gz.suspend_node != 0) { + return astgen.failNodeNotes(node, "cannot await inside suspend block", .{}, &[_]u32{ + try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}), + }); + } + const operand = try expr(gz, scope, .none, rhs_node); + const tag: Zir.Inst.Tag = if (gz.nosuspend_node != 0) .await_nosuspend else .@"await"; + const result = try gz.addUnNode(tag, operand, node); + return rvalue(gz, scope, rl, result, node); } pub fn resumeExpr( @@ -969,7 +981,12 @@ pub fn resumeExpr( node: ast.Node.Index, ) InnerError!Zir.Inst.Ref { const astgen = gz.astgen; - return astgen.failNode(node, "TODO AstGen resumeExpr", .{}); + const tree = &astgen.file.tree; + const node_datas = tree.nodes.items(.data); + const rhs_node = node_datas[node].lhs; + const operand = try expr(gz, scope, .none, rhs_node); + const result = try gz.addUnNode(.@"resume", operand, node); + return rvalue(gz, scope, rl, result, node); } pub fn fnProtoExpr( @@ -2005,6 +2022,9 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner .memset, .builtin_async_call, .c_import, + .@"resume", + .@"await", + .await_nosuspend, .extended, => break :b false, diff --git a/src/Sema.zig b/src/Sema.zig index 6d0dc807bf..e09d82dc14 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -317,6 +317,9 @@ pub fn analyzeBody( .memcpy => try sema.zirMemcpy(block, inst), .memset => try sema.zirMemset(block, inst), .builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst), + .@"resume" => try sema.zirResume(block, inst), + .@"await" => try sema.zirAwait(block, inst, false), + .await_nosuspend => try sema.zirAwait(block, inst, true), .extended => try sema.zirExtended(block, inst), .sqrt => try sema.zirUnaryMath(block, inst), @@ -5413,6 +5416,23 @@ fn zirBuiltinAsyncCall(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) I return sema.mod.fail(&block.base, src, "TODO: Sema.zirBuiltinAsyncCall", .{}); } +fn zirResume(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { + const inst_data = sema.code.instructions.items(.data)[inst].un_node; + const src = inst_data.src(); + return sema.mod.fail(&block.base, src, "TODO: Sema.zirResume", .{}); +} + +fn zirAwait( + sema: *Sema, + block: *Scope.Block, + inst: Zir.Inst.Index, + is_nosuspend: bool, +) InnerError!*Inst { + const inst_data = sema.code.instructions.items(.data)[inst].un_node; + const src = inst_data.src(); + return sema.mod.fail(&block.base, src, "TODO: Sema.zirAwait", .{}); +} + fn zirFuncExtended( sema: *Sema, block: *Scope.Block, diff --git a/src/Zir.zig b/src/Zir.zig index 746c101e23..b058284b79 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -936,6 +936,10 @@ pub const Inst = struct { /// Uses the `un_node` field. The AST node is the var decl. resolve_inferred_alloc, + @"resume", + @"await", + await_nosuspend, + /// The ZIR instruction tag is one of the `Extended` ones. /// Uses the `extended` union field. extended, @@ -1185,6 +1189,9 @@ pub const Inst = struct { .memset, .builtin_async_call, .c_import, + .@"resume", + .@"await", + .await_nosuspend, .extended, => false, @@ -2416,6 +2423,9 @@ const Writer = struct { .byte_swap, .bit_reverse, .elem_type, + .@"resume", + .@"await", + .await_nosuspend, => try self.writeUnNode(stream, inst), .ref,