Skip to content

Commit 8dddf0f

Browse files
Copilotenghitalo
andcommitted
wasm: add support for array initialization with named params
Implemented array initialization with named parameters (len:, cap:, init:): - Updated ArrayInit handling in mem.v to detect has_len, has_cap, has_init flags - Calls __new_array_with_default() when named params are used - Supports syntax like []int{len: 5, cap: 10, init: 42} - Handles init value by creating temporary stack variable - Falls back to regular __new_array() for literal arrays [1, 2, 3] Added test array_named_init.vv demonstrating: - Array with just len parameter - Array with len and cap - Array with len, cap, and init value - String arrays with init All WASM tests pass including the new named parameter tests. Co-authored-by: enghitalo <63821277+enghitalo@users.noreply.github.com>
1 parent 00d6dca commit 8dddf0f

3 files changed

Lines changed: 119 additions & 11 deletions

File tree

vlib/v/gen/wasm/mem.v

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,18 +1087,63 @@ pub fn (mut g Gen) set_with_expr(init ast.Expr, v Var) {
10871087
ast.ArrayInit {
10881088
if !init.is_fixed {
10891089
// Dynamic array initialization
1090-
// Use __new_array() function to create the array struct
1090+
// Use __new_array() or __new_array_with_default() function
10911091
elm_typ := init.elem_type
10921092
elm_size, _ := g.pool.type_size(elm_typ)
10931093

1094-
// Calculate array length
1095-
arr_len := init.exprs.len
1096-
1097-
// Call __new_array(len, cap, element_size) to create array struct
1098-
g.literalint(arr_len, ast.int_type) // len
1099-
g.literalint(arr_len, ast.int_type) // cap (same as len for now)
1100-
g.literalint(elm_size, ast.int_type) // element_size
1101-
g.func.call('builtin____new_array')
1094+
// Check if using named parameters (len:, cap:, init:)
1095+
if init.has_len || init.has_cap || init.has_init {
1096+
// Array init with named params: []int{len: 5, cap: 10, init: 42}
1097+
// Use __new_array_with_default(len, cap, elm_size, default_value_ptr)
1098+
1099+
// Push len (required or 0)
1100+
if init.has_len {
1101+
g.expr(init.len_expr, ast.int_type)
1102+
} else {
1103+
g.literalint(0, ast.int_type)
1104+
}
1105+
1106+
// Push cap (or use len if not specified)
1107+
if init.has_cap {
1108+
g.expr(init.cap_expr, ast.int_type)
1109+
} else if init.has_len {
1110+
g.expr(init.len_expr, ast.int_type)
1111+
} else {
1112+
g.literalint(0, ast.int_type)
1113+
}
1114+
1115+
// Push element_size
1116+
g.literalint(elm_size, ast.int_type)
1117+
1118+
// Push init value pointer (or 0 for no default)
1119+
if init.has_init {
1120+
// Allocate space on stack for init value
1121+
init_var := g.new_local('__init', elm_typ)
1122+
init_var_addr := g.ensure_var_addressable(mut init_var)
1123+
1124+
// Store init value
1125+
g.get(init_var_addr)
1126+
g.expr(init.init_expr, elm_typ)
1127+
g.store(elm_typ, 0)
1128+
1129+
// Push address of init value
1130+
g.get(init_var_addr)
1131+
} else {
1132+
g.literalint(0, ast.int_type)
1133+
}
1134+
1135+
g.func.call('builtin____new_array_with_default')
1136+
} else {
1137+
// Regular array initialization: [1, 2, 3]
1138+
// Calculate array length
1139+
arr_len := init.exprs.len
1140+
1141+
// Call __new_array(len, cap, element_size) to create array struct
1142+
g.literalint(arr_len, ast.int_type) // len
1143+
g.literalint(arr_len, ast.int_type) // cap (same as len for now)
1144+
g.literalint(elm_size, ast.int_type) // element_size
1145+
g.func.call('builtin____new_array')
1146+
}
11021147

11031148
// Store the returned array struct
11041149
array_struct_tmp := g.func.new_local_named(.i32_t, '__tmp<array_struct>')
@@ -1112,8 +1157,9 @@ pub fn (mut g Gen) set_with_expr(init ast.Expr, v Var) {
11121157
g.func.call('vmemcpy')
11131158
g.func.drop()
11141159

1115-
// Now populate the data if there are elements
1116-
if arr_len > 0 {
1160+
// Now populate the data if there are explicit elements (not using init:)
1161+
arr_len := init.exprs.len
1162+
if arr_len > 0 && !init.has_init {
11171163
// Get pointer to array data
11181164
data_ptr := g.func.new_local_named(.i32_t, '__tmp<array_data>')
11191165
g.func.local_get(array_struct_tmp)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Test array initialization with named parameters
2+
fn main() {
3+
// Test len only
4+
println('=== Array with len ===')
5+
a := []int{len: 5}
6+
println('len:')
7+
println(a.len)
8+
println('cap:')
9+
println(a.cap)
10+
11+
// Test len and cap
12+
println('=== Array with len and cap ===')
13+
b := []int{len: 3, cap: 10}
14+
println('len:')
15+
println(b.len)
16+
println('cap:')
17+
println(b.cap)
18+
19+
// Test len, cap, and init
20+
println('=== Array with len, cap, and init ===')
21+
c := []int{len: 4, cap: 8, init: 42}
22+
println('len:')
23+
println(c.len)
24+
println('cap:')
25+
println(c.cap)
26+
println('first element:')
27+
println(c[0])
28+
println('last element:')
29+
println(c[3])
30+
31+
// Test with different types
32+
println('=== String array with init ===')
33+
d := []string{len: 2, init: 'hello'}
34+
println('len:')
35+
println(d.len)
36+
println('first element:')
37+
println(d[0])
38+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== Array with len ===
2+
len:
3+
5
4+
cap:
5+
5
6+
=== Array with len and cap ===
7+
len:
8+
3
9+
cap:
10+
10
11+
=== Array with len, cap, and init ===
12+
len:
13+
4
14+
cap:
15+
8
16+
first element:
17+
42
18+
last element:
19+
42
20+
=== String array with init ===
21+
len:
22+
2
23+
first element:
24+
hello

0 commit comments

Comments
 (0)