runtime: Func, Method, Imethod

This commit is contained in:
xushiwei
2024-05-25 22:52:48 +08:00
parent f06899303c
commit afe20ffe92
7 changed files with 115 additions and 7 deletions

9
_demo/interf/foo/foo.go Normal file
View File

@@ -0,0 +1,9 @@
package foo
func Bar() any {
return struct{ V int }{1}
}
func F() any {
return struct{ v int }{1}
}

35
_demo/interf/interf.go Normal file
View File

@@ -0,0 +1,35 @@
package main
import (
"github.com/goplus/llgo/_demo/interf/foo"
)
func Foo() any {
return struct{ v int }{1}
}
func main() {
v := Foo()
if x, ok := v.(struct{ v int }); ok {
println(x.v)
} else {
println("Foo: not ok")
}
bar := foo.Bar()
if x, ok := bar.(struct{ V int }); ok {
println(x.V)
} else {
println("Bar: not ok")
}
if x, ok := foo.F().(struct{ v int }); ok {
println(x.v)
} else {
println("F: not ok")
}
}
/* Expected output:
1
1
F: not ok
*/

Binary file not shown.

View File

@@ -193,6 +193,21 @@ type FuncType struct {
OutCount uint16 // top bit is set if last input parameter is ... OutCount uint16 // top bit is set if last input parameter is ...
} }
// In returns the number of input parameters of a function type.
func (p *FuncType) In() int {
return int(p.InCount)
}
// Out returns the number of output results of a function type.
func (p *FuncType) Out() int {
return int(p.OutCount &^ (1 << 15))
}
// Variadic reports whether the function type is variadic.
func (p *FuncType) Variadic() bool {
return p.OutCount&(1<<15) != 0
}
type StructField struct { type StructField struct {
Name Name // name is always non-empty Name Name // name is always non-empty
Typ *Type // type of field Typ *Type // type of field
@@ -219,10 +234,10 @@ type Text = unsafe.Pointer // TODO(xsw): to be confirmed
// Method on non-interface type // Method on non-interface type
type Method struct { type Method struct {
Name_ Name // name of method Name_ Name // name of method
Mtyp_ *Type // method type (without receiver) Mtyp_ *FuncType // method type (without receiver)
Ifn_ Text // fn used in interface call (one-word receiver) Ifn_ Text // fn used in interface call (one-word receiver)
Tfn_ Text // fn used for normal method call Tfn_ Text // fn used for normal method call
} }
// UncommonType is present only for defined types or types with methods // UncommonType is present only for defined types or types with methods

Binary file not shown.

View File

@@ -10,9 +10,6 @@ import (
"github.com/goplus/llgo/internal/abi" "github.com/goplus/llgo/internal/abi"
) )
// type nameOff = abi.NameOff
// type typeOff = abi.TypeOff
type _type = abi.Type type _type = abi.Type
type interfacetype = abi.InterfaceType type interfacetype = abi.InterfaceType

View File

@@ -20,6 +20,7 @@ import (
"unsafe" "unsafe"
"github.com/goplus/llgo/internal/abi" "github.com/goplus/llgo/internal/abi"
"github.com/goplus/llgo/internal/runtime/c"
) )
type ( type (
@@ -31,10 +32,61 @@ type (
type Kind = abi.Kind type Kind = abi.Kind
type Type = abi.Type type Type = abi.Type
type FuncType = abi.FuncType
type InterfaceType = abi.InterfaceType type InterfaceType = abi.InterfaceType
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Func returns a function type.
func Func(in, out []*Type, variadic bool) *FuncType {
const (
funcTypeHdrSize = unsafe.Sizeof(abi.FuncType{})
pointerSize = unsafe.Sizeof(uintptr(0))
)
n := len(in) + len(out)
ptr := AllocU(funcTypeHdrSize + uintptr(n)*pointerSize)
c.Memset(ptr, 0, funcTypeHdrSize)
ret := (*abi.FuncType)(ptr)
ret.Size_ = pointerSize
ret.Hash = uint32(abi.Func) // TODO(xsw): hash
ret.Kind_ = uint8(abi.Func)
ret.InCount = uint16(len(in))
ret.OutCount = uint16(len(out))
if variadic {
ret.OutCount |= 1 << 15
}
data := (**Type)(c.Advance(ptr, int(funcTypeHdrSize)))
params := unsafe.Slice(data, n)
copy(params, in)
copy(params[len(in):], out)
return ret
}
// Imethod returns an interface method.
func Imethod(name string, typ *FuncType, exported bool) abi.Imethod {
n := abi.NewName(name, "", exported, false)
return abi.Imethod{
Name_: n,
Typ_: typ,
}
}
// Method returns a method.
func Method(name string, typ *FuncType, fn abi.Text, exported bool) abi.Method {
n := abi.NewName(name, "", exported, false)
return abi.Method{
Name_: n,
Mtyp_: typ,
Ifn_: fn,
Tfn_: fn,
}
}
// -----------------------------------------------------------------------------
// Named returns a named type. // Named returns a named type.
func Named(name string, typ *Type) *Type { func Named(name string, typ *Type) *Type {
ret := *typ // TODO(xsw): named type ret := *typ // TODO(xsw): named type