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
|
||||
}
|
||||
|
||||
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 {
|
||||
cap_ := if cap < mylen { mylen } else { cap }
|
||||
mut arr := array{
|
||||
|
@ -42,6 +42,22 @@ fn __new_array_with_default_noscan(mylen int, cap int, elm_size int, val voidptr
|
||||
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 {
|
||||
cap_ := if cap < mylen { mylen } else { cap }
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
return __new_array_with_array_default(mylen, cap, elm_size, val, depth)
|
||||
}
|
||||
|
@ -1607,3 +1607,27 @@ fn test_using_array_name_variable() {
|
||||
println(array)
|
||||
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}`
|
||||
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)
|
||||
noscan := g.check_noscan(elem_type.typ)
|
||||
is_default_array := elem_type.unaliased_sym.kind == .array && 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
|
||||
g.inside_lambda = true
|
||||
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}(')
|
||||
} else if is_default_map {
|
||||
g.write('__new_array_with_map_default${noscan}(')
|
||||
} else if needs_more_defaults {
|
||||
g.write('__new_array_with_multi_default${noscan}(')
|
||||
} else {
|
||||
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.expr(node.default_expr)
|
||||
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 {
|
||||
g.write('&(${elem_styp}[]){')
|
||||
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',
|
||||
'format_sb',
|
||||
'__new_array_with_default',
|
||||
'__new_array_with_multi_default',
|
||||
'__new_array_with_array_default',
|
||||
'init_global_allocator' /* needed for linux_bare and wasm_bare */,
|
||||
'v_realloc' /* needed for _STR */,
|
||||
|
Loading…
Reference in New Issue
Block a user