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, | ||||||
|  |  | ||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Ayke van Laethem
						Ayke van Laethem