Correct function name for calls to other packages
Этот коммит содержится в:
родитель
9d3dfd8868
коммит
cefce41df0
1 изменённых файлов: 30 добавлений и 34 удалений
64
tgo.go
64
tgo.go
|
@ -57,12 +57,18 @@ type Compiler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Frame struct {
|
type Frame struct {
|
||||||
pkgPrefix string
|
llvmFn llvm.Value
|
||||||
llvmFn llvm.Value
|
params map[*ssa.Parameter]int // arguments to the function
|
||||||
params map[*ssa.Parameter]int // arguments to the function
|
locals map[ssa.Value]llvm.Value // local variables
|
||||||
locals map[ssa.Value]llvm.Value // local variables
|
blocks map[*ssa.BasicBlock]llvm.BasicBlock
|
||||||
blocks map[*ssa.BasicBlock]llvm.BasicBlock
|
phis []Phi
|
||||||
phis []Phi
|
}
|
||||||
|
|
||||||
|
func pkgPrefix(pkg *ssa.Package) string {
|
||||||
|
if pkg.Pkg.Name() == "main" {
|
||||||
|
return "main"
|
||||||
|
}
|
||||||
|
return pkg.Pkg.Path()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Phi struct {
|
type Phi struct {
|
||||||
|
@ -224,14 +230,9 @@ func (c *Compiler) Parse(mainPath string) error {
|
||||||
for _, name := range memberNames {
|
for _, name := range memberNames {
|
||||||
member := pkg.Members[name]
|
member := pkg.Members[name]
|
||||||
|
|
||||||
pkgPrefix := pkg.Pkg.Path()
|
|
||||||
if pkg.Pkg.Name() == "main" {
|
|
||||||
pkgPrefix = "main"
|
|
||||||
}
|
|
||||||
|
|
||||||
switch member := member.(type) {
|
switch member := member.(type) {
|
||||||
case *ssa.Function:
|
case *ssa.Function:
|
||||||
frame, err := c.parseFuncDecl(pkgPrefix, member)
|
frame, err := c.parseFuncDecl(member)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -244,7 +245,7 @@ func (c *Compiler) Parse(mainPath string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
global := llvm.AddGlobal(c.mod, typ, pkgPrefix + "." + member.Name())
|
global := llvm.AddGlobal(c.mod, typ, pkgPrefix(member.Pkg) + "." + member.Name())
|
||||||
if ast.IsExported(member.Name()) {
|
if ast.IsExported(member.Name()) {
|
||||||
global.SetLinkage(llvm.PrivateLinkage)
|
global.SetLinkage(llvm.PrivateLinkage)
|
||||||
}
|
}
|
||||||
|
@ -252,7 +253,7 @@ func (c *Compiler) Parse(mainPath string) error {
|
||||||
ms := program.MethodSets.MethodSet(member.Type())
|
ms := program.MethodSets.MethodSet(member.Type())
|
||||||
for i := 0; i < ms.Len(); i++ {
|
for i := 0; i < ms.Len(); i++ {
|
||||||
fn := program.MethodValue(ms.At(i))
|
fn := program.MethodValue(ms.At(i))
|
||||||
frame, err := c.parseFuncDecl(pkgPrefix, fn)
|
frame, err := c.parseFuncDecl(fn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -361,30 +362,30 @@ func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value {
|
||||||
return llvm.ConstInt(llvm.Int32Type(), c.itfTypeNumbers[typ], false)
|
return llvm.ConstInt(llvm.Int32Type(), c.itfTypeNumbers[typ], false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) getFunctionName(pkgPrefix string, fn *ssa.Function) string {
|
func (c *Compiler) getFunctionName(fn *ssa.Function) string {
|
||||||
if fn.Signature.Recv() != nil {
|
if fn.Signature.Recv() != nil {
|
||||||
// Method on a defined type.
|
// Method on a defined type.
|
||||||
typeName := fn.Params[0].Type().(*types.Named).Obj().Name()
|
typeName := fn.Params[0].Type().(*types.Named).Obj().Name()
|
||||||
return pkgPrefix + "." + typeName + "." + fn.Name()
|
return pkgPrefix(fn.Pkg) + "." + typeName + "." + fn.Name()
|
||||||
} else {
|
} else {
|
||||||
// Bare function.
|
// Bare function.
|
||||||
return pkgPrefix + "." + fn.Name()
|
if strings.HasPrefix(fn.Name(), "_Cfunc_") {
|
||||||
|
// Name CGo functions directly.
|
||||||
|
return fn.Name()[len("_Cfunc_"):]
|
||||||
|
} else {
|
||||||
|
return pkgPrefix(fn.Pkg) + "." + fn.Name()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) parseFuncDecl(pkgPrefix string, f *ssa.Function) (*Frame, error) {
|
func (c *Compiler) parseFuncDecl(f *ssa.Function) (*Frame, error) {
|
||||||
name := c.getFunctionName(pkgPrefix, f)
|
f.WriteTo(os.Stdout)
|
||||||
if strings.HasPrefix(name, pkgPrefix + "._Cfunc_") {
|
name := c.getFunctionName(f)
|
||||||
// CGo wrapper declaration.
|
|
||||||
// Don't wrap the function, instead declare it.
|
|
||||||
name = name[len(pkgPrefix + "._Cfunc_"):]
|
|
||||||
}
|
|
||||||
|
|
||||||
frame := &Frame{
|
frame := &Frame{
|
||||||
pkgPrefix: pkgPrefix,
|
params: make(map[*ssa.Parameter]int),
|
||||||
params: make(map[*ssa.Parameter]int),
|
locals: make(map[ssa.Value]llvm.Value),
|
||||||
locals: make(map[ssa.Value]llvm.Value),
|
blocks: make(map[*ssa.BasicBlock]llvm.BasicBlock),
|
||||||
blocks: make(map[*ssa.BasicBlock]llvm.BasicBlock),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var retType llvm.Type
|
var retType llvm.Type
|
||||||
|
@ -581,12 +582,7 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
|
||||||
func (c *Compiler) parseFunctionCall(frame *Frame, call *ssa.CallCommon, fn *ssa.Function) (llvm.Value, error) {
|
func (c *Compiler) parseFunctionCall(frame *Frame, call *ssa.CallCommon, fn *ssa.Function) (llvm.Value, error) {
|
||||||
fmt.Printf(" function: %s\n", fn)
|
fmt.Printf(" function: %s\n", fn)
|
||||||
|
|
||||||
name := c.getFunctionName(frame.pkgPrefix, fn)
|
name := c.getFunctionName(fn)
|
||||||
if strings.HasPrefix(name, frame.pkgPrefix + "._Cfunc_") {
|
|
||||||
// Call C function directly.
|
|
||||||
name = name[len(frame.pkgPrefix + "._Cfunc_"):]
|
|
||||||
}
|
|
||||||
|
|
||||||
target := c.mod.NamedFunction(name)
|
target := c.mod.NamedFunction(name)
|
||||||
if target.IsNil() {
|
if target.IsNil() {
|
||||||
return llvm.Value{}, errors.New("undefined function: " + name)
|
return llvm.Value{}, errors.New("undefined function: " + name)
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче