cgen: put `shared` arrays and maps always on heap (#8496)

pull/8499/head
Uwe Krüger 2021-02-01 20:07:01 +01:00 committed by GitHub
parent 4d268d1436
commit 17746561f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 44 deletions

View File

@ -2522,11 +2522,13 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
}
mut ident_var_info := left.info as ast.IdentVar
if ident_var_info.share == .shared_t {
if left_type.nr_muls() > 1 {
c.error('shared cannot be multi level reference', left.pos)
}
left_type = left_type.set_flag(.shared_f)
left_type = left_type.set_nr_muls(1)
if is_decl {
if left_type.nr_muls() > 1 {
c.error('shared cannot be multi level reference', left.pos)
}
left_type = left_type.set_nr_muls(1)
}
}
if ident_var_info.share == .atomic_t {
left_type = left_type.set_flag(.atomic_f)

View File

@ -14,17 +14,13 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
g.is_amp = false
if is_amp {
g.out.go_back(1) // delete the `&` already generated in `prefix_expr()
if g.is_shared {
mut shared_typ := node.typ.set_flag(.shared_f)
shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.val = ')
} else {
g.write('($styp*)memdup(ADDR($styp, ')
}
} else {
if g.is_shared {
g.writeln('{.val = ($styp*)')
}
}
if g.is_shared {
mut shared_typ := node.typ.set_flag(.shared_f)
shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.val = ')
} else if is_amp {
g.write('($styp*)memdup(ADDR($styp, ')
}
if type_sym.kind == .array_fixed {
g.write('{')
@ -93,12 +89,10 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
} else {
g.write('0)')
}
if is_amp {
if g.is_shared {
g.write('}, sizeof($shared_styp))')
} else {
g.write('), sizeof($styp))')
}
if g.is_shared {
g.write('}, sizeof($shared_styp))')
} else if is_amp {
g.write('), sizeof($styp))')
}
return
}
@ -121,12 +115,9 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
}
g.write('}))')
if g.is_shared {
g.write(', .mtx = sync__new_rwmutex()}')
if is_amp {
g.write(', sizeof($shared_styp))')
}
g.write('}, sizeof($shared_styp))')
} else if is_amp {
g.write(', sizeof($styp))')
g.write('), sizeof($styp))')
}
}

View File

@ -2692,19 +2692,14 @@ fn (mut g Gen) expr(node ast.Expr) {
g.is_amp = false
if is_amp {
g.out.go_back(1) // delete the `&` already generated in `prefix_expr()
if g.is_shared {
mut shared_typ := node.typ.set_flag(.shared_f)
shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.val = ')
} else {
styp = g.typ(node.typ)
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*)')
}
}
if g.is_shared {
mut shared_typ := node.typ.set_flag(.shared_f)
shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.val = ')
} else if is_amp {
styp = g.typ(node.typ)
g.write('($styp*)memdup(ADDR($styp, ')
}
if size > 0 {
if value_typ.kind == .function {
@ -2730,10 +2725,7 @@ fn (mut g Gen) expr(node ast.Expr) {
g.write('new_map_2(sizeof($key_typ_str), sizeof($value_typ_str), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)')
}
if g.is_shared {
g.write('}')
if is_amp {
g.write(', sizeof($shared_styp))')
}
g.write('}, sizeof($shared_styp))')
} else if is_amp {
g.write('), sizeof($styp))')
}

View File

@ -40,3 +40,26 @@ fn test_shared_array() {
assert f1 == 350020
}
}
fn test_shared_init_syntax() {
shared foo := &[3, 5, 6, -12]
shared bar := [-12.5, 23.125, 6.0625, 12.5]
shared baz := &[]int{len: 5, cap: 12}
shared qux := []f64{len: 7}
lock foo {
foo[2] = 20
}
lock bar {
bar[3] = 12.5
}
lock baz, qux {
baz[3] = 12
qux[6] = -17.0625
}
rlock foo, bar, baz, qux {
assert foo[2] == 20
assert bar[3] == 12.5
assert baz[3] == 12
assert qux[6] == -17.0625
}
}

View File

@ -10,7 +10,7 @@ fn incr(shared foo map[string]int, key string, mut sem sync.Semaphore) {
}
fn test_shared_array() {
shared foo := &{'p': 10, 'q': 0}
shared foo := {'p': 10, 'q': 0}
lock foo {
foo['q'] = 20
}
@ -35,3 +35,26 @@ fn test_shared_array() {
assert fq == 350020
}
}
fn test_shared_init_syntax() {
shared foo := &{'p': 17, 'q': -3, 'qwertz': 10}
shared bar := {'wer': 13.75, 'cvbn': -7.25, 'asd': -0.0625}
shared baz := &map[string]int{}
shared qux := map[string]f64{}
lock foo {
foo['q'] = 20
}
lock bar {
bar['asd'] = 12.5
}
lock baz, qux {
baz['wer'] = 12
qux['abc'] = -17.0625
}
rlock foo, bar, baz, qux {
assert foo['q'] == 20
assert bar['asd'] == 12.5
assert baz['wer'] == 12
assert qux['abc'] == -17.0625
}
}