runtime: Func, Method, Imethod
This commit is contained in:
9
_demo/interf/foo/foo.go
Normal file
9
_demo/interf/foo/foo.go
Normal 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
35
_demo/interf/interf.go
Normal 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.
@@ -193,6 +193,21 @@ type FuncType struct {
|
||||
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 {
|
||||
Name Name // name is always non-empty
|
||||
Typ *Type // type of field
|
||||
@@ -219,10 +234,10 @@ type Text = unsafe.Pointer // TODO(xsw): to be confirmed
|
||||
|
||||
// Method on non-interface type
|
||||
type Method struct {
|
||||
Name_ Name // name of method
|
||||
Mtyp_ *Type // method type (without receiver)
|
||||
Ifn_ Text // fn used in interface call (one-word receiver)
|
||||
Tfn_ Text // fn used for normal method call
|
||||
Name_ Name // name of method
|
||||
Mtyp_ *FuncType // method type (without receiver)
|
||||
Ifn_ Text // fn used in interface call (one-word receiver)
|
||||
Tfn_ Text // fn used for normal method call
|
||||
}
|
||||
|
||||
// UncommonType is present only for defined types or types with methods
|
||||
|
||||
Binary file not shown.
@@ -10,9 +10,6 @@ import (
|
||||
"github.com/goplus/llgo/internal/abi"
|
||||
)
|
||||
|
||||
// type nameOff = abi.NameOff
|
||||
// type typeOff = abi.TypeOff
|
||||
|
||||
type _type = abi.Type
|
||||
|
||||
type interfacetype = abi.InterfaceType
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/internal/abi"
|
||||
"github.com/goplus/llgo/internal/runtime/c"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -31,10 +32,61 @@ type (
|
||||
type Kind = abi.Kind
|
||||
type Type = abi.Type
|
||||
|
||||
type FuncType = abi.FuncType
|
||||
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.
|
||||
func Named(name string, typ *Type) *Type {
|
||||
ret := *typ // TODO(xsw): named type
|
||||
|
||||
Reference in New Issue
Block a user