authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-09 15:51:51+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-09 15:51:51+02:00
log03c1431f9c0b651f3f1853f11112edc07555883d
tree4d87acafcb8b97bf99292559894205bdced12dc1
parent3618256c97a9988f7d623eeabb667010ca30656f
signaturelock-open Commit is signed but in an unrecognized format.

disallow resume and suspend in noasync scopes


4 files changed, 43 insertions(+), 27 deletions(-)

lib/std/zig/ast.zig-1
......@@ -1081,7 +1081,6 @@ pub const Node = struct {
10811081
10821082 pub const Noasync = struct {
10831083 base: Node = Node{ .id = .Noasync },
1084 doc_comments: ?*DocComment,
10851084 noasync_token: TokenIndex,
10861085 expr: *Node,
10871086
lib/std/zig/parse.zig+14-2
......@@ -462,6 +462,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
462462/// Statement
463463/// <- KEYWORD_comptime? VarDecl
464464/// / KEYWORD_comptime BlockExprStatement
465/// / KEYWORD_noasync BlockExprStatement
465466/// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
466467/// / KEYWORD_defer BlockExprStatement
467468/// / KEYWORD_errdefer BlockExprStatement
......@@ -493,6 +494,19 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
493494 return &node.base;
494495 }
495496
497 if (eatToken(it, .Keyword_noasync)) |noasync_token| {
498 const block_expr = try expectNode(arena, it, tree, parseBlockExprStatement, .{
499 .ExpectedBlockOrAssignment = .{ .token = it.index },
500 });
501
502 const node = try arena.create(Node.Noasync);
503 node.* = .{
504 .noasync_token = noasync_token,
505 .expr = block_expr,
506 };
507 return &node.base;
508 }
509
496510 if (eatToken(it, .Keyword_suspend)) |suspend_token| {
497511 const semicolon = eatToken(it, .Semicolon);
498512
......@@ -898,7 +912,6 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
898912 });
899913 const node = try arena.create(Node.Noasync);
900914 node.* = .{
901 .doc_comments = null,
902915 .noasync_token = token,
903916 .expr = expr_node,
904917 };
......@@ -1280,7 +1293,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
12801293 const expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
12811294 const node = try arena.create(Node.Noasync);
12821295 node.* = .{
1283 .doc_comments = null,
12841296 .noasync_token = token,
12851297 .expr = expr,
12861298 };
src/ir.cpp+20-24
......@@ -7309,29 +7309,16 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
73097309 zig_unreachable();
73107310}
73117311
7312static bool is_noasync_scope(Scope *scope) {
7313 for (;;) {
7314 switch (scope->id) {
7315 case ScopeIdNoAsync:
7316 return true;
7317 case ScopeIdDefer:
7318 case ScopeIdDeferExpr:
7319 case ScopeIdDecls:
7320 case ScopeIdFnDef:
7321 case ScopeIdCompTime:
7322 case ScopeIdVarDecl:
7323 case ScopeIdCImport:
7324 case ScopeIdSuspend:
7325 return false;
7326 case ScopeIdExpr:
7327 case ScopeIdTypeOf:
7328 case ScopeIdBlock:
7329 case ScopeIdLoop:
7330 case ScopeIdRuntime:
7331 scope = scope->parent;
7332 continue;
7333 }
7312static ScopeNoAsync *get_scope_noasync(Scope *scope) {
7313 while (scope) {
7314 if (scope->id == ScopeIdNoAsync)
7315 return (ScopeNoAsync *)scope;
7316 if (scope->id == ScopeIdFnDef)
7317 return nullptr;
7318
7319 scope = scope->parent;
73347320 }
7321 return nullptr;
73357322}
73367323
73377324static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
......@@ -7342,7 +7329,7 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node,
73427329 if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
73437330 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
73447331
7345 bool is_noasync = is_noasync_scope(scope);
7332 bool is_noasync = get_scope_noasync(scope) != nullptr;
73467333 CallModifier modifier = node->data.fn_call_expr.modifier;
73477334 if (is_noasync) {
73487335 if (modifier == CallModifierAsync) {
......@@ -9796,6 +9783,10 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod
97969783
97979784static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
97989785 assert(node->type == NodeTypeResume);
9786 if (get_scope_noasync(scope) != nullptr) {
9787 add_node_error(irb->codegen, node, buf_sprintf("resume in noasync scope"));
9788 return irb->codegen->invalid_inst_src;
9789 }
97999790
98009791 IrInstSrc *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr);
98019792 if (target_inst == irb->codegen->invalid_inst_src)
......@@ -9809,7 +9800,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
98099800{
98109801 assert(node->type == NodeTypeAwaitExpr);
98119802
9812 bool is_noasync = is_noasync_scope(scope);
9803 bool is_noasync = get_scope_noasync(scope) != nullptr;
98139804
98149805 AstNode *expr_node = node->data.await_expr.expr;
98159806 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
......@@ -9855,6 +9846,11 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode
98559846 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));
98569847 return irb->codegen->invalid_inst_src;
98579848 }
9849 if (get_scope_noasync(parent_scope) != nullptr) {
9850 add_node_error(irb->codegen, node, buf_sprintf("suspend in noasync scope"));
9851 return irb->codegen->invalid_inst_src;
9852 }
9853
98589854 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope);
98599855 if (existing_suspend_scope) {
98609856 if (!existing_suspend_scope->reported_err) {
src/parser.cpp+9
......@@ -876,6 +876,7 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
876876// Statement
877877// <- KEYWORD_comptime? VarDecl
878878// / KEYWORD_comptime BlockExprStatement
879// / KEYWORD_noasync BlockExprStatement
879880// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
880881// / KEYWORD_defer BlockExprStatement
881882// / KEYWORD_errdefer BlockExprStatement
......@@ -899,6 +900,14 @@ static AstNode *ast_parse_statement(ParseContext *pc) {
899900 return res;
900901 }
901902
903 Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
904 if (noasync != nullptr) {
905 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
906 AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
907 res->data.noasync_expr.expr = statement;
908 return res;
909 }
910
902911 Token *suspend = eat_token_if(pc, TokenIdKeywordSuspend);
903912 if (suspend != nullptr) {
904913 AstNode *statement = nullptr;