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 ...
|
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.
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user