llgo/ssa: llvmSignature/castPtr/castInt bugfix; link: runtime
This commit is contained in:
24
ssa/expr.go
24
ssa/expr.go
@@ -494,19 +494,37 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
|
||||
kind := und.Kind()
|
||||
switch {
|
||||
case kind >= types.Int && kind <= types.Uintptr:
|
||||
ret.impl = b.impl.CreateIntCast(x.impl, t.ll, "castInt")
|
||||
ret.impl = castInt(b.impl, x.impl, t.ll)
|
||||
return
|
||||
case kind == types.UnsafePointer:
|
||||
ret.impl = b.impl.CreatePointerCast(x.impl, t.ll, "castPtr")
|
||||
ret.impl = castPtr(b.impl, x.impl, t.ll)
|
||||
return
|
||||
}
|
||||
case *types.Pointer:
|
||||
ret.impl = b.impl.CreatePointerCast(x.impl, t.ll, "castPtr")
|
||||
ret.impl = castPtr(b.impl, x.impl, t.ll)
|
||||
return
|
||||
}
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
func castInt(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value {
|
||||
xt := x.Type()
|
||||
if xt.TypeKind() == llvm.PointerTypeKind {
|
||||
return b.CreatePtrToInt(x, t, "ptr2int")
|
||||
}
|
||||
if xt.IntTypeWidth() <= t.IntTypeWidth() {
|
||||
return b.CreateIntCast(x, t, "castInt")
|
||||
}
|
||||
return b.CreateTrunc(x, t, "truncInt")
|
||||
}
|
||||
|
||||
func castPtr(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value {
|
||||
if x.Type().TypeKind() == llvm.PointerTypeKind {
|
||||
return b.CreatePointerCast(x, t, "castPtr")
|
||||
}
|
||||
return b.CreateIntToPtr(x, t, "int2ptr")
|
||||
}
|
||||
|
||||
// MakeInterface constructs an instance of an interface type from a
|
||||
// value of a concrete type.
|
||||
//
|
||||
|
||||
@@ -305,7 +305,7 @@ func (p Package) NewFunc(name string, sig *types.Signature) Function {
|
||||
if v, ok := p.fns[name]; ok {
|
||||
return v
|
||||
}
|
||||
t := p.prog.llvmSignature(sig)
|
||||
t := p.prog.llvmSignature(sig, false)
|
||||
fn := llvm.AddFunction(p.mod, name, t.ll)
|
||||
ret := newFunction(fn, t, p, p.prog)
|
||||
p.fns[name] = ret
|
||||
|
||||
11
ssa/type.go
11
ssa/type.go
@@ -124,7 +124,7 @@ func (p Program) Field(typ Type, i int) Type {
|
||||
|
||||
func (p Program) Type(typ types.Type) Type {
|
||||
if sig, ok := typ.(*types.Signature); ok { // should methodToFunc
|
||||
return p.llvmSignature(sig)
|
||||
return p.llvmSignature(sig, true)
|
||||
}
|
||||
if v := p.typs.At(typ); v != nil {
|
||||
return v.(Type)
|
||||
@@ -134,12 +134,12 @@ func (p Program) Type(typ types.Type) Type {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p Program) llvmSignature(sig *types.Signature) Type {
|
||||
func (p Program) llvmSignature(sig *types.Signature, isPtr bool) Type {
|
||||
sig = methodToFunc(sig)
|
||||
if v := p.typs.At(sig); v != nil {
|
||||
return v.(Type)
|
||||
}
|
||||
ret := p.toLLVMFunc(sig)
|
||||
ret := p.toLLVMFunc(sig, isPtr)
|
||||
p.typs.Set(sig, ret)
|
||||
return ret
|
||||
}
|
||||
@@ -301,7 +301,7 @@ func (p Program) toLLVMTypes(t *types.Tuple, n int) (ret []llvm.Type) {
|
||||
return
|
||||
}
|
||||
|
||||
func (p Program) toLLVMFunc(sig *types.Signature) Type {
|
||||
func (p Program) toLLVMFunc(sig *types.Signature, isPtr bool) Type {
|
||||
tParams := sig.Params()
|
||||
n := tParams.Len()
|
||||
hasVArg := HasVArg(tParams, n)
|
||||
@@ -320,6 +320,9 @@ func (p Program) toLLVMFunc(sig *types.Signature) Type {
|
||||
ret = p.toLLVMTuple(out)
|
||||
}
|
||||
ft := llvm.FunctionType(ret, params, hasVArg)
|
||||
if isPtr {
|
||||
ft = llvm.PointerType(ft, 0)
|
||||
}
|
||||
return &aType{ft, sig, vkFunc}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user