diff --git a/cl/_testrt/map/out.ll b/cl/_testrt/map/out.ll index 1a93ecaf..19de1043 100644 --- a/cl/_testrt/map/out.ll +++ b/cl/_testrt/map/out.ll @@ -4,6 +4,8 @@ source_filename = "main" @"main.init$guard" = global ptr null @__llgo_argc = global ptr null @__llgo_argv = global ptr null +@"map[_llgo_int]_llgo_int" = linkonce global ptr null +@_llgo_int = linkonce global ptr null @0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1 define void @main.init() { @@ -13,6 +15,7 @@ _llgo_0: _llgo_1: ; preds = %_llgo_0 store i1 true, ptr @"main.init$guard", align 1 + call void @"main.init$after"() br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 @@ -26,7 +29,13 @@ _llgo_0: call void @"github.com/goplus/llgo/internal/runtime.init"() call void @main.init() %2 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeSmallMap"() - %3 = call i32 (ptr, ...) @printf(ptr @0, ) + %3 = load ptr, ptr @"map[_llgo_int]_llgo_int", align 8 + %4 = call ptr @"github.com/goplus/llgo/internal/runtime.MapAssign"(ptr %3, ptr %2, i64 23) + store i64 100, ptr %4, align 4 + %5 = load ptr, ptr @"map[_llgo_int]_llgo_int", align 8 + %6 = call ptr @"github.com/goplus/llgo/internal/runtime.MapAssign"(ptr %5, ptr %2, i64 7) + store i64 29, ptr %6, align 4 + %7 = call i32 (ptr, ...) @printf(ptr @0, ) ret i32 0 } @@ -34,4 +43,37 @@ declare void @"github.com/goplus/llgo/internal/runtime.init"() declare ptr @"github.com/goplus/llgo/internal/runtime.MakeSmallMap"() +define void @"main.init$after"() { +_llgo_0: + %0 = load ptr, ptr @_llgo_int, align 8 + %1 = icmp eq ptr %0, null + br i1 %1, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %2 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) + store ptr %2, ptr @_llgo_int, align 8 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + %3 = load ptr, ptr @_llgo_int, align 8 + %4 = load ptr, ptr @_llgo_int, align 8 + %5 = load ptr, ptr @"map[_llgo_int]_llgo_int", align 8 + %6 = icmp eq ptr %5, null + br i1 %6, label %_llgo_3, label %_llgo_4 + +_llgo_3: ; preds = %_llgo_2 + %7 = call ptr @"github.com/goplus/llgo/internal/runtime.MapOf"(ptr %3, ptr %4) + store ptr %7, ptr @"map[_llgo_int]_llgo_int", align 8 + br label %_llgo_4 + +_llgo_4: ; preds = %_llgo_3, %_llgo_2 + ret void +} + +declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) + +declare ptr @"github.com/goplus/llgo/internal/runtime.MapOf"(ptr, ptr) + +declare ptr @"github.com/goplus/llgo/internal/runtime.MapAssign"(ptr, ptr, ptr) + declare i32 @printf(ptr, ...) diff --git a/internal/runtime/z_slice.go b/internal/runtime/z_slice.go index 61c80381..3657b22c 100644 --- a/internal/runtime/z_slice.go +++ b/internal/runtime/z_slice.go @@ -24,10 +24,10 @@ import ( // ----------------------------------------------------------------------------- -// Slice is the runtime representation of a slice. -type Slice = slice +// type Slice = slice -type slice struct { +// Slice is the runtime representation of a slice. +type Slice struct { data unsafe.Pointer len int cap int diff --git a/ssa/abi/abi.go b/ssa/abi/abi.go index 4841b895..28e065b3 100644 --- a/ssa/abi/abi.go +++ b/ssa/abi/abi.go @@ -159,6 +159,10 @@ func (b *Builder) TypeName(t types.Type) (ret string, pub bool) { return "_llgo_any", true } return b.InterfaceName(t) + case *types.Map: + key, pub1 := b.TypeName(t.Key()) + elem, pub2 := b.TypeName(t.Elem()) + return fmt.Sprintf("map[%s]%s", key, elem), pub1 && pub2 } log.Panicf("todo: %T\n", t) return diff --git a/ssa/abitype.go b/ssa/abitype.go index 36c14489..da29c957 100644 --- a/ssa/abitype.go +++ b/ssa/abitype.go @@ -66,6 +66,8 @@ func (b Builder) abiTypeOf(t types.Type) func() Expr { return b.abiFuncOf(t) case *types.Slice: return b.abiSliceOf(t) + case *types.Map: + return b.abiMapOf(t) case *types.Array: return b.abiArrayOf(t) } @@ -244,6 +246,14 @@ func (b Builder) abiPointerOf(t *types.Pointer) func() Expr { } } +func (b Builder) abiMapOf(t *types.Map) func() Expr { + key := b.abiType(t.Key()) + elem := b.abiType(t.Elem()) + return func() Expr { + return b.Call(b.Pkg.rtFunc("MapOf"), key, elem) + } +} + func (b Builder) abiSliceOf(t *types.Slice) func() Expr { elem := b.abiType(t.Elem()) return func() Expr { diff --git a/ssa/datastruct.go b/ssa/datastruct.go index 9981ca8f..0070e160 100644 --- a/ssa/datastruct.go +++ b/ssa/datastruct.go @@ -365,7 +365,9 @@ func (b Builder) MapUpdate(m, k, v Expr) { panic("TODO: not a map") } tabi := b.abiType(t.raw.Type) - ptr := b.InlineCall(b.Pkg.rtFunc("MapAssign"), tabi, m, k) + prog := b.Prog + ptrimpl := b.InlineCall(b.Pkg.rtFunc("MapAssign"), tabi, m, k).impl + ptr := Expr{ptrimpl, prog.Pointer(v.Type)} b.Store(ptr, v) // TODO(xsw): indirect store }