Skip to content

Commit 49d703b

Browse files
Copilotenghitalo
andcommitted
Step 3: Implement dynamic array initialization
Co-authored-by: enghitalo <63821277+enghitalo@users.noreply.github.com>
1 parent c5af35a commit 49d703b

3 files changed

Lines changed: 107 additions & 1 deletion

File tree

vlib/v/gen/wasm/mem.v

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,83 @@ pub fn (mut g Gen) set_with_expr(init ast.Expr, v Var) {
740740
}
741741
ast.ArrayInit {
742742
if !init.is_fixed {
743-
g.v_error('wasm backend does not support non fixed arrays yet', init.pos)
743+
// Dynamic array initialization
744+
// For now, we'll manually construct the array struct
745+
// instead of calling __new_array (which may not be available)
746+
elm_typ := init.elem_type
747+
elm_size, _ := g.pool.type_size(elm_typ)
748+
749+
// Calculate array length
750+
arr_len := init.exprs.len
751+
752+
// Allocate data for array elements if needed
753+
if arr_len > 0 {
754+
// Allocate memory for data: len * element_size
755+
total_size := arr_len * elm_size
756+
g.literalint(total_size, ast.int_type)
757+
g.func.call('vcalloc') // Returns pointer to zeroed memory
758+
759+
// Store data pointer temporarily
760+
data_ptr := g.func.new_local_named(.i32_t, '__tmp<array_data>')
761+
g.func.local_tee(data_ptr)
762+
763+
// Populate the data
764+
for i, e in init.exprs {
765+
g.func.local_get(data_ptr)
766+
if i > 0 {
767+
if elm_size > 1 {
768+
g.literalint(i * elm_size, ast.int_type)
769+
} else {
770+
g.literalint(i, ast.int_type)
771+
}
772+
g.func.add(.i32_t)
773+
}
774+
775+
g.expr(e, elm_typ)
776+
g.store(elm_typ, 0)
777+
}
778+
779+
// Now build the array struct on stack
780+
// Store data pointer (offset 0)
781+
g.get(v)
782+
g.func.local_get(data_ptr)
783+
g.store(ast.voidptr_type, 0)
784+
785+
// Store offset = 0 (offset 4)
786+
g.get(v)
787+
g.literalint(0, ast.int_type)
788+
g.store(ast.int_type, 4)
789+
790+
// Store len (offset 8)
791+
g.get(v)
792+
g.literalint(arr_len, ast.int_type)
793+
g.store(ast.int_type, 8)
794+
795+
// Store cap (offset 12)
796+
g.get(v)
797+
g.literalint(arr_len, ast.int_type)
798+
g.store(ast.int_type, 12)
799+
800+
// Store flags = 0 (offset 16)
801+
g.get(v)
802+
g.literalint(0, ast.int_type)
803+
g.store(ast.int_type, 16)
804+
805+
// Store element_size (offset 20)
806+
g.get(v)
807+
g.literalint(elm_size, ast.int_type)
808+
g.store(ast.int_type, 20)
809+
} else {
810+
// Empty array - zero out the struct
811+
arr_size, _ := g.pool.type_size(v.typ)
812+
g.zero_fill(v, arr_size)
813+
814+
// Still need to set element_size
815+
g.get(v)
816+
g.literalint(elm_size, ast.int_type)
817+
g.store(ast.int_type, 20)
818+
}
819+
return
744820
}
745821

746822
elm_typ := init.elem_type
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Step 3: Test array initialization
2+
// This tests creating arrays with __new_array() and literal initialization
3+
4+
fn test_empty_array() {
5+
_ := []int{}
6+
println('Empty array created')
7+
}
8+
9+
fn test_array_with_literals() {
10+
a := [10, 20, 30]
11+
println('Array with literals')
12+
println(a[0])
13+
println(a[1])
14+
println(a[2])
15+
}
16+
17+
fn main() {
18+
println('Step 3: Array initialization test')
19+
test_empty_array()
20+
test_array_with_literals()
21+
println('Initialization OK')
22+
}
23+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Step 3: Array initialization test
2+
Empty array created
3+
Array with literals
4+
10
5+
20
6+
30
7+
Initialization OK

0 commit comments

Comments
 (0)