parser/cgen: fix explicit array/map shared/reference initializers (#8307)

pull/8265/head
Uwe Krüger 2021-01-23 22:54:57 +01:00 committed by GitHub
parent 35432c5e92
commit 1ea5cedd03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 4 deletions

View File

@ -19,7 +19,7 @@ fn (mut g Gen) array_init(it ast.ArrayInit) {
shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)memdup(&($shared_styp){.val = ')
} else {
g.write('($styp*)memdup(&') // TODO: doesn't work with every compiler
g.write('($styp*)memdup(ADDR($styp, ')
}
} else {
if g.is_shared {
@ -93,6 +93,13 @@ fn (mut g Gen) array_init(it ast.ArrayInit) {
} else {
g.write('0)')
}
if is_amp {
if g.is_shared {
g.write(', .mtx = sync__new_rwmutex()}, sizeof($shared_styp))')
} else {
g.write('), sizeof($styp))')
}
}
return
}
len := it.exprs.len

View File

@ -2720,10 +2720,11 @@ fn (mut g Gen) expr(node ast.Expr) {
g.writeln('($shared_styp*)memdup(&($shared_styp){.val = ')
} else {
styp = g.typ(node.typ)
g.write('($styp*)memdup(&') // TODO: doesn't work with every compiler
g.write('($styp*)memdup(ADDR($styp, ')
}
} else {
if g.is_shared {
// TODO: shared objects on stack should be forbidden or auto-converted to heap
g.writeln('{.val = ($styp*)')
}
}
@ -2756,7 +2757,7 @@ fn (mut g Gen) expr(node ast.Expr) {
g.write(', sizeof($shared_styp))')
}
} else if is_amp {
g.write(', sizeof($styp))')
g.write('), sizeof($styp))')
}
}
ast.None {

View File

@ -133,7 +133,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
if p.expecting_type {
// parse json.decode type (`json.decode([]User, s)`)
node = p.name_expr()
} else if p.is_amp && p.peek_tok.kind == .rsbr {
} else if p.is_amp && p.peek_tok.kind == .rsbr && p.peek_tok3.kind != .lcbr {
pos := p.tok.position()
typ := p.parse_type().to_ptr()
p.check(.lpar)

View File

@ -0,0 +1,56 @@
fn mod_map(shared m map[string]f64) {
lock m {
m['y'] = 6.5
m['op'] = -13.0625
}
}
fn mod_array(shared a []f64) {
lock a {
a[5] = -13.5
a[7] = 167.125
}
}
fn test_array_map_ref() {
// test initialization
mut m := map[string]int{}
mut m_ref := &map[string]f64{}
mut a := []int{len: 10}
mut a_ref := &[]f64{cap: 12, len: 2}
shared m_shared := &map[string]f64{}
shared a_shared := &[]f64{cap: 12, len: 9}
// test usage
m['a'] = 3
unsafe {
m_ref['b'] = 12.25
}
a << 67
a << 45
assert a.len == 12
a_ref << 73
a_ref << 12
a_ref << 8
unsafe {
a_ref[1] = 17
}
assert a_ref.len == 5
t1 := go mod_map(shared m_shared)
t2 := go mod_array(shared a_shared)
lock m_shared, a_shared {
a_shared[4] = -12.25
m_shared['tz'] = 73.75
}
t1.wait()
t2.wait()
rlock m_shared {
assert m_shared['y'] == 6.5
assert m_shared['op'] == -13.0625
assert m_shared['tz'] == 73.75
}
rlock a_shared {
assert a_shared[4] == -12.25
assert a_shared[5] == -13.5
assert a_shared[7] == 167.125
}
}