MCPcopy
hub / github.com/tinygo-org/tinygo / createGoroutineStartWrapper

Method createGoroutineStartWrapper

compiler/goroutine.go:289–534  ·  view source on GitHub ↗

createGoroutineStartWrapper creates a wrapper for the task-based implementation of goroutines. For example, to call a function like this: func add(x, y int) int { ... } It creates a wrapper like this: func add$gowrapper(ptr *unsafe.Pointer) { args := (*struct{ x, y int })(ptr

(fnType llvm.Type, fn llvm.Value, prefix string, hasContext, isWasmExport bool, pos token.Pos)

Source from the content-addressed store, hash-verified

287// false, the parameter bundle is assumed to have no context parameter and undef
288// is passed instead.
289func (c *compilerContext) createGoroutineStartWrapper(fnType llvm.Type, fn llvm.Value, prefix string, hasContext, isWasmExport bool, pos token.Pos) llvm.Value {
290 var wrapper llvm.Value
291
292 b := &builder{
293 compilerContext: c,
294 Builder: c.ctx.NewBuilder(),
295 }
296 defer b.Dispose()
297
298 var deadlock llvm.Value
299 var deadlockType llvm.Type
300 if c.Scheduler == "asyncify" {
301 deadlockType, deadlock = c.getFunction(c.program.ImportedPackage("runtime").Members["deadlock"].(*ssa.Function))
302 }
303
304 if !fn.IsAFunction().IsNil() {
305 // See whether this wrapper has already been created. If so, return it.
306 name := fn.Name()
307 wrapperName := name + "$gowrapper"
308 if isWasmExport {
309 wrapperName += "-wasmexport"
310 }
311 wrapper = c.mod.NamedFunction(wrapperName)
312 if !wrapper.IsNil() {
313 return llvm.ConstPtrToInt(wrapper, c.uintptrType)
314 }
315
316 // Create the wrapper.
317 wrapperType := llvm.FunctionType(c.ctx.VoidType(), []llvm.Type{c.dataPtrType}, false)
318 wrapper = llvm.AddFunction(c.mod, wrapperName, wrapperType)
319 c.addStandardAttributes(wrapper)
320 wrapper.SetLinkage(llvm.LinkOnceODRLinkage)
321 wrapper.SetUnnamedAddr(true)
322 wrapper.AddAttributeAtIndex(-1, c.ctx.CreateStringAttribute("tinygo-gowrapper", name))
323 entry := c.ctx.AddBasicBlock(wrapper, "entry")
324 b.SetInsertPointAtEnd(entry)
325
326 if c.Debug {
327 pos := c.program.Fset.Position(pos)
328 diFuncType := c.dibuilder.CreateSubroutineType(llvm.DISubroutineType{
329 File: c.getDIFile(pos.Filename),
330 Parameters: nil, // do not show parameters in debugger
331 Flags: 0, // ?
332 })
333 difunc := c.dibuilder.CreateFunction(c.getDIFile(pos.Filename), llvm.DIFunction{
334 Name: "<goroutine wrapper>",
335 File: c.getDIFile(pos.Filename),
336 Line: pos.Line,
337 Type: diFuncType,
338 LocalToUnit: true,
339 IsDefinition: true,
340 ScopeLine: 0,
341 Flags: llvm.FlagPrototyped,
342 Optimized: true,
343 })
344 wrapper.SetSubprogram(difunc)
345 b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{})
346 }

Callers 2

createGoMethod · 0.80
createWasmExportMethod · 0.80

Calls 8

getFunctionMethod · 0.95
IsNilMethod · 0.95
addStandardAttributesMethod · 0.95
getDIFileMethod · 0.95
emitPointerUnpackMethod · 0.95
createRuntimeCallMethod · 0.95
NameMethod · 0.65
TypeMethod · 0.45

Tested by

no test coverage detected