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

Method createGo

compiler/goroutine.go:16–123  ·  view source on GitHub ↗

createGo emits code to start a new goroutine.

(instr *ssa.Go)

Source from the content-addressed store, hash-verified

14
15// createGo emits code to start a new goroutine.
16func (b *builder) createGo(instr *ssa.Go) {
17 if builtin, ok := instr.Call.Value.(*ssa.Builtin); ok {
18 // We cheat. None of the builtins do any long or blocking operation, so
19 // we might as well run these builtins right away without the program
20 // noticing the difference.
21 // Possible exceptions:
22 // - copy: this is a possibly long operation, but not a blocking
23 // operation. Semantically it makes no difference to run it right
24 // away (not in a goroutine). However, in practice it makes no sense
25 // to run copy in a goroutine as there is no way to (safely) know
26 // when it is finished.
27 // - panic: the error message would appear in the parent goroutine.
28 // But because `go panic("err")` would halt the program anyway
29 // (there is no recover), panicking right away would give the same
30 // behavior as creating a goroutine, switching the scheduler to that
31 // goroutine, and panicking there. So this optimization seems
32 // correct.
33 // - recover: because it runs in a new goroutine, it is never a
34 // deferred function. Thus this is a no-op.
35 if builtin.Name() == "recover" {
36 // This is a no-op, even in a deferred function:
37 // go recover()
38 return
39 }
40 var argTypes []types.Type
41 var argValues []llvm.Value
42 for _, arg := range instr.Call.Args {
43 argTypes = append(argTypes, arg.Type())
44 argValues = append(argValues, b.getValue(arg, getPos(instr)))
45 }
46 b.createBuiltin(argTypes, argValues, builtin.Name(), instr.Pos())
47 return
48 }
49
50 // Get all function parameters to pass to the goroutine.
51 var params []llvm.Value
52 for _, param := range instr.Call.Args {
53 params = append(params, b.expandFormalParam(b.getValue(param, getPos(instr)))...)
54 }
55
56 var prefix string
57 var funcPtr llvm.Value
58 var funcType llvm.Type
59 hasContext := false
60 if callee := instr.Call.StaticCallee(); callee != nil {
61 // Static callee is known. This makes it easier to start a new
62 // goroutine.
63 var context llvm.Value
64 switch value := instr.Call.Value.(type) {
65 case *ssa.Function:
66 // Goroutine call is regular function call. No context is necessary.
67 case *ssa.MakeClosure:
68 // A goroutine call on a func value, but the callee is trivial to find. For
69 // example: immediately applied functions.
70 funcValue := b.getValue(value, getPos(instr))
71 context = b.extractFuncContext(funcValue)
72 default:
73 panic("StaticCallee returned an unexpected value")

Callers 1

createInstructionMethod · 0.95

Calls 15

getValueMethod · 0.95
createBuiltinMethod · 0.95
expandFormalParamMethod · 0.95
extractFuncContextMethod · 0.95
IsNilMethod · 0.95
decodeFuncValueMethod · 0.95
emitPointerPackMethod · 0.95
createCallMethod · 0.95
getInvokeFunctionMethod · 0.80
getLLVMFunctionTypeMethod · 0.80
getPosFunction · 0.70

Tested by

no test coverage detected