Static Definition and Initialization

  • Code Path: src/runtime/iface.go

In proc.go, itabsinit will init the itabTable with the current activeModules information. The itabsinit function will read the itablinks from each module and add them to the global hash table.

During the runtime, the getitab function will also build more items dynamically and fill the hash table accordingly.

itablinks was produced for each module during the linking stage, and contains an array of itab. itab is generated by writeITab function (code path: cmd/compile/internal/reflectdata/reflect.go), used to store the type link between a concrete type (_type field) implementing an interface (inter field). If _type doesn’t implement inter, fun will be empty; else it will save the methods of _type implementing inter (not all methods of _type).

Runtime Type Assertion

  • Code Path: src/cmd/compile/internal/ssagen/ssa.go

A type assertion is something like y = x.(T), it’s executed during runtime instead of compiling stage (e.g. generics). The SSA module will generate the code with dottype function.

Interface Type Conversion

  • Code Path: src/cmd/compile/internal/walk/convert.go

Interface-to-interface conversion is done during IR walking, walkConvInterface will check the types of source and destination types, and only an interface-to-interface conversion needs a runtime call to convI2I.

Concrete type to interface conversion is done by walkConvIData. It will use dataWordFuncName to check the correct conversion implementation defined in iface.go.

Runtime Interface Method Call

  • Code Path: src/cmd/compile/internal/walk/expr.go

An interface call (x.A()) will be walked by walkCall. Note that ir.ODOTINTER are ir.OCALLINTER the same for an interface, because interfaces don’t have any fields so they’ll always be method calls.