llgo/ssa: llvmSignature/castPtr/castInt bugfix; link: runtime

This commit is contained in:
xushiwei
2024-04-29 00:16:00 +08:00
parent 78d7f984d1
commit c30ed1b3c8
6 changed files with 715 additions and 27 deletions

View File

@@ -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.
//

View File

@@ -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

View File

@@ -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}
}