From f013e6567071f575d5ebea5101410c99a6227d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kr=C3=BCger?= <45282134+UweKrueger@users.noreply.github.com> Date: Wed, 3 Feb 2021 23:56:58 +0100 Subject: [PATCH] checker/cgen: support lock expressions `x := rlock s { s.get() }` (#8540) --- vlib/v/checker/checker.v | 15 +++++++++++++-- vlib/v/gen/c/cgen.v | 16 ++++++++++++++-- vlib/v/tests/shared_lock_expr_test.v | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/shared_lock_expr_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 197ff7a336..f6ce7d1fe4 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4589,8 +4589,19 @@ pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) table.Type { c.stmts(node.stmts) c.rlocked_names = [] c.locked_names = [] - // void for now... maybe sometime `x := lock a { a.getval() }` - return table.void_type + // handle `x := rlock a { a.getval() }` + mut ret_type := table.void_type + if node.stmts.len > 0 { + last_stmt := node.stmts[node.stmts.len - 1] + if last_stmt is ast.ExprStmt { + ret_type = last_stmt.typ + } + } + if ret_type != table.void_type { + node.is_expr = true + } + node.typ = ret_type + return ret_type } pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) table.Type { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 4616619c86..f61ae071c8 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -876,7 +876,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) { // Handle if expressions, set the value of the last expression to the temp var. g.stmt_path_pos << g.out.len g.skip_stmt_pos = true - g.writeln('$tmp_var = /* if expr set */') + g.write('$tmp_var = ') } g.stmt(stmt) g.skip_stmt_pos = false @@ -3407,6 +3407,13 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { } fn (mut g Gen) lock_expr(node ast.LockExpr) { + tmp_result := if node.is_expr { g.new_tmp_var() } else { '' } + mut cur_line := '' + if node.is_expr { + styp := g.typ(node.typ) + cur_line = g.go_before_stmt(0) + g.writeln('$styp $tmp_result;') + } mut mtxs := '' if node.lockeds.len == 0 { // this should not happen @@ -3449,7 +3456,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) { g.writeln('}') } g.writeln('/*lock*/ {') - g.stmts(node.stmts) + g.stmts_with_tmp_var(node.stmts, tmp_result) g.writeln('}') if node.lockeds.len == 0 { // this should not happen @@ -3469,6 +3476,11 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) { g.writeln('\t\tsync__RwMutex_unlock((sync__RwMutex*)_arr_$mtxs[$mtxs]);') g.write('}') } + if node.is_expr { + g.writeln('') + g.write(cur_line) + g.write('$tmp_result') + } } fn (mut g Gen) match_expr(node ast.MatchExpr) { diff --git a/vlib/v/tests/shared_lock_expr_test.v b/vlib/v/tests/shared_lock_expr_test.v new file mode 100644 index 0000000000..fa488d3551 --- /dev/null +++ b/vlib/v/tests/shared_lock_expr_test.v @@ -0,0 +1,14 @@ +struct St { +mut: + i int +} + +fn test_lock_expr() { + shared xx := St{ i: 173 } + shared y := St{ i: -57 } + mut m := 0 + m = lock y { y.i } + n := rlock xx { xx.i } + assert m == -57 + assert n == 173 +}