diff options
| author | Vexu <git@vexu.eu> | 2020-03-09 12:31:36 +0200 |
|---|---|---|
| committer | Vexu <git@vexu.eu> | 2020-03-09 12:33:24 +0200 |
| commit | 3618256c97a9988f7d623eeabb667010ca30656f (patch) | |
| tree | 0e6e0d8f3fc958809ffe9ea007416738d136c032 /src/ir.cpp | |
| parent | 6f8d732599461aa816f545b658a068eceb6ac9bc (diff) | |
| download | zig-3618256c97a9988f7d623eeabb667010ca30656f.tar.gz zig-3618256c97a9988f7d623eeabb667010ca30656f.zip | |
implement noasync scopes
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 110778fb9a..6a387e12e0 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4978,6 +4978,7 @@ static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_ case ScopeIdLoop: case ScopeIdSuspend: case ScopeIdCompTime: + case ScopeIdNoAsync: case ScopeIdRuntime: case ScopeIdTypeOf: case ScopeIdExpr: @@ -5033,6 +5034,7 @@ static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope case ScopeIdLoop: case ScopeIdSuspend: case ScopeIdCompTime: + case ScopeIdNoAsync: case ScopeIdRuntime: case ScopeIdTypeOf: case ScopeIdExpr: @@ -7307,6 +7309,31 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod zig_unreachable(); } +static bool is_noasync_scope(Scope *scope) { + for (;;) { + switch (scope->id) { + case ScopeIdNoAsync: + return true; + case ScopeIdDefer: + case ScopeIdDeferExpr: + case ScopeIdDecls: + case ScopeIdFnDef: + case ScopeIdCompTime: + case ScopeIdVarDecl: + case ScopeIdCImport: + case ScopeIdSuspend: + return false; + case ScopeIdExpr: + case ScopeIdTypeOf: + case ScopeIdBlock: + case ScopeIdLoop: + case ScopeIdRuntime: + scope = scope->parent; + continue; + } + } +} + static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { @@ -7315,8 +7342,19 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, if (node->data.fn_call_expr.modifier == CallModifierBuiltin) return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); + bool is_noasync = is_noasync_scope(scope); + CallModifier modifier = node->data.fn_call_expr.modifier; + if (is_noasync) { + if (modifier == CallModifierAsync) { + add_node_error(irb->codegen, node, + buf_sprintf("async call in noasync scope")); + return irb->codegen->invalid_inst_src; + } + modifier = CallModifierNoAsync; + } + AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; - return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, node->data.fn_call_expr.modifier, + return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, modifier, nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc); } @@ -9170,6 +9208,14 @@ static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNod return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); } +static IrInstSrc *ir_gen_noasync(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) { + assert(node->type == NodeTypeNoAsync); + + Scope *child_scope = create_noasync_scope(irb->codegen, node, parent_scope); + // purposefully pass null for result_loc and let EndExpr handle it + return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); +} + static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, break_scope)) { @@ -9763,7 +9809,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no { assert(node->type == NodeTypeAwaitExpr); - bool is_noasync = node->data.await_expr.noasync_token != nullptr; + bool is_noasync = is_noasync_scope(scope); AstNode *expr_node = node->data.await_expr.expr; if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) { @@ -9938,6 +9984,8 @@ static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope return ir_gen_switch_expr(irb, scope, node, lval, result_loc); case NodeTypeCompTime: return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); + case NodeTypeNoAsync: + return ir_expr_wrap(irb, scope, ir_gen_noasync(irb, scope, node, lval), result_loc); case NodeTypeErrorType: return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); case NodeTypeBreak: |
