run runs the pass itself.
()
| 138 | |
| 139 | // run runs the pass itself. |
| 140 | func (p *lowerInterfacesPass) run() error { |
| 141 | if p.dibuilder != nil { |
| 142 | p.dibuilder.CreateCompileUnit(llvm.DICompileUnit{ |
| 143 | Language: 0xb, // DW_LANG_C99 (0xc, off-by-one?) |
| 144 | File: "<unknown>", |
| 145 | Dir: "", |
| 146 | Producer: "TinyGo", |
| 147 | Optimized: true, |
| 148 | }) |
| 149 | } |
| 150 | |
| 151 | // Collect all type codes. |
| 152 | for global := p.mod.FirstGlobal(); !global.IsNil(); global = llvm.NextGlobal(global) { |
| 153 | if strings.HasPrefix(global.Name(), "reflect/types.type:") { |
| 154 | // Retrieve Go type information based on an opaque global variable. |
| 155 | // Only the name of the global is relevant, the object itself is |
| 156 | // discarded afterwards. |
| 157 | name := strings.TrimPrefix(global.Name(), "reflect/types.type:") |
| 158 | if _, ok := p.types[name]; !ok { |
| 159 | t := &typeInfo{ |
| 160 | name: name, |
| 161 | typecode: global, |
| 162 | } |
| 163 | p.types[name] = t |
| 164 | initializer := global.Initializer() |
| 165 | firstField := p.builder.CreateExtractValue(initializer, 0, "") |
| 166 | if firstField.Type() != p.ctx.Int8Type() { |
| 167 | // This type has a method set at index 0. Change the GEP to |
| 168 | // point to index 1 (the meta byte). |
| 169 | t.typecodeGEP = llvm.ConstGEP(global.GlobalValueType(), global, []llvm.Value{ |
| 170 | llvm.ConstInt(p.ctx.Int32Type(), 0, false), |
| 171 | llvm.ConstInt(p.ctx.Int32Type(), 1, false), |
| 172 | }) |
| 173 | methodSet := stripPointerCasts(firstField) |
| 174 | if !strings.HasSuffix(methodSet.Name(), "$methodset") { |
| 175 | panic("expected method set") |
| 176 | } |
| 177 | p.addTypeMethods(t, methodSet) |
| 178 | } else { |
| 179 | // This type has no method set. |
| 180 | t.typecodeGEP = llvm.ConstGEP(global.GlobalValueType(), global, []llvm.Value{ |
| 181 | llvm.ConstInt(p.ctx.Int32Type(), 0, false), |
| 182 | llvm.ConstInt(p.ctx.Int32Type(), 0, false), |
| 183 | }) |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | // Find all interface type asserts and interface method thunks. |
| 190 | var interfaceAssertFunctions []llvm.Value |
| 191 | var interfaceInvokeFunctions []llvm.Value |
| 192 | for fn := p.mod.FirstFunction(); !fn.IsNil(); fn = llvm.NextFunction(fn) { |
| 193 | methodsAttr := fn.GetStringAttributeAtIndex(-1, "tinygo-methods") |
| 194 | if methodsAttr.IsNil() { |
| 195 | continue |
| 196 | } |
| 197 | if !hasUses(fn) { |
no test coverage detected