// emitAlloc emits to f a new Alloc instruction allocating a variable // of type typ. // // The caller must set Alloc.Heap=true (for an heap-allocated variable) // or add the Alloc to f.Locals (for a frame-allocated variable). // // During building, a variable in f.Locals may have its Heap flag // set when it is discovered that its address is taken. // These Allocs are removed from f.Locals at the end. // // The builder should generally call one of the emit{New,Local,LocalVar} wrappers instead. func emitAlloc(f *Function, typ types.Type, pos token.Pos, comment string) *Alloc { … } // emitNew emits to f a new Alloc instruction heap-allocating a // variable of type typ. pos is the optional source location. func emitNew(f *Function, typ types.Type, pos token.Pos, comment string) *Alloc { … } // emitLocal creates a local var for (t, pos, comment) and // emits an Alloc instruction for it. // // (Use this function or emitNew for synthetic variables; // for source-level variables in the same function, use emitLocalVar.) func emitLocal(f *Function, t types.Type, pos token.Pos, comment string) *Alloc { … } // emitLocalVar creates a local var for v and emits an Alloc instruction for it. // Subsequent calls to f.lookup(v) return it. // It applies the appropriate generic instantiation to the type. func emitLocalVar(f *Function, v *types.Var) *Alloc { … } // emitLoad emits to f an instruction to load the address addr into a // new temporary, and returns the value so defined. func emitLoad(f *Function, addr Value) *UnOp { … } // emitDebugRef emits to f a DebugRef pseudo-instruction associating // expression e with value v. func emitDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) { … } // emitArith emits to f code to compute the binary operation op(x, y) // where op is an eager shift, logical or arithmetic operation. // (Use emitCompare() for comparisons and Builder.logicalBinop() for // non-eager operations.) func emitArith(f *Function, op token.Token, x, y Value, t types.Type, pos token.Pos) Value { … } // emitCompare emits to f code compute the boolean result of // comparison 'x op y'. func emitCompare(f *Function, op token.Token, x, y Value, pos token.Pos) Value { … } // isValuePreserving returns true if a conversion from ut_src to // ut_dst is value-preserving, i.e. just a change of type. // Precondition: neither argument is a named or alias type. func isValuePreserving(ut_src, ut_dst types.Type) bool { … } // emitConv emits to f code to convert Value val to exactly type typ, // and returns the converted value. Implicit conversions are required // by language assignability rules in assignments, parameter passing, // etc. func emitConv(f *Function, val Value, typ types.Type) Value { … } // emitTypeCoercion emits to f code to coerce the type of a // Value v to exactly type typ, and returns the coerced value. // // Requires that coercing v.Typ() to typ is a value preserving change. // // Currently used only when v.Type() is a type instance of typ or vice versa. // A type v is a type instance of a type t if there exists a // type parameter substitution σ s.t. σ(v) == t. Example: // // σ(func(T) T) == func(int) int for σ == [T ↦ int] // // This happens in instantiation wrappers for conversion // from an instantiation to a parameterized type (and vice versa) // with σ substituting f.typeparams by f.typeargs. func emitTypeCoercion(f *Function, v Value, typ types.Type) Value { … } // emitStore emits to f an instruction to store value val at location // addr, applying implicit conversions as required by assignability rules. func emitStore(f *Function, addr, val Value, pos token.Pos) *Store { … } // emitJump emits to f a jump to target, and updates the control-flow graph. // Postcondition: f.currentBlock is nil. func emitJump(f *Function, target *BasicBlock) { … } // emitIf emits to f a conditional jump to tblock or fblock based on // cond, and updates the control-flow graph. // Postcondition: f.currentBlock is nil. func emitIf(f *Function, cond Value, tblock, fblock *BasicBlock) { … } // emitExtract emits to f an instruction to extract the index'th // component of tuple. It returns the extracted value. func emitExtract(f *Function, tuple Value, index int) Value { … } // emitTypeAssert emits to f a type assertion value := x.(t) and // returns the value. x.Type() must be an interface. func emitTypeAssert(f *Function, x Value, t types.Type, pos token.Pos) Value { … } // emitTypeTest emits to f a type test value,ok := x.(t) and returns // a (value, ok) tuple. x.Type() must be an interface. func emitTypeTest(f *Function, x Value, t types.Type, pos token.Pos) Value { … } // emitTailCall emits to f a function call in tail position. The // caller is responsible for all fields of 'call' except its type. // Intended for wrapper methods. // Precondition: f does/will not use deferred procedure calls. // Postcondition: f.currentBlock is nil. func emitTailCall(f *Function, call *Call) { … } // emitImplicitSelections emits to f code to apply the sequence of // implicit field selections specified by indices to base value v, and // returns the selected value. // // If v is the address of a struct, the result will be the address of // a field; if it is the value of a struct, the result will be the // value of a field. func emitImplicitSelections(f *Function, v Value, indices []int, pos token.Pos) Value { … } // emitFieldSelection emits to f code to select the index'th field of v. // // If wantAddr, the input must be a pointer-to-struct and the result // will be the field's address; otherwise the result will be the // field's value. // Ident id is used for position and debug info. func emitFieldSelection(f *Function, v Value, index int, wantAddr bool, id *ast.Ident) Value { … } // createRecoverBlock emits to f a block of code to return after a // recovered panic, and sets f.Recover to it. // // If f's result parameters are named, the code loads and returns // their current values, otherwise it returns the zero values of their // type. // // Idempotent. func createRecoverBlock(f *Function) { … }