From 0d7cc8829a00315f4cec087bd83df956371a188c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kr=C3=BCger?= <45282134+UweKrueger@users.noreply.github.com> Date: Mon, 17 Aug 2020 23:35:36 +0200 Subject: [PATCH] cgen: implement channel `push()`/`pop()` using `<-` operator (#6154) --- vlib/sync/channel_select_2_test.v | 22 ++++++++-------- vlib/v/ast/ast.v | 8 +++--- vlib/v/checker/checker.v | 1 + vlib/v/gen/cgen.v | 42 ++++++++++++++++++++++++++----- 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/vlib/sync/channel_select_2_test.v b/vlib/sync/channel_select_2_test.v index abea5f081f..1a4f3a216a 100644 --- a/vlib/sync/channel_select_2_test.v +++ b/vlib/sync/channel_select_2_test.v @@ -1,45 +1,42 @@ import sync +import time fn do_rec_i64(ch chan i64) { mut sum := i64(0) for _ in 0 .. 300 { - mut a := i64(0) - (&sync.Channel(ch)).pop(&a) - sum += a + sum += <-ch } assert sum == 300 * (300 - 1) / 2 } fn do_send_int(ch chan int) { for i in 0 .. 300 { - (&sync.Channel(ch)).push(&i) + ch <- i } } fn do_send_byte(ch chan byte) { for i in 0 .. 300 { - ii := byte(i) - (&sync.Channel(ch)).push(&ii) + ch <- byte(i) } } -fn do_send_i64(mut ch sync.Channel) { +fn do_send_i64(ch chan i64) { for i in 0 .. 300 { - ii := i64(i) - ch.push(&ii) + ch <- i } } fn test_select() { chi := chan int{} - mut chl := sync.new_channel(1) + chl := chan i64{cap: 1} chb := chan byte{cap: 10} recch := chan i64{cap: 0} go do_rec_i64(recch) go do_send_int(chi) go do_send_byte(chb) - go do_send_i64(mut chl) - mut channels := [&sync.Channel(chi), &sync.Channel(recch), chl, &sync.Channel(chb)] + go do_send_i64(chl) + mut channels := [&sync.Channel(chi), &sync.Channel(recch), &sync.Channel(chl), &sync.Channel(chb)] directions := [sync.Direction.pop, .push, .pop, .pop] mut sum := i64(0) mut rl := i64(0) @@ -73,4 +70,5 @@ fn test_select() { 256 * (256 - 1) / 2 + 44 * (44 - 1) / 2 assert sum == expected_sum + time.sleep_ms(20) // to give assert in coroutine enough time } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 4d4789db3a..5347478aa1 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -435,9 +435,11 @@ pub mut: pub struct PrefixExpr { pub: - op token.Kind - right Expr - pos token.Position + op token.Kind + right Expr + pos token.Position +pub mut: + right_type table.Type } pub struct IndexExpr { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index fbf23c45ab..6469f42945 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2439,6 +2439,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { } ast.PrefixExpr { right_type := c.expr(node.right) + node.right_type = right_type // TODO: testing ref/deref strategy if node.op == .amp && !right_type.is_ptr() { return right_type.to_ptr() diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 26921c3b43..9bf1775987 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -498,8 +498,21 @@ typedef struct { g.type_definitions.writeln('typedef _Interface ${c_name(typ.name)};') } .chan { - styp := util.no_dots(typ.name) - g.type_definitions.writeln('typedef chan $styp;') + if typ.name != 'chan' { + styp := util.no_dots(typ.name) + g.type_definitions.writeln('typedef chan $styp;') + el_stype := g.typ(typ.chan_info().elem_type) + g.hotcode_definitions.writeln(' +static inline $el_stype __${styp}_popval($styp ch) { + $el_stype val; + sync__Channel_try_pop_priv(ch, &val, false); + return val; +}') + g.hotcode_definitions.writeln(' +static inline void __${styp}_pushval($styp ch, $el_stype val) { + sync__Channel_try_push_priv(ch, &val, false); +}') + } } .map { styp := util.no_dots(typ.name) @@ -1969,11 +1982,20 @@ fn (mut g Gen) expr(node ast.Expr) { if node.op == .amp { g.is_amp = true } - // g.write('/*pref*/') - g.write(node.op.str()) - // g.write('(') + if node.op == .arrow { + right_type := g.unwrap_generic(node.right_type) + right_sym := g.table.get_type_symbol(right_type) + styp := util.no_dots(right_sym.name) + g.write('__${styp}_popval(') + } else { + // g.write('/*pref*/') + g.write(node.op.str()) + // g.write('(') + } g.expr(node.right) - // g.write(')') + if node.op == .arrow { + g.write(')') + } g.is_amp = false } ast.RangeExpr { @@ -2326,6 +2348,14 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { } g.write(' }))') } + } else if node.op == .arrow { + // chan <- val + styp := util.no_dots(left_sym.name) + g.write('__${styp}_pushval(') + g.expr(node.left) + g.write(', ') + g.expr(node.right) + g.write(')') } else if unaliased_left.idx() in [table.u32_type_idx, table.u64_type_idx] && unaliased_right.is_signed() && node.op in [.eq, .ne, .gt, .lt, .ge, .le] { bitsize := if unaliased_left.idx() == table.u32_type_idx &&