mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
8011121d43
commit
93a3f5ff7d
|
@ -78,6 +78,33 @@ fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn __new_array_with_multi_default(mylen int, cap int, elm_size int, val voidptr) array {
|
||||||
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
|
mut arr := array{
|
||||||
|
element_size: elm_size
|
||||||
|
len: mylen
|
||||||
|
cap: cap_
|
||||||
|
}
|
||||||
|
// x := []EmptyStruct{cap:5} ; for clang/gcc with -gc none,
|
||||||
|
// -> sizeof(EmptyStruct) == 0 -> elm_size == 0
|
||||||
|
// -> total_size == 0 -> malloc(0) -> panic;
|
||||||
|
// to avoid it, just allocate a single byte
|
||||||
|
total_size := u64(cap_) * u64(elm_size)
|
||||||
|
arr.data = vcalloc(__at_least_one(total_size))
|
||||||
|
if val != 0 {
|
||||||
|
mut eptr := &u8(arr.data)
|
||||||
|
unsafe {
|
||||||
|
if eptr != nil {
|
||||||
|
for i in 0 .. arr.len {
|
||||||
|
vmemcpy(eptr, charptr(val) + i * arr.element_size, arr.element_size)
|
||||||
|
eptr += arr.element_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array, depth int) array {
|
fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array, depth int) array {
|
||||||
cap_ := if cap < mylen { mylen } else { cap }
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
mut arr := array{
|
mut arr := array{
|
||||||
|
|
|
@ -42,6 +42,22 @@ fn __new_array_with_default_noscan(mylen int, cap int, elm_size int, val voidptr
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn __new_array_with_multi_default_noscan(mylen int, cap int, elm_size int, val voidptr) array {
|
||||||
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
|
mut arr := array{
|
||||||
|
element_size: elm_size
|
||||||
|
data: vcalloc_noscan(u64(cap_) * u64(elm_size))
|
||||||
|
len: mylen
|
||||||
|
cap: cap_
|
||||||
|
}
|
||||||
|
if val != 0 && arr.data != unsafe { nil } {
|
||||||
|
for i in 0 .. arr.len {
|
||||||
|
unsafe { arr.set_unsafe(i, charptr(val) + i * elm_size) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
fn __new_array_with_array_default_noscan(mylen int, cap int, elm_size int, val array) array {
|
fn __new_array_with_array_default_noscan(mylen int, cap int, elm_size int, val array) array {
|
||||||
cap_ := if cap < mylen { mylen } else { cap }
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
mut arr := array{
|
mut arr := array{
|
||||||
|
|
|
@ -13,6 +13,10 @@ fn __new_array_with_default_noscan(mylen int, cap int, elm_size int, val voidptr
|
||||||
return __new_array_with_default(mylen, cap, elm_size, val)
|
return __new_array_with_default(mylen, cap, elm_size, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn __new_array_with_multi_default_noscan(mylen int, cap int, elm_size int, val voidptr) array {
|
||||||
|
return __new_array_with_multi_default(mylen, cap, elm_size, val)
|
||||||
|
}
|
||||||
|
|
||||||
fn __new_array_with_array_default_noscan(mylen int, cap int, elm_size int, val array, depth int) array {
|
fn __new_array_with_array_default_noscan(mylen int, cap int, elm_size int, val array, depth int) array {
|
||||||
return __new_array_with_array_default(mylen, cap, elm_size, val, depth)
|
return __new_array_with_array_default(mylen, cap, elm_size, val, depth)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1607,3 +1607,27 @@ fn test_using_array_name_variable() {
|
||||||
println(array)
|
println(array)
|
||||||
assert array == [0, 1, 2, 3]
|
assert array == [0, 1, 2, 3]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
mut:
|
||||||
|
sub_map map[int]int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_array_of_struct_with_map_field() {
|
||||||
|
n := 3
|
||||||
|
mut arr := []Data{len: n}
|
||||||
|
for i, mut a in arr {
|
||||||
|
arr[i].sub_map[i] = 1
|
||||||
|
a.sub_map[i] += 1
|
||||||
|
}
|
||||||
|
println(arr)
|
||||||
|
assert arr[0].sub_map == {
|
||||||
|
0: 2
|
||||||
|
}
|
||||||
|
assert arr[1].sub_map == {
|
||||||
|
1: 2
|
||||||
|
}
|
||||||
|
assert arr[2].sub_map == {
|
||||||
|
2: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -175,12 +175,27 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) struct_has_array_or_map_field(elem_typ ast.Type) bool {
|
||||||
|
unaliased_sym := g.table.final_sym(elem_typ)
|
||||||
|
if unaliased_sym.kind == .struct_ {
|
||||||
|
info := unaliased_sym.info as ast.Struct
|
||||||
|
for field in info.fields {
|
||||||
|
field_sym := g.table.final_sym(field.typ)
|
||||||
|
if field_sym.kind in [.array, .map] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// `[]int{len: 6, cap: 10, init: it * it}`
|
// `[]int{len: 6, cap: 10, init: it * it}`
|
||||||
fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp bool, shared_styp string, var_name string) {
|
fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp bool, shared_styp string, var_name string) {
|
||||||
elem_styp := g.typ(elem_type.typ)
|
elem_styp := g.typ(elem_type.typ)
|
||||||
noscan := g.check_noscan(elem_type.typ)
|
noscan := g.check_noscan(elem_type.typ)
|
||||||
is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default
|
is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default
|
||||||
is_default_map := elem_type.unaliased_sym.kind == .map && node.has_default
|
is_default_map := elem_type.unaliased_sym.kind == .map && node.has_default
|
||||||
|
needs_more_defaults := node.has_len && g.struct_has_array_or_map_field(elem_type.typ)
|
||||||
if node.has_it { // []int{len: 6, init: it * it} when variable it is used in init expression
|
if node.has_it { // []int{len: 6, init: it * it} when variable it is used in init expression
|
||||||
g.inside_lambda = true
|
g.inside_lambda = true
|
||||||
mut tmp := g.new_tmp_var()
|
mut tmp := g.new_tmp_var()
|
||||||
|
@ -278,6 +293,8 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
|
||||||
g.write('__new_array_with_array_default${noscan}(')
|
g.write('__new_array_with_array_default${noscan}(')
|
||||||
} else if is_default_map {
|
} else if is_default_map {
|
||||||
g.write('__new_array_with_map_default${noscan}(')
|
g.write('__new_array_with_map_default${noscan}(')
|
||||||
|
} else if needs_more_defaults {
|
||||||
|
g.write('__new_array_with_multi_default${noscan}(')
|
||||||
} else {
|
} else {
|
||||||
g.write('__new_array_with_default${noscan}(')
|
g.write('__new_array_with_default${noscan}(')
|
||||||
}
|
}
|
||||||
|
@ -312,6 +329,27 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
|
||||||
g.write('(${elem_styp}[]){')
|
g.write('(${elem_styp}[]){')
|
||||||
g.expr(node.default_expr)
|
g.expr(node.default_expr)
|
||||||
g.write('}[0])')
|
g.write('}[0])')
|
||||||
|
} else if needs_more_defaults {
|
||||||
|
tmp := g.new_tmp_var()
|
||||||
|
line := g.go_before_stmt(0).trim_space()
|
||||||
|
g.empty_line = true
|
||||||
|
g.write('${elem_styp}* ${tmp} = malloc((')
|
||||||
|
g.expr(node.len_expr)
|
||||||
|
g.writeln(') * sizeof(${elem_styp}));')
|
||||||
|
ind := g.new_tmp_var()
|
||||||
|
g.write('for (int ${ind}=0; ${ind}<')
|
||||||
|
g.expr(node.len_expr)
|
||||||
|
g.writeln('; ${ind}++) {')
|
||||||
|
g.write('\t${tmp}[${ind}] = ')
|
||||||
|
if node.has_default {
|
||||||
|
g.expr_with_cast(node.default_expr, node.default_type, node.elem_type)
|
||||||
|
} else {
|
||||||
|
g.write(g.type_default(node.elem_type))
|
||||||
|
}
|
||||||
|
g.writeln(';')
|
||||||
|
g.writeln('}')
|
||||||
|
g.write(line)
|
||||||
|
g.write(' (voidptr)${tmp})')
|
||||||
} else if node.has_default {
|
} else if node.has_default {
|
||||||
g.write('&(${elem_styp}[]){')
|
g.write('&(${elem_styp}[]){')
|
||||||
g.expr_with_cast(node.default_expr, node.default_type, node.elem_type)
|
g.expr_with_cast(node.default_expr, node.default_type, node.elem_type)
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub fn mark_used(mut table ast.Table, pref_ &pref.Preferences, ast_files []&ast.
|
||||||
'str_intp',
|
'str_intp',
|
||||||
'format_sb',
|
'format_sb',
|
||||||
'__new_array_with_default',
|
'__new_array_with_default',
|
||||||
|
'__new_array_with_multi_default',
|
||||||
'__new_array_with_array_default',
|
'__new_array_with_array_default',
|
||||||
'init_global_allocator' /* needed for linux_bare and wasm_bare */,
|
'init_global_allocator' /* needed for linux_bare and wasm_bare */,
|
||||||
'v_realloc' /* needed for _STR */,
|
'v_realloc' /* needed for _STR */,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user