diff --git a/vlib/v/gen/array.v b/vlib/v/gen/array.v index f967c3eca0..e3a4da3759 100644 --- a/vlib/v/gen/array.v +++ b/vlib/v/gen/array.v @@ -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 diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index e5a1fa12f3..6855311f1f 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -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 { diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index ac4a14953e..05a8312f5b 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -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) diff --git a/vlib/v/tests/array_map_ref_test.v b/vlib/v/tests/array_map_ref_test.v new file mode 100644 index 0000000000..19e2c4a527 --- /dev/null +++ b/vlib/v/tests/array_map_ref_test.v @@ -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 + } +}