@@ -292,58 +292,40 @@ func (p *lowerInterfacesPass) run() error {
292292
293293 methodSet := use .Operand (1 ).Operand (0 ) // global variable
294294 itf := p .interfaces [methodSet .Name ()]
295- if len (itf .types ) == 0 {
296- // This method call is impossible: no type implements this
297- // interface. In fact, the previous type assert that got this
298- // interface value should already have returned false.
299- // Replace the function pointer with undef (which will then be
300- // called), indicating to the optimizer this code is unreachable.
301- use .ReplaceAllUsesWith (llvm .Undef (p .uintptrType ))
302- use .EraseFromParentAsInstruction ()
303- } else if len (itf .types ) == 1 {
304- // There is only one implementation of the given type.
305- // Call that function directly.
306- err := p .replaceInvokeWithCall (use , itf .types [0 ], signature )
307- if err != nil {
308- return err
309- }
310- } else {
311- // There are multiple types implementing this interface, thus there
312- // are multiple possible functions to call. Delegate calling the
313- // right function to a special wrapper function.
314- inttoptrs := getUses (use )
315- if len (inttoptrs ) != 1 || inttoptrs [0 ].IsAIntToPtrInst ().IsNil () {
316- return errorAt (use , "internal error: expected exactly one inttoptr use of runtime.interfaceMethod" )
295+
296+ // Delegate calling the right function to a special wrapper function.
297+ inttoptrs := getUses (use )
298+ if len (inttoptrs ) != 1 || inttoptrs [0 ].IsAIntToPtrInst ().IsNil () {
299+ return errorAt (use , "internal error: expected exactly one inttoptr use of runtime.interfaceMethod" )
300+ }
301+ inttoptr := inttoptrs [0 ]
302+ calls := getUses (inttoptr )
303+ for _ , call := range calls {
304+ // Set up parameters for the call. First copy the regular params...
305+ params := make ([]llvm.Value , call .OperandsCount ())
306+ paramTypes := make ([]llvm.Type , len (params ))
307+ for i := 0 ; i < len (params )- 1 ; i ++ {
308+ params [i ] = call .Operand (i )
309+ paramTypes [i ] = params [i ].Type ()
317310 }
318- inttoptr := inttoptrs [0 ]
319- calls := getUses (inttoptr )
320- for _ , call := range calls {
321- // Set up parameters for the call. First copy the regular params...
322- params := make ([]llvm.Value , call .OperandsCount ())
323- paramTypes := make ([]llvm.Type , len (params ))
324- for i := 0 ; i < len (params )- 1 ; i ++ {
325- params [i ] = call .Operand (i )
326- paramTypes [i ] = params [i ].Type ()
327- }
328- // then add the typecode to the end of the list.
329- params [len (params )- 1 ] = typecode
330- paramTypes [len (params )- 1 ] = p .uintptrType
331-
332- // Create a function that redirects the call to the destination
333- // call, after selecting the right concrete type.
334- redirector := p .getInterfaceMethodFunc (itf , signature , call .Type (), paramTypes )
335-
336- // Replace the old lookup/inttoptr/call with the new call.
337- p .builder .SetInsertPointBefore (call )
338- retval := p .builder .CreateCall (redirector , append (params , llvm .ConstNull (llvm .PointerType (p .ctx .Int8Type (), 0 ))), "" )
339- if retval .Type ().TypeKind () != llvm .VoidTypeKind {
340- call .ReplaceAllUsesWith (retval )
341- }
342- call .EraseFromParentAsInstruction ()
311+ // then add the typecode to the end of the list.
312+ params [len (params )- 1 ] = typecode
313+ paramTypes [len (params )- 1 ] = p .uintptrType
314+
315+ // Create a function that redirects the call to the destination
316+ // call, after selecting the right concrete type.
317+ redirector := p .getInterfaceMethodFunc (itf , signature , call .Type (), paramTypes )
318+
319+ // Replace the old lookup/inttoptr/call with the new call.
320+ p .builder .SetInsertPointBefore (call )
321+ retval := p .builder .CreateCall (redirector , append (params , llvm .ConstNull (llvm .PointerType (p .ctx .Int8Type (), 0 ))), "" )
322+ if retval .Type ().TypeKind () != llvm .VoidTypeKind {
323+ call .ReplaceAllUsesWith (retval )
343324 }
344- inttoptr .EraseFromParentAsInstruction ()
345- use .EraseFromParentAsInstruction ()
325+ call .EraseFromParentAsInstruction ()
346326 }
327+ inttoptr .EraseFromParentAsInstruction ()
328+ use .EraseFromParentAsInstruction ()
347329 }
348330
349331 // Replace all typeasserts on interface types with matches on their concrete
0 commit comments