llgo/ssa: MakeInterface

This commit is contained in:
xushiwei
2024-04-29 22:57:40 +08:00
parent 85bb1302ca
commit f64abf37ab
7 changed files with 40 additions and 14 deletions

View File

@@ -30,9 +30,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
define void @main() { define void @main() {
_llgo_0: _llgo_0:
call void @main.init() call void @main.init()
%0 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(i64 100) %0 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%1 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %0) %1 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %0, i64 100)
%2 = call i32 (ptr, ...) @printf(ptr @0, i64 %1) %2 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %1)
%3 = call i32 (ptr, ...) @printf(ptr @0, i64 %2)
ret void ret void
} }

View File

@@ -29,7 +29,7 @@ func testCompile(t *testing.T, src, expected string) {
} }
func TestFromTestcgo(t *testing.T) { func TestFromTestcgo(t *testing.T) {
cltest.FromDir(t, "", "./_testcgo", true) cltest.FromDir(t, "any", "./_testcgo", true)
} }
func TestFromTestdata(t *testing.T) { func TestFromTestdata(t *testing.T) {

View File

@@ -22,7 +22,7 @@ import (
"github.com/goplus/llgo/internal/abi" "github.com/goplus/llgo/internal/abi"
) )
type Interface = iface // -----------------------------------------------------------------------------
type InterfaceType = abi.InterfaceType type InterfaceType = abi.InterfaceType
@@ -30,6 +30,10 @@ var (
TyAny = &InterfaceType{} TyAny = &InterfaceType{}
) )
// -----------------------------------------------------------------------------
type Interface = iface
func MakeAnyInt(typ *Type, data uintptr) Interface { func MakeAnyInt(typ *Type, data uintptr) Interface {
return Interface{ return Interface{
tab: &itab{inter: TyAny, _type: typ, hash: 0, fun: [1]uintptr{0}}, 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 return 0, false
} }
// -----------------------------------------------------------------------------

View File

@@ -20,6 +20,8 @@ import (
"unsafe" "unsafe"
) )
// -----------------------------------------------------------------------------
// Slice is the runtime representation of a slice. // Slice is the runtime representation of a slice.
type Slice struct { type Slice struct {
array unsafe.Pointer array unsafe.Pointer
@@ -31,3 +33,5 @@ type Slice struct {
func NilSlice() Slice { func NilSlice() Slice {
return Slice{nil, 0, 0} return Slice{nil, 0, 0}
} }
// -----------------------------------------------------------------------------

View File

@@ -20,6 +20,8 @@ import (
"unsafe" "unsafe"
) )
// -----------------------------------------------------------------------------
// String is the runtime representation of a string. // String is the runtime representation of a string.
// It cannot be used safely or portably and its representation may // It cannot be used safely or portably and its representation may
// change in a later release. // change in a later release.
@@ -35,3 +37,5 @@ type String struct {
func EmptyString() String { func EmptyString() String {
return String{nil, 0} return String{nil, 0}
} }
// -----------------------------------------------------------------------------

View File

@@ -22,6 +22,8 @@ import (
"github.com/goplus/llgo/internal/abi" "github.com/goplus/llgo/internal/abi"
) )
// -----------------------------------------------------------------------------
type Kind = abi.Kind type Kind = abi.Kind
type Type = abi.Type type Type = abi.Type
@@ -79,3 +81,5 @@ func basicType(kind abi.Kind) *Type {
Kind_: uint8(kind), Kind_: uint8(kind),
} }
} }
// -----------------------------------------------------------------------------

View File

@@ -569,17 +569,24 @@ func (b Builder) MakeInterface(inter types.Type, x Expr, mayDelay bool) (ret Exp
if debugInstr { if debugInstr {
log.Printf("MakeInterface %v, %v\n", inter, x.impl) log.Printf("MakeInterface %v, %v\n", inter, x.impl)
} }
t := inter.Underlying().(*types.Interface) tiund := inter.Underlying().(*types.Interface)
isAny := t.Empty() isAny := tiund.Empty()
fnDo := func() Expr { fnDo := func() Expr {
prog := b.Prog
pkg := b.fn.pkg pkg := b.fn.pkg
switch x.kind { tinter := prog.Type(inter)
case vkSigned, vkUnsigned, vkFloat: switch tx := x.t.Underlying().(type) {
fn := pkg.rtFunc("MakeAnyInt") case *types.Basic:
return b.InlineCall(fn, x) kind := tx.Kind()
case vkString: switch {
fn := pkg.rtFunc("MakeAnyString") case kind >= types.Int && kind <= types.Uintptr:
return b.InlineCall(fn, x) 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") panic("todo")
} }