compiler: simplify some interface code
No error is produced, so no error needs to be returned. It was missed in https://github.com/tinygo-org/tinygo/pull/294. Also, it fixes this smelly code: if err != nil { return <something>, nil } There could never be an error, so the code was already dead.
Этот коммит содержится в:
родитель
763b9d7d10
коммит
c981f14e61
2 изменённых файлов: 13 добавлений и 19 удалений
|
@ -1416,7 +1416,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
return c.parseMakeClosure(frame, expr)
|
return c.parseMakeClosure(frame, expr)
|
||||||
case *ssa.MakeInterface:
|
case *ssa.MakeInterface:
|
||||||
val := c.getValue(frame, expr.X)
|
val := c.getValue(frame, expr.X)
|
||||||
return c.parseMakeInterface(val, expr.X.Type(), expr.Pos())
|
return c.parseMakeInterface(val, expr.X.Type(), expr.Pos()), nil
|
||||||
case *ssa.MakeMap:
|
case *ssa.MakeMap:
|
||||||
mapType := expr.Type().Underlying().(*types.Map)
|
mapType := expr.Type().Underlying().(*types.Map)
|
||||||
llvmKeyType := c.getLLVMType(mapType.Key().Underlying())
|
llvmKeyType := c.getLLVMType(mapType.Key().Underlying())
|
||||||
|
|
|
@ -22,13 +22,10 @@ import (
|
||||||
// value field.
|
// value field.
|
||||||
//
|
//
|
||||||
// An interface value is a {typecode, value} tuple, or {i16, i8*} to be exact.
|
// An interface value is a {typecode, value} tuple, or {i16, i8*} to be exact.
|
||||||
func (c *Compiler) parseMakeInterface(val llvm.Value, typ types.Type, pos token.Pos) (llvm.Value, error) {
|
func (c *Compiler) parseMakeInterface(val llvm.Value, typ types.Type, pos token.Pos) llvm.Value {
|
||||||
itfValue := c.emitPointerPack([]llvm.Value{val})
|
itfValue := c.emitPointerPack([]llvm.Value{val})
|
||||||
itfTypeCodeGlobal := c.getTypeCode(typ)
|
itfTypeCodeGlobal := c.getTypeCode(typ)
|
||||||
itfMethodSetGlobal, err := c.getTypeMethodSet(typ)
|
itfMethodSetGlobal := c.getTypeMethodSet(typ)
|
||||||
if err != nil {
|
|
||||||
return llvm.Value{}, nil
|
|
||||||
}
|
|
||||||
itfConcreteTypeGlobal := c.mod.NamedGlobal("typeInInterface:" + itfTypeCodeGlobal.Name())
|
itfConcreteTypeGlobal := c.mod.NamedGlobal("typeInInterface:" + itfTypeCodeGlobal.Name())
|
||||||
if itfConcreteTypeGlobal.IsNil() {
|
if itfConcreteTypeGlobal.IsNil() {
|
||||||
typeInInterface := c.mod.GetTypeByName("runtime.typeInInterface")
|
typeInInterface := c.mod.GetTypeByName("runtime.typeInInterface")
|
||||||
|
@ -41,7 +38,7 @@ func (c *Compiler) parseMakeInterface(val llvm.Value, typ types.Type, pos token.
|
||||||
itf := llvm.Undef(c.mod.GetTypeByName("runtime._interface"))
|
itf := llvm.Undef(c.mod.GetTypeByName("runtime._interface"))
|
||||||
itf = c.builder.CreateInsertValue(itf, itfTypeCode, 0, "")
|
itf = c.builder.CreateInsertValue(itf, itfTypeCode, 0, "")
|
||||||
itf = c.builder.CreateInsertValue(itf, itfValue, 1, "")
|
itf = c.builder.CreateInsertValue(itf, itfValue, 1, "")
|
||||||
return itf, nil
|
return itf
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTypeCode returns a reference to a type code.
|
// getTypeCode returns a reference to a type code.
|
||||||
|
@ -155,18 +152,18 @@ func getTypeCodeName(t types.Type) string {
|
||||||
|
|
||||||
// getTypeMethodSet returns a reference (GEP) to a global method set. This
|
// getTypeMethodSet returns a reference (GEP) to a global method set. This
|
||||||
// method set should be unreferenced after the interface lowering pass.
|
// method set should be unreferenced after the interface lowering pass.
|
||||||
func (c *Compiler) getTypeMethodSet(typ types.Type) (llvm.Value, error) {
|
func (c *Compiler) getTypeMethodSet(typ types.Type) llvm.Value {
|
||||||
global := c.mod.NamedGlobal(typ.String() + "$methodset")
|
global := c.mod.NamedGlobal(typ.String() + "$methodset")
|
||||||
zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false)
|
zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false)
|
||||||
if !global.IsNil() {
|
if !global.IsNil() {
|
||||||
// the method set already exists
|
// the method set already exists
|
||||||
return llvm.ConstGEP(global, []llvm.Value{zero, zero}), nil
|
return llvm.ConstGEP(global, []llvm.Value{zero, zero})
|
||||||
}
|
}
|
||||||
|
|
||||||
ms := c.ir.Program.MethodSets.MethodSet(typ)
|
ms := c.ir.Program.MethodSets.MethodSet(typ)
|
||||||
if ms.Len() == 0 {
|
if ms.Len() == 0 {
|
||||||
// no methods, so can leave that one out
|
// no methods, so can leave that one out
|
||||||
return llvm.ConstPointerNull(llvm.PointerType(c.mod.GetTypeByName("runtime.interfaceMethodInfo"), 0)), nil
|
return llvm.ConstPointerNull(llvm.PointerType(c.mod.GetTypeByName("runtime.interfaceMethodInfo"), 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
methods := make([]llvm.Value, ms.Len())
|
methods := make([]llvm.Value, ms.Len())
|
||||||
|
@ -179,10 +176,7 @@ func (c *Compiler) getTypeMethodSet(typ types.Type) (llvm.Value, error) {
|
||||||
// compiler error, so panic
|
// compiler error, so panic
|
||||||
panic("cannot find function: " + f.LinkName())
|
panic("cannot find function: " + f.LinkName())
|
||||||
}
|
}
|
||||||
fn, err := c.getInterfaceInvokeWrapper(f)
|
fn := c.getInterfaceInvokeWrapper(f)
|
||||||
if err != nil {
|
|
||||||
return llvm.Value{}, err
|
|
||||||
}
|
|
||||||
methodInfo := llvm.ConstNamedStruct(interfaceMethodInfoType, []llvm.Value{
|
methodInfo := llvm.ConstNamedStruct(interfaceMethodInfoType, []llvm.Value{
|
||||||
signatureGlobal,
|
signatureGlobal,
|
||||||
llvm.ConstPtrToInt(fn, c.uintptrType),
|
llvm.ConstPtrToInt(fn, c.uintptrType),
|
||||||
|
@ -195,7 +189,7 @@ func (c *Compiler) getTypeMethodSet(typ types.Type) (llvm.Value, error) {
|
||||||
global.SetInitializer(value)
|
global.SetInitializer(value)
|
||||||
global.SetGlobalConstant(true)
|
global.SetGlobalConstant(true)
|
||||||
global.SetLinkage(llvm.PrivateLinkage)
|
global.SetLinkage(llvm.PrivateLinkage)
|
||||||
return llvm.ConstGEP(global, []llvm.Value{zero, zero}), nil
|
return llvm.ConstGEP(global, []llvm.Value{zero, zero})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getInterfaceMethodSet returns a global variable with the method set of the
|
// getInterfaceMethodSet returns a global variable with the method set of the
|
||||||
|
@ -365,12 +359,12 @@ type interfaceInvokeWrapper struct {
|
||||||
// the underlying value, dereferences it, and calls the real method. This
|
// the underlying value, dereferences it, and calls the real method. This
|
||||||
// wrapper is only needed when the interface value actually doesn't fit in a
|
// wrapper is only needed when the interface value actually doesn't fit in a
|
||||||
// pointer and a pointer to the value must be created.
|
// pointer and a pointer to the value must be created.
|
||||||
func (c *Compiler) getInterfaceInvokeWrapper(f *ir.Function) (llvm.Value, error) {
|
func (c *Compiler) getInterfaceInvokeWrapper(f *ir.Function) llvm.Value {
|
||||||
wrapperName := f.LinkName() + "$invoke"
|
wrapperName := f.LinkName() + "$invoke"
|
||||||
wrapper := c.mod.NamedFunction(wrapperName)
|
wrapper := c.mod.NamedFunction(wrapperName)
|
||||||
if !wrapper.IsNil() {
|
if !wrapper.IsNil() {
|
||||||
// Wrapper already created. Return it directly.
|
// Wrapper already created. Return it directly.
|
||||||
return wrapper, nil
|
return wrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the expanded receiver type.
|
// Get the expanded receiver type.
|
||||||
|
@ -383,7 +377,7 @@ func (c *Compiler) getInterfaceInvokeWrapper(f *ir.Function) (llvm.Value, error)
|
||||||
// Casting a function signature to a different signature and calling it
|
// Casting a function signature to a different signature and calling it
|
||||||
// with a receiver pointer bitcasted to *i8 (as done in calls on an
|
// with a receiver pointer bitcasted to *i8 (as done in calls on an
|
||||||
// interface) is hopefully a safe (defined) operation.
|
// interface) is hopefully a safe (defined) operation.
|
||||||
return f.LLVMFn, nil
|
return f.LLVMFn
|
||||||
}
|
}
|
||||||
|
|
||||||
// create wrapper function
|
// create wrapper function
|
||||||
|
@ -396,7 +390,7 @@ func (c *Compiler) getInterfaceInvokeWrapper(f *ir.Function) (llvm.Value, error)
|
||||||
wrapper: wrapper,
|
wrapper: wrapper,
|
||||||
receiverType: receiverType,
|
receiverType: receiverType,
|
||||||
})
|
})
|
||||||
return wrapper, nil
|
return wrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
// createInterfaceInvokeWrapper finishes the work of getInterfaceInvokeWrapper,
|
// createInterfaceInvokeWrapper finishes the work of getInterfaceInvokeWrapper,
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче