type pkgReader … func newPkgReader(pr pkgbits.PkgDecoder) *pkgReader { … } type pkgReaderIndex … func (pri pkgReaderIndex) asReader(k pkgbits.RelocKind, marker pkgbits.SyncMarker) *reader { … } func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx index, marker pkgbits.SyncMarker) *reader { … } type reader … type readerDict … type readerMethodExprInfo … func setType(n ir.Node, typ *types.Type) { … } func setValue(name *ir.Name, val constant.Value) { … } // pos reads a position from the bitstream. func (r *reader) pos() src.XPos { … } // origPos reads a position from the bitstream, and returns both the // original raw position and an inlining-adjusted position. func (r *reader) origPos() (origPos, inlPos src.XPos) { … } func (r *reader) pos0() src.Pos { … } // posBase reads a position base from the bitstream. func (r *reader) posBase() *src.PosBase { … } // posBaseIdx returns the specified position base, reading it first if // needed. func (pr *pkgReader) posBaseIdx(idx index) *src.PosBase { … } // inlPosBase returns the inlining-adjusted src.PosBase corresponding // to oldBase, which must be a non-inlined position. When not // inlining, this is just oldBase. func (r *reader) inlPosBase(oldBase *src.PosBase) *src.PosBase { … } // inlPos returns the inlining-adjusted src.XPos corresponding to // xpos, which must be a non-inlined position. When not inlining, this // is just xpos. func (r *reader) inlPos(xpos src.XPos) src.XPos { … } // pkg reads a package reference from the bitstream. func (r *reader) pkg() *types.Pkg { … } // pkgIdx returns the specified package from the export data, reading // it first if needed. func (pr *pkgReader) pkgIdx(idx index) *types.Pkg { … } // doPkg reads a package definition from the bitstream. func (r *reader) doPkg() *types.Pkg { … } func (r *reader) typ() *types.Type { … } // typWrapped is like typ, but allows suppressing generation of // unnecessary wrappers as a compile-time optimization. func (r *reader) typWrapped(wrapped bool) *types.Type { … } func (r *reader) typInfo() typeInfo { … } // typListIdx returns a list of the specified types, resolving derived // types within the given dictionary. func (pr *pkgReader) typListIdx(infos []typeInfo, dict *readerDict) []*types.Type { … } // typIdx returns the specified type. If info specifies a derived // type, it's resolved within the given dictionary. If wrapped is // true, then method wrappers will be generated, if appropriate. func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict, wrapped bool) *types.Type { … } func (r *reader) doTyp() *types.Type { … } func (r *reader) unionType() *types.Type { … } func (r *reader) interfaceType() *types.Type { … } func (r *reader) structType() *types.Type { … } func (r *reader) signature(recv *types.Field) *types.Type { … } func (r *reader) params() []*types.Field { … } func (r *reader) param() *types.Field { … } var objReader … // obj reads an instantiated object reference from the bitstream. func (r *reader) obj() ir.Node { … } // objInfo reads an instantiated object reference from the bitstream // and returns the encoded reference to it, without instantiating it. func (r *reader) objInfo() objInfo { … } // objInstIdx returns the encoded, instantiated object. If shaped is // true, then the shaped variant of the object is returned instead. func (pr *pkgReader) objInstIdx(info objInfo, dict *readerDict, shaped bool) ir.Node { … } // objIdx returns the specified object, instantiated with the given // type arguments, if any. // If shaped is true, then the shaped variant of the object is returned // instead. func (pr *pkgReader) objIdx(idx index, implicits, explicits []*types.Type, shaped bool) ir.Node { … } // objIdxMayFail is equivalent to objIdx, but returns an error rather than // failing the build if this object requires type arguments and the incorrect // number of type arguments were passed. // // Other sources of internal failure (such as duplicate definitions) still fail // the build. func (pr *pkgReader) objIdxMayFail(idx index, implicits, explicits []*types.Type, shaped bool) (ir.Node, error) { … } func (dict *readerDict) mangle(sym *types.Sym) *types.Sym { … } // shapify returns the shape type for targ. // // If basic is true, then the type argument is used to instantiate a // type parameter whose constraint is a basic interface. func shapify(targ *types.Type, basic bool) *types.Type { … } // objDictIdx reads and returns the specified object dictionary. func (pr *pkgReader) objDictIdx(sym *types.Sym, idx index, implicits, explicits []*types.Type, shaped bool) (*readerDict, error) { … } func (r *reader) typeParamNames() { … } func (r *reader) method(rext *reader) *types.Field { … } func (r *reader) qualifiedIdent() (pkg *types.Pkg, sym *types.Sym) { … } func (r *reader) localIdent() *types.Sym { … } func (r *reader) selector() *types.Sym { … } func (r *reader) hasTypeParams() bool { … } func (dict *readerDict) hasTypeParams() bool { … } func (r *reader) funcExt(name *ir.Name, method *types.Sym) { … } func (r *reader) typeExt(name *ir.Name) { … } func (r *reader) varExt(name *ir.Name) { … } func (r *reader) linkname(name *ir.Name) { … } func (r *reader) pragmaFlag() ir.PragmaFlag { … } var bodyReader … var importBodyReader … // bodyReaderFor returns the pkgReaderIndex for reading fn's // serialized IR, and whether one was found. func bodyReaderFor(fn *ir.Func) (pri pkgReaderIndex, ok bool) { … } var todoDicts … var todoBodies … // addBody reads a function body reference from the element bitstream, // and associates it with fn. func (r *reader) addBody(fn *ir.Func, method *types.Sym) { … } func (pri pkgReaderIndex) funcBody(fn *ir.Func) { … } // funcBody reads a function body definition from the element // bitstream, and populates fn with it. func (r *reader) funcBody(fn *ir.Func) { … } // syntheticBody adds a synthetic body to r.curfn if appropriate, and // reports whether it did. func (r *reader) syntheticBody(pos src.XPos) bool { … } // callShaped emits a tail call to r.shapedFn, passing along the // arguments to the current function. func (r *reader) callShaped(pos src.XPos) { … } // syntheticArgs returns the recvs and params arguments passed to the // current function. func (r *reader) syntheticArgs() ir.Nodes { … } // syntheticTailCall emits a tail call to fn, passing the given // arguments list. func (r *reader) syntheticTailCall(pos src.XPos, fn ir.Node, args ir.Nodes) { … } // dictNameOf returns the runtime dictionary corresponding to dict. func (pr *pkgReader) dictNameOf(dict *readerDict) *ir.Name { … } // typeParamMethodExprsOffset returns the offset of the runtime // dictionary's type parameter method expressions section, in words. func (dict *readerDict) typeParamMethodExprsOffset() int { … } // subdictsOffset returns the offset of the runtime dictionary's // subdictionary section, in words. func (dict *readerDict) subdictsOffset() int { … } // rtypesOffset returns the offset of the runtime dictionary's rtypes // section, in words. func (dict *readerDict) rtypesOffset() int { … } // itabsOffset returns the offset of the runtime dictionary's itabs // section, in words. func (dict *readerDict) itabsOffset() int { … } // numWords returns the total number of words that comprise dict's // runtime dictionary variable. func (dict *readerDict) numWords() int64 { … } // varType returns the type of dict's runtime dictionary variable. func (dict *readerDict) varType() *types.Type { … } func (r *reader) declareParams() { … } func (r *reader) addLocal(name *ir.Name) { … } func (r *reader) useLocal() *ir.Name { … } func (r *reader) openScope() { … } func (r *reader) closeScope() { … } // closeAnotherScope is like closeScope, but it reuses the same mark // position as the last closeScope call. This is useful for "for" and // "if" statements, as their implicit blocks always end at the same // position as an explicit block. func (r *reader) closeAnotherScope() { … } func (r *reader) stmt() ir.Node { … } func block(stmts []ir.Node) ir.Node { … } func (r *reader) stmts() ir.Nodes { … } func (r *reader) stmt1(tag codeStmt, out *ir.Nodes) ir.Node { … } func (r *reader) assignList() ([]*ir.Name, []ir.Node) { … } // assign returns an assignee expression. It also reports whether the // returned expression is a newly declared variable. func (r *reader) assign() (ir.Node, bool) { … } func (r *reader) blockStmt() []ir.Node { … } func (r *reader) forStmt(label *types.Sym) ir.Node { … } func (r *reader) ifStmt() ir.Node { … } func (r *reader) selectStmt(label *types.Sym) ir.Node { … } func (r *reader) switchStmt(label *types.Sym) ir.Node { … } func (r *reader) label() *types.Sym { … } func (r *reader) optLabel() *types.Sym { … } // initDefn marks the given names as declared by defn and populates // its Init field with ODCL nodes. It then reports whether any names // were so declared, which can be used to initialize defn.Def. func (r *reader) initDefn(defn ir.InitNode, names []*ir.Name) bool { … } // expr reads and returns a typechecked expression. func (r *reader) expr() (res ir.Node) { … } // funcInst reads an instantiated function reference, and returns // three (possibly nil) expressions related to it: // // baseFn is always non-nil: it's either a function of the appropriate // type already, or it has an extra dictionary parameter as the first // parameter. // // If dictPtr is non-nil, then it's a dictionary argument that must be // passed as the first argument to baseFn. // // If wrapperFn is non-nil, then it's either the same as baseFn (if // dictPtr is nil), or it's semantically equivalent to currying baseFn // to pass dictPtr. (wrapperFn is nil when dictPtr is an expression // that needs to be computed dynamically.) // // For callers that are creating a call to the returned function, it's // best to emit a call to baseFn, and include dictPtr in the arguments // list as appropriate. // // For callers that want to return the function without invoking it, // they may return wrapperFn if it's non-nil; but otherwise, they need // to create their own wrapper. func (r *reader) funcInst(pos src.XPos) (wrapperFn, baseFn, dictPtr ir.Node) { … } func (pr *pkgReader) objDictName(idx index, implicits, explicits []*types.Type) *ir.Name { … } // curry returns a function literal that calls fun with arg0 and // (optionally) arg1, accepting additional arguments to the function // literal as necessary to satisfy fun's signature. // // If nilCheck is true and arg0 is an interface value, then it's // checked to be non-nil as an initial step at the point of evaluating // the function literal itself. func (r *reader) curry(origPos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.Node) ir.Node { … } // methodExprWrap returns a function literal that changes method's // first parameter's type to recv, and uses implicits/deref/addr to // select the appropriate receiver parameter to pass to method. func (r *reader) methodExprWrap(origPos src.XPos, recv *types.Type, implicits []int, deref, addr bool, method, dictPtr ir.Node) ir.Node { … } // syntheticClosure constructs a synthetic function literal for // currying dictionary arguments. origPos is the position used for the // closure, which must be a non-inlined position. typ is the function // literal's signature type. // // captures is a list of expressions that need to be evaluated at the // point of function literal evaluation and captured by the function // literal. If ifaceHack is true and captures[1] is an interface type, // it's checked to be non-nil after evaluation. // // addBody is a callback function to populate the function body. The // list of captured values passed back has the captured variables for // use within the function literal, corresponding to the expressions // in captures. func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack bool, captures ir.Nodes, addBody func(pos src.XPos, r *reader, captured []ir.Node)) ir.Node { … } // syntheticSig duplicates and returns the params and results lists // for sig, but renaming anonymous parameters so they can be assigned // ir.Names. func syntheticSig(sig *types.Type) (params, results []*types.Field) { … } func (r *reader) optExpr() ir.Node { … } // methodExpr reads a method expression reference, and returns three // (possibly nil) expressions related to it: // // baseFn is always non-nil: it's either a function of the appropriate // type already, or it has an extra dictionary parameter as the second // parameter (i.e., immediately after the promoted receiver // parameter). // // If dictPtr is non-nil, then it's a dictionary argument that must be // passed as the second argument to baseFn. // // If wrapperFn is non-nil, then it's either the same as baseFn (if // dictPtr is nil), or it's semantically equivalent to currying baseFn // to pass dictPtr. (wrapperFn is nil when dictPtr is an expression // that needs to be computed dynamically.) // // For callers that are creating a call to the returned method, it's // best to emit a call to baseFn, and include dictPtr in the arguments // list as appropriate. // // For callers that want to return a method expression without // invoking it, they may return wrapperFn if it's non-nil; but // otherwise, they need to create their own wrapper. func (r *reader) methodExpr() (wrapperFn, baseFn, dictPtr ir.Node) { … } // shapedMethodExpr returns the specified method on the given shaped // type. func shapedMethodExpr(pos src.XPos, obj *ir.Name, sym *types.Sym) *ir.SelectorExpr { … } func (r *reader) multiExpr() []ir.Node { … } // temp returns a new autotemp of the specified type. func (r *reader) temp(pos src.XPos, typ *types.Type) *ir.Name { … } // tempCopy declares and returns a new autotemp initialized to the // value of expr. func (r *reader) tempCopy(pos src.XPos, expr ir.Node, init *ir.Nodes) *ir.Name { … } func (r *reader) compLit() ir.Node { … } func (r *reader) funcLit() ir.Node { … } // inlClosureFunc constructs a new closure function, but correctly // handles inlining. func (r *reader) inlClosureFunc(origPos src.XPos, sig *types.Type, why ir.Op) *ir.Func { … } func (r *reader) exprList() []ir.Node { … } func (r *reader) exprs() []ir.Node { … } // dictWord returns an expression to return the specified // uintptr-typed word from the dictionary parameter. func (r *reader) dictWord(pos src.XPos, idx int) ir.Node { … } // rttiWord is like dictWord, but converts it to *byte (the type used // internally to represent *runtime._type and *runtime.itab). func (r *reader) rttiWord(pos src.XPos, idx int) ir.Node { … } // rtype reads a type reference from the element bitstream, and // returns an expression of type *runtime._type representing that // type. func (r *reader) rtype(pos src.XPos) ir.Node { … } func (r *reader) rtype0(pos src.XPos) (typ *types.Type, rtype ir.Node) { … } // varDictIndex populates name.DictIndex if name is a derived type. func (r *reader) varDictIndex(name *ir.Name) { … } // itab returns a (typ, iface) pair of types. // // typRType and ifaceRType are expressions that evaluate to the // *runtime._type for typ and iface, respectively. // // If typ is a concrete type and iface is a non-empty interface type, // then itab is an expression that evaluates to the *runtime.itab for // the pair. Otherwise, itab is nil. func (r *reader) itab(pos src.XPos) (typ *types.Type, typRType ir.Node, iface *types.Type, ifaceRType ir.Node, itab ir.Node) { … } // convRTTI returns expressions appropriate for populating an // ir.ConvExpr's TypeWord and SrcRType fields, respectively. func (r *reader) convRTTI(pos src.XPos) (typeWord, srcRType ir.Node) { … } func (r *reader) exprType() ir.Node { … } func (r *reader) op() ir.Op { … } func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) { … } // pkgInitOrder creates a synthetic init function to handle any // package-scope initialization statements. func (r *reader) pkgInitOrder(target *ir.Package) { … } func (r *reader) pkgDecls(target *ir.Package) { … } func (r *reader) pkgObjs(target *ir.Package) []*ir.Name { … } // unifiedHaveInlineBody reports whether we have the function body for // fn, so we can inline it. func unifiedHaveInlineBody(fn *ir.Func) bool { … } var inlgen … // unifiedInlineCall implements inline.NewInline by re-reading the function // body from its Unified IR export data. func unifiedInlineCall(callerfn *ir.Func, call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr { … } // inlReturn returns a statement that can substitute for the given // return statement when inlining. func (r *reader) inlReturn(ret *ir.ReturnStmt, retvars []*ir.Name) *ir.BlockStmt { … } // expandInline reads in an extra copy of IR to populate // fn.Inl.Dcl. func expandInline(fn *ir.Func, pri pkgReaderIndex) { … } // usedLocals returns a set of local variables that are used within body. func usedLocals(body []ir.Node) ir.NameSet { … } var needWrapperTypes … var haveWrapperTypes … var needMethodValueWrappers … var haveMethodValueWrappers … type methodValueWrapper … // needWrapper records that wrapper methods may be needed at link // time. func (r *reader) needWrapper(typ *types.Type) { … } // importedDef reports whether r is reading from an imported and // non-generic element. // // If a type was found in an imported package, then we can assume that // package (or one of its transitive dependencies) already generated // method wrappers for it. // // Exception: If we're instantiating an imported generic type or // function, we might be instantiating it with type arguments not // previously seen before. // // TODO(mdempsky): Distinguish when a generic function or type was // instantiated in an imported package so that we can add types to // haveWrapperTypes instead. func (r *reader) importedDef() bool { … } // MakeWrappers constructs all wrapper methods needed for the target // compilation unit. func MakeWrappers(target *ir.Package) { … } func wrapType(typ *types.Type, target *ir.Package, seen map[string]*types.Type, needed bool) { … } func methodWrapper(derefs int, tbase *types.Type, method *types.Field, target *ir.Package) { … } func wrapMethodValue(recvType *types.Type, method *types.Field, target *ir.Package, needed bool) { … } func newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func { … } func finishWrapperFunc(fn *ir.Func, target *ir.Package) { … } // newWrapperType returns a copy of the given signature type, but with // the receiver parameter type substituted with recvType. // If recvType is nil, newWrapperType returns a signature // without a receiver parameter. func newWrapperType(recvType *types.Type, method *types.Field) *types.Type { … } func addTailCall(pos src.XPos, fn *ir.Func, recv ir.Node, method *types.Field) { … } func setBasePos(pos src.XPos) { … } const dictParamName … // shapeSig returns a copy of fn's signature, except adding a // dictionary parameter and promoting the receiver parameter (if any) // to a normal parameter. // // The parameter types.Fields are all copied too, so their Nname // fields can be initialized for use by the shape function. func shapeSig(fn *ir.Func, dict *readerDict) *types.Type { … }