cgen: optimize array op assign (#7178)
parent
91e18b039c
commit
fd689f5fdd
|
@ -796,6 +796,57 @@ fn test_in_struct() {
|
|||
assert baz.bar[0] == 3
|
||||
}
|
||||
|
||||
[direct_array_access]
|
||||
fn test_direct_modification() {
|
||||
mut foo := [2, 0, 5]
|
||||
foo[1] = 3
|
||||
foo[0] *= 7
|
||||
foo[1]--
|
||||
foo[2] -= 2
|
||||
assert foo[0] == 14
|
||||
assert foo[1] == 2
|
||||
assert foo[2] == 3
|
||||
}
|
||||
|
||||
fn test_shared_modification() {
|
||||
shared foo := &[2, 0, 5]
|
||||
lock foo {
|
||||
unsafe {
|
||||
foo[1] = 3
|
||||
foo[0] *= 7
|
||||
foo[1]--
|
||||
foo[2] -= 2
|
||||
}
|
||||
}
|
||||
rlock foo {
|
||||
unsafe {
|
||||
assert foo[0] == 14
|
||||
assert foo[1] == 2
|
||||
assert foo[2] == 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[direct_array_access]
|
||||
fn test_shared_direct_modification() {
|
||||
shared foo := &[2, 0, 5]
|
||||
lock foo {
|
||||
unsafe {
|
||||
foo[1] = 3
|
||||
foo[0] *= 7
|
||||
foo[1]--
|
||||
foo[2] -= 2
|
||||
}
|
||||
}
|
||||
rlock foo {
|
||||
unsafe {
|
||||
assert foo[0] == 14
|
||||
assert foo[1] == 2
|
||||
assert foo[2] == 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_bools() {
|
||||
println('test b')
|
||||
mut a := [true, false]
|
||||
|
|
|
@ -3666,12 +3666,18 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
|||
is_selector := node.left is ast.SelectorExpr
|
||||
if g.is_assign_lhs && !is_selector && node.is_setter {
|
||||
is_direct_array_access := g.fn_decl != 0 && g.fn_decl.is_direct_arr
|
||||
is_op_assign := g.assign_op != .assign && info.elem_type != table.string_type
|
||||
array_ptr_type_str := match elem_typ.kind {
|
||||
.function { 'voidptr*' }
|
||||
else { '$elem_type_str*' }
|
||||
}
|
||||
if is_direct_array_access {
|
||||
g.write('(($array_ptr_type_str)')
|
||||
} else if is_op_assign {
|
||||
g.write('(*($array_ptr_type_str)array_get(')
|
||||
if left_is_ptr && !node.left_type.has_flag(.shared_f) {
|
||||
g.write('*')
|
||||
}
|
||||
} else {
|
||||
g.is_array_set = true // special handling of assign_op and closing with '})'
|
||||
g.write('array_set(')
|
||||
|
@ -3680,7 +3686,6 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
|||
}
|
||||
}
|
||||
g.expr(node.left)
|
||||
// TODO: test direct_array_access when 'shared' is implemented
|
||||
if node.left_type.has_flag(.shared_f) {
|
||||
if left_is_ptr {
|
||||
g.write('->val')
|
||||
|
@ -3700,59 +3705,30 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
|||
} else {
|
||||
g.write(', ')
|
||||
g.expr(node.index)
|
||||
mut need_wrapper := true
|
||||
/*
|
||||
match node.right {
|
||||
ast.EnumVal, ast.Ident {
|
||||
// `&x` is enough for variables and enums
|
||||
// `&(Foo[]){ ... }` is only needed for function calls and literals
|
||||
need_wrapper = false
|
||||
if !is_op_assign {
|
||||
mut need_wrapper := true
|
||||
/*
|
||||
match node.right {
|
||||
ast.EnumVal, ast.Ident {
|
||||
// `&x` is enough for variables and enums
|
||||
// `&(Foo[]){ ... }` is only needed for function calls and literals
|
||||
need_wrapper = false
|
||||
}
|
||||
else {}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
*/
|
||||
if need_wrapper {
|
||||
if elem_typ.kind == .function {
|
||||
g.write(', &(voidptr[]) { ')
|
||||
*/
|
||||
if need_wrapper {
|
||||
if elem_typ.kind == .function {
|
||||
g.write(', &(voidptr[]) { ')
|
||||
} else {
|
||||
g.write(', &($elem_type_str[]) { ')
|
||||
}
|
||||
} else {
|
||||
g.write(', &($elem_type_str[]) { ')
|
||||
g.write(', &')
|
||||
}
|
||||
} else {
|
||||
g.write(', &')
|
||||
}
|
||||
// `x[0] *= y`
|
||||
if g.assign_op != .assign &&
|
||||
g.assign_op in token.assign_tokens && info.elem_type != table.string_type {
|
||||
// TODO move this
|
||||
g.write('*($elem_type_str*)array_get(')
|
||||
if left_is_ptr && !node.left_type.has_flag(.shared_f) {
|
||||
g.write('*')
|
||||
}
|
||||
g.expr(node.left)
|
||||
if node.left_type.has_flag(.shared_f) {
|
||||
if left_is_ptr {
|
||||
g.write('->val')
|
||||
} else {
|
||||
g.write('.val')
|
||||
}
|
||||
}
|
||||
g.write(', ')
|
||||
g.expr(node.index)
|
||||
g.write(') ')
|
||||
op := match g.assign_op {
|
||||
.mult_assign { '*' }
|
||||
.plus_assign { '+' }
|
||||
.minus_assign { '-' }
|
||||
.div_assign { '/' }
|
||||
.xor_assign { '^' }
|
||||
.mod_assign { '%' }
|
||||
.or_assign { '|' }
|
||||
.and_assign { '&' }
|
||||
.left_shift_assign { '<<' }
|
||||
.right_shift_assign { '>>' }
|
||||
else { '' }
|
||||
}
|
||||
g.write(op)
|
||||
// `x[0] *= y`
|
||||
g.write('))')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue