llgo/ssa: Imethod
This commit is contained in:
@@ -560,8 +560,9 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
|
|||||||
cv := v.Call.Value
|
cv := v.Call.Value
|
||||||
if mthd := v.Call.Method; mthd != nil {
|
if mthd := v.Call.Method; mthd != nil {
|
||||||
o := p.compileValue(b, cv)
|
o := p.compileValue(b, cv)
|
||||||
|
fn := b.Imethod(o, v.Call.Method)
|
||||||
args := p.compileValues(b, v.Call.Args, fnNormal)
|
args := p.compileValues(b, v.Call.Args, fnNormal)
|
||||||
ret = b.Icall(o, v.Call.Method, args...)
|
b.Call(fn, args...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
kind := p.funcKind(cv)
|
kind := p.funcKind(cv)
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
/*
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Closure represents a closure.
|
|
||||||
type Closure struct {
|
|
||||||
f unsafe.Pointer
|
|
||||||
data unsafe.Pointer // means no context if data is nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClosure creates a closure.
|
|
||||||
func NewClosure(f, data unsafe.Pointer) Closure {
|
|
||||||
return Closure{f, data}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClosureF returns the function of a closure.
|
|
||||||
func ClosureF(c Closure) unsafe.Pointer {
|
|
||||||
return c.f
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClosureData returns the data of a closure.
|
|
||||||
func ClosureData(c Closure) unsafe.Pointer {
|
|
||||||
return c.data
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
14
ssa/expr.go
14
ssa/expr.go
@@ -900,15 +900,6 @@ func (b Builder) InlineCall(fn Expr, args ...Expr) (ret Expr) {
|
|||||||
return b.Call(fn, args...)
|
return b.Call(fn, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Icall instruction represents a interface method call.
|
|
||||||
//
|
|
||||||
// Example printed form:
|
|
||||||
//
|
|
||||||
// t7 = invoke t5.Println(...t6)
|
|
||||||
func (b Builder) Icall(o Expr, method *types.Func, args ...Expr) (ret Expr) {
|
|
||||||
panic("todo")
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Call instruction represents a function call.
|
// The Call instruction represents a function call.
|
||||||
//
|
//
|
||||||
// The Call instruction yields the function result if there is exactly
|
// The Call instruction yields the function result if there is exactly
|
||||||
@@ -1079,11 +1070,10 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
|||||||
typ = prog.Float64()
|
typ = prog.Float64()
|
||||||
case vkSlice:
|
case vkSlice:
|
||||||
fn = "PrintSlice"
|
fn = "PrintSlice"
|
||||||
case vkPtr, vkFuncPtr, vkFuncDecl:
|
|
||||||
fn = "PrintPointer"
|
|
||||||
typ = prog.VoidPtr()
|
|
||||||
case vkClosure:
|
case vkClosure:
|
||||||
arg = b.Field(arg, 0)
|
arg = b.Field(arg, 0)
|
||||||
|
fallthrough
|
||||||
|
case vkPtr, vkFuncPtr, vkFuncDecl:
|
||||||
fn = "PrintPointer"
|
fn = "PrintPointer"
|
||||||
typ = prog.VoidPtr()
|
typ = prog.VoidPtr()
|
||||||
case vkString:
|
case vkString:
|
||||||
|
|||||||
@@ -226,6 +226,31 @@ func (b Builder) unsafeInterface(rawIntf *types.Interface, t Expr, data llvm.Val
|
|||||||
return b.unsafeIface(itab.impl, data)
|
return b.unsafeIface(itab.impl, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func iMethodOf(rawIntf *types.Interface, method *types.Func) int {
|
||||||
|
name := method.Name()
|
||||||
|
n := rawIntf.NumMethods()
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
m := rawIntf.Method(i)
|
||||||
|
if m.Name() == name {
|
||||||
|
// TODO(xsw): check signature
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Imethod returns closure of an interface method.
|
||||||
|
func (b Builder) Imethod(intf Expr, method *types.Func) Expr {
|
||||||
|
prog := b.Prog
|
||||||
|
rawIntf := intf.raw.Type.Underlying().(*types.Interface)
|
||||||
|
i := iMethodOf(rawIntf, method)
|
||||||
|
impl := intf.impl
|
||||||
|
itab := Expr{b.faceItab(impl), prog.VoidPtrPtr()}
|
||||||
|
pfn := b.Advance(itab, prog.IntVal(uint64(i+3), prog.Int()))
|
||||||
|
tclosure := prog.Type(method.Type(), InGo)
|
||||||
|
return b.aggregateValue(tclosure, b.Load(pfn).impl, b.faceData(impl))
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// MakeInterface constructs an instance of an interface type from a
|
// MakeInterface constructs an instance of an interface type from a
|
||||||
@@ -427,6 +452,10 @@ func (b Builder) faceData(x llvm.Value) llvm.Value {
|
|||||||
return llvm.CreateExtractValue(b.impl, x, 1)
|
return llvm.CreateExtractValue(b.impl, x, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b Builder) faceItab(x llvm.Value) llvm.Value {
|
||||||
|
return llvm.CreateExtractValue(b.impl, x, 0)
|
||||||
|
}
|
||||||
|
|
||||||
func (b Builder) faceAbiType(x Expr) Expr {
|
func (b Builder) faceAbiType(x Expr) Expr {
|
||||||
if x.kind == vkIface {
|
if x.kind == vkIface {
|
||||||
panic("todo")
|
panic("todo")
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ type aProgram struct {
|
|||||||
anyTy Type
|
anyTy Type
|
||||||
voidTy Type
|
voidTy Type
|
||||||
voidPtr Type
|
voidPtr Type
|
||||||
|
voidPPtr Type
|
||||||
boolTy Type
|
boolTy Type
|
||||||
cstrTy Type
|
cstrTy Type
|
||||||
cintTy Type
|
cintTy Type
|
||||||
@@ -371,6 +372,13 @@ func (p Program) VoidPtr() Type {
|
|||||||
return p.voidPtr
|
return p.voidPtr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Program) VoidPtrPtr() Type {
|
||||||
|
if p.voidPPtr == nil {
|
||||||
|
p.voidPPtr = p.rawType(types.NewPointer(types.Typ[types.UnsafePointer]))
|
||||||
|
}
|
||||||
|
return p.voidPPtr
|
||||||
|
}
|
||||||
|
|
||||||
// Bool returns bool type.
|
// Bool returns bool type.
|
||||||
func (p Program) Bool() Type {
|
func (p Program) Bool() Type {
|
||||||
if p.boolTy == nil {
|
if p.boolTy == nil {
|
||||||
|
|||||||
@@ -66,27 +66,6 @@ func (p Program) FuncDecl(sig *types.Signature, bg Background) Type {
|
|||||||
return &aType{p.toLLVMFunc(sig), rawType{sig}, vkFuncDecl}
|
return &aType{p.toLLVMFunc(sig), rawType{sig}, vkFuncDecl}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// cvtCxFunc converts a C extended function type into raw type.
|
|
||||||
func cvtCxFunc(sig *types.Signature, recv *types.Var) *types.Signature {
|
|
||||||
if sig.Variadic() {
|
|
||||||
// convert printf-like function type
|
|
||||||
tParams := sig.Params()
|
|
||||||
n := tParams.Len()
|
|
||||||
params := make([]*types.Var, n)
|
|
||||||
n--
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
params[i] = tParams.At(i)
|
|
||||||
}
|
|
||||||
params[n] = VArg()
|
|
||||||
sig = types.NewSignatureType(nil, nil, nil, types.NewTuple(params...), sig.Results(), true)
|
|
||||||
panic("todo")
|
|
||||||
}
|
|
||||||
sig = FuncAddCtx(recv, sig)
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Closure creates a closture type for a function.
|
// Closure creates a closture type for a function.
|
||||||
func (p Program) Closure(fn Type) Type {
|
func (p Program) Closure(fn Type) Type {
|
||||||
sig := fn.raw.Type.(*types.Signature)
|
sig := fn.raw.Type.(*types.Signature)
|
||||||
|
|||||||
Reference in New Issue
Block a user