checker/cgen: support lock expressions `x := rlock s { s.get() }` (#8540)

pull/8542/head
Uwe Krüger 2021-02-03 23:56:58 +01:00 committed by GitHub
parent cee00a3551
commit f013e65670
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 4 deletions

View File

@ -4589,8 +4589,19 @@ pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) table.Type {
c.stmts(node.stmts) c.stmts(node.stmts)
c.rlocked_names = [] c.rlocked_names = []
c.locked_names = [] c.locked_names = []
// void for now... maybe sometime `x := lock a { a.getval() }` // handle `x := rlock a { a.getval() }`
return table.void_type 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 { pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) table.Type {

View File

@ -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. // Handle if expressions, set the value of the last expression to the temp var.
g.stmt_path_pos << g.out.len g.stmt_path_pos << g.out.len
g.skip_stmt_pos = true g.skip_stmt_pos = true
g.writeln('$tmp_var = /* if expr set */') g.write('$tmp_var = ')
} }
g.stmt(stmt) g.stmt(stmt)
g.skip_stmt_pos = false 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) { 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 := '' mut mtxs := ''
if node.lockeds.len == 0 { if node.lockeds.len == 0 {
// this should not happen // this should not happen
@ -3449,7 +3456,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
g.writeln('}') g.writeln('}')
} }
g.writeln('/*lock*/ {') g.writeln('/*lock*/ {')
g.stmts(node.stmts) g.stmts_with_tmp_var(node.stmts, tmp_result)
g.writeln('}') g.writeln('}')
if node.lockeds.len == 0 { if node.lockeds.len == 0 {
// this should not happen // 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.writeln('\t\tsync__RwMutex_unlock((sync__RwMutex*)_arr_$mtxs[$mtxs]);')
g.write('}') 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) { fn (mut g Gen) match_expr(node ast.MatchExpr) {

View File

@ -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
}