diff --git a/cl/_testcgo/any/out.ll b/cl/_testcgo/any/out.ll index 3f495973..cb4e49d9 100644 --- a/cl/_testcgo/any/out.ll +++ b/cl/_testcgo/any/out.ll @@ -30,9 +30,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define void @main() { _llgo_0: call void @main.init() - %0 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(i64 100) - %1 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %0) - %2 = call i32 (ptr, ...) @printf(ptr @0, i64 %1) + %0 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) + %1 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %0, i64 100) + %2 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %1) + %3 = call i32 (ptr, ...) @printf(ptr @0, i64 %2) ret void } diff --git a/cl/compile_test.go b/cl/compile_test.go index 62f7bedb..7c948433 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -29,7 +29,7 @@ func testCompile(t *testing.T, src, expected string) { } func TestFromTestcgo(t *testing.T) { - cltest.FromDir(t, "", "./_testcgo", true) + cltest.FromDir(t, "any", "./_testcgo", true) } func TestFromTestdata(t *testing.T) { diff --git a/internal/runtime/z_iface.go b/internal/runtime/z_iface.go index a8ed5590..2d35d8f9 100644 --- a/internal/runtime/z_iface.go +++ b/internal/runtime/z_iface.go @@ -22,7 +22,7 @@ import ( "github.com/goplus/llgo/internal/abi" ) -type Interface = iface +// ----------------------------------------------------------------------------- type InterfaceType = abi.InterfaceType @@ -30,6 +30,10 @@ var ( TyAny = &InterfaceType{} ) +// ----------------------------------------------------------------------------- + +type Interface = iface + func MakeAnyInt(typ *Type, data uintptr) Interface { return Interface{ tab: &itab{inter: TyAny, _type: typ, hash: 0, fun: [1]uintptr{0}}, @@ -71,3 +75,5 @@ func CheckI2Int(v Interface, t *Type) (uintptr, bool) { } return 0, false } + +// ----------------------------------------------------------------------------- diff --git a/internal/runtime/z_slice.go b/internal/runtime/z_slice.go index 4a8e0e40..215d327a 100644 --- a/internal/runtime/z_slice.go +++ b/internal/runtime/z_slice.go @@ -20,6 +20,8 @@ import ( "unsafe" ) +// ----------------------------------------------------------------------------- + // Slice is the runtime representation of a slice. type Slice struct { array unsafe.Pointer @@ -31,3 +33,5 @@ type Slice struct { func NilSlice() Slice { return Slice{nil, 0, 0} } + +// ----------------------------------------------------------------------------- diff --git a/internal/runtime/z_string.go b/internal/runtime/z_string.go index ed8ca0c1..a31f991a 100644 --- a/internal/runtime/z_string.go +++ b/internal/runtime/z_string.go @@ -20,6 +20,8 @@ import ( "unsafe" ) +// ----------------------------------------------------------------------------- + // String is the runtime representation of a string. // It cannot be used safely or portably and its representation may // change in a later release. @@ -35,3 +37,5 @@ type String struct { func EmptyString() String { return String{nil, 0} } + +// ----------------------------------------------------------------------------- diff --git a/internal/runtime/z_type.go b/internal/runtime/z_type.go index 3e8adb26..85ee1b66 100644 --- a/internal/runtime/z_type.go +++ b/internal/runtime/z_type.go @@ -22,6 +22,8 @@ import ( "github.com/goplus/llgo/internal/abi" ) +// ----------------------------------------------------------------------------- + type Kind = abi.Kind type Type = abi.Type @@ -79,3 +81,5 @@ func basicType(kind abi.Kind) *Type { Kind_: uint8(kind), } } + +// ----------------------------------------------------------------------------- diff --git a/ssa/expr.go b/ssa/expr.go index 822e7172..50f6f732 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -569,17 +569,24 @@ func (b Builder) MakeInterface(inter types.Type, x Expr, mayDelay bool) (ret Exp if debugInstr { log.Printf("MakeInterface %v, %v\n", inter, x.impl) } - t := inter.Underlying().(*types.Interface) - isAny := t.Empty() + tiund := inter.Underlying().(*types.Interface) + isAny := tiund.Empty() fnDo := func() Expr { + prog := b.Prog pkg := b.fn.pkg - switch x.kind { - case vkSigned, vkUnsigned, vkFloat: - fn := pkg.rtFunc("MakeAnyInt") - return b.InlineCall(fn, x) - case vkString: - fn := pkg.rtFunc("MakeAnyString") - return b.InlineCall(fn, x) + tinter := prog.Type(inter) + switch tx := x.t.Underlying().(type) { + case *types.Basic: + kind := tx.Kind() + switch { + case kind >= types.Int && kind <= types.Uintptr: + t := b.InlineCall(pkg.rtFunc("Basic"), prog.Val(int(kind))) + tptr := prog.Uintptr() + vptr := Expr{llvm.CreateIntCast(b.impl, x.impl, tptr.ll), tptr} + return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter} + case kind == types.String: + return Expr{b.InlineCall(pkg.rtFunc("MakeAnyString"), x).impl, tinter} + } } panic("todo") }