mirror of
https://github.com/golang/go.git
synced 2025-11-09 21:21:03 +00:00
[dev.regabi] cmd/compile: add ir.Closure, ir.ClosureRead
Closures are another reference to Funcs, and it cleans up the code quite a bit to be clear about types. OCLOSUREVAR is renamed to OCLOSUREREAD to make clearer that it is unrelated to the list Func.ClosureVars. Passes buildall w/ toolstash -cmp. Change-Id: Id0d28df2d4d6e9954e34df7a39ea226995eee937 Reviewed-on: https://go-review.googlesource.com/c/go/+/274098 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
e84b27bec5
commit
4eaef981b5
11 changed files with 82 additions and 51 deletions
|
|
@ -23,8 +23,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
|
||||||
fn.Nname.Ntype = xtype
|
fn.Nname.Ntype = xtype
|
||||||
fn.Nname.Defn = fn
|
fn.Nname.Defn = fn
|
||||||
|
|
||||||
clo := p.nod(expr, ir.OCLOSURE, nil, nil)
|
clo := ir.NewClosureExpr(p.pos(expr), fn)
|
||||||
clo.SetFunc(fn)
|
|
||||||
fn.ClosureType = ntype
|
fn.ClosureType = ntype
|
||||||
fn.OClosure = clo
|
fn.OClosure = clo
|
||||||
|
|
||||||
|
|
@ -285,21 +284,19 @@ func transformclosure(fn *ir.Func) {
|
||||||
offset := int64(Widthptr)
|
offset := int64(Widthptr)
|
||||||
for _, v := range fn.ClosureVars {
|
for _, v := range fn.ClosureVars {
|
||||||
// cv refers to the field inside of closure OSTRUCTLIT.
|
// cv refers to the field inside of closure OSTRUCTLIT.
|
||||||
cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
|
typ := v.Type()
|
||||||
|
|
||||||
cv.SetType(v.Type())
|
|
||||||
if !v.Byval() {
|
if !v.Byval() {
|
||||||
cv.SetType(types.NewPtr(v.Type()))
|
typ = types.NewPtr(typ)
|
||||||
}
|
}
|
||||||
offset = Rnd(offset, int64(cv.Type().Align))
|
offset = Rnd(offset, int64(typ.Align))
|
||||||
cv.SetOffset(offset)
|
cr := ir.NewClosureRead(typ, offset)
|
||||||
offset += cv.Type().Width
|
offset += typ.Width
|
||||||
|
|
||||||
if v.Byval() && v.Type().Width <= int64(2*Widthptr) {
|
if v.Byval() && v.Type().Width <= int64(2*Widthptr) {
|
||||||
// If it is a small variable captured by value, downgrade it to PAUTO.
|
// If it is a small variable captured by value, downgrade it to PAUTO.
|
||||||
v.SetClass(ir.PAUTO)
|
v.SetClass(ir.PAUTO)
|
||||||
fn.Dcl = append(fn.Dcl, v)
|
fn.Dcl = append(fn.Dcl, v)
|
||||||
body = append(body, ir.Nod(ir.OAS, v, cv))
|
body = append(body, ir.Nod(ir.OAS, v, cr))
|
||||||
} else {
|
} else {
|
||||||
// Declare variable holding addresses taken from closure
|
// Declare variable holding addresses taken from closure
|
||||||
// and initialize in entry prologue.
|
// and initialize in entry prologue.
|
||||||
|
|
@ -310,10 +307,11 @@ func transformclosure(fn *ir.Func) {
|
||||||
addr.Curfn = fn
|
addr.Curfn = fn
|
||||||
fn.Dcl = append(fn.Dcl, addr)
|
fn.Dcl = append(fn.Dcl, addr)
|
||||||
v.Heapaddr = addr
|
v.Heapaddr = addr
|
||||||
|
var src ir.Node = cr
|
||||||
if v.Byval() {
|
if v.Byval() {
|
||||||
cv = ir.Nod(ir.OADDR, cv, nil)
|
src = ir.Nod(ir.OADDR, cr, nil)
|
||||||
}
|
}
|
||||||
body = append(body, ir.Nod(ir.OAS, addr, cv))
|
body = append(body, ir.Nod(ir.OAS, addr, src))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -473,21 +471,17 @@ func makepartialcall(dot ir.Node, t0 *types.Type, meth *types.Sym) *ir.Func {
|
||||||
tfn.Type().SetPkg(t0.Pkg())
|
tfn.Type().SetPkg(t0.Pkg())
|
||||||
|
|
||||||
// Declare and initialize variable holding receiver.
|
// Declare and initialize variable holding receiver.
|
||||||
|
cr := ir.NewClosureRead(rcvrtype, Rnd(int64(Widthptr), int64(rcvrtype.Align)))
|
||||||
cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
|
|
||||||
cv.SetType(rcvrtype)
|
|
||||||
cv.SetOffset(Rnd(int64(Widthptr), int64(cv.Type().Align)))
|
|
||||||
|
|
||||||
ptr := NewName(lookup(".this"))
|
ptr := NewName(lookup(".this"))
|
||||||
declare(ptr, ir.PAUTO)
|
declare(ptr, ir.PAUTO)
|
||||||
ptr.SetUsed(true)
|
ptr.SetUsed(true)
|
||||||
var body []ir.Node
|
var body []ir.Node
|
||||||
if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
|
if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
|
||||||
ptr.SetType(rcvrtype)
|
ptr.SetType(rcvrtype)
|
||||||
body = append(body, ir.Nod(ir.OAS, ptr, cv))
|
body = append(body, ir.Nod(ir.OAS, ptr, cr))
|
||||||
} else {
|
} else {
|
||||||
ptr.SetType(types.NewPtr(rcvrtype))
|
ptr.SetType(types.NewPtr(rcvrtype))
|
||||||
body = append(body, ir.Nod(ir.OAS, ptr, ir.Nod(ir.OADDR, cv, nil)))
|
body = append(body, ir.Nod(ir.OAS, ptr, ir.Nod(ir.OADDR, cr, nil)))
|
||||||
}
|
}
|
||||||
|
|
||||||
call := ir.Nod(ir.OCALL, nodSym(ir.OXDOT, ptr, meth), nil)
|
call := ir.Nod(ir.OCALL, nodSym(ir.OXDOT, ptr, meth), nil)
|
||||||
|
|
|
||||||
|
|
@ -486,7 +486,7 @@ func (e *Escape) exprSkipInit(k EscHole, n ir.Node) {
|
||||||
default:
|
default:
|
||||||
base.Fatalf("unexpected expr: %v", n)
|
base.Fatalf("unexpected expr: %v", n)
|
||||||
|
|
||||||
case ir.OLITERAL, ir.ONIL, ir.OGETG, ir.OCLOSUREVAR, ir.OTYPE, ir.OMETHEXPR:
|
case ir.OLITERAL, ir.ONIL, ir.OGETG, ir.OCLOSUREREAD, ir.OTYPE, ir.OMETHEXPR:
|
||||||
// nop
|
// nop
|
||||||
|
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
|
|
@ -1718,7 +1718,7 @@ func mayAffectMemory(n ir.Node) bool {
|
||||||
// We're ignoring things like division by zero, index out of range,
|
// We're ignoring things like division by zero, index out of range,
|
||||||
// and nil pointer dereference here.
|
// and nil pointer dereference here.
|
||||||
switch n.Op() {
|
switch n.Op() {
|
||||||
case ir.ONAME, ir.OCLOSUREVAR, ir.OLITERAL, ir.ONIL:
|
case ir.ONAME, ir.OCLOSUREREAD, ir.OLITERAL, ir.ONIL:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
// Left+Right group.
|
// Left+Right group.
|
||||||
|
|
|
||||||
|
|
@ -963,7 +963,7 @@ func mkinlcall(n ir.Node, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool)
|
||||||
|
|
||||||
// Handle captured variables when inlining closures.
|
// Handle captured variables when inlining closures.
|
||||||
if c := fn.OClosure; c != nil {
|
if c := fn.OClosure; c != nil {
|
||||||
for _, v := range c.Func().ClosureVars {
|
for _, v := range fn.ClosureVars {
|
||||||
if v.Op() == ir.OXXX {
|
if v.Op() == ir.OXXX {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -973,7 +973,7 @@ func mkinlcall(n ir.Node, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool)
|
||||||
// NB: if we enabled inlining of functions containing OCLOSURE or refined
|
// NB: if we enabled inlining of functions containing OCLOSURE or refined
|
||||||
// the reassigned check via some sort of copy propagation this would most
|
// the reassigned check via some sort of copy propagation this would most
|
||||||
// likely need to be changed to a loop to walk up to the correct Param
|
// likely need to be changed to a loop to walk up to the correct Param
|
||||||
if o == nil || (o.Curfn != Curfn && o.Curfn.OClosure != Curfn) {
|
if o == nil || o.Curfn != Curfn {
|
||||||
base.Fatalf("%v: unresolvable capture %v %v\n", ir.Line(n), fn, v)
|
base.Fatalf("%v: unresolvable capture %v %v\n", ir.Line(n), fn, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2025,7 +2025,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
|
||||||
}
|
}
|
||||||
addr := s.addr(n)
|
addr := s.addr(n)
|
||||||
return s.load(n.Type(), addr)
|
return s.load(n.Type(), addr)
|
||||||
case ir.OCLOSUREVAR:
|
case ir.OCLOSUREREAD:
|
||||||
addr := s.addr(n)
|
addr := s.addr(n)
|
||||||
return s.load(n.Type(), addr)
|
return s.load(n.Type(), addr)
|
||||||
case ir.ONIL:
|
case ir.ONIL:
|
||||||
|
|
@ -4895,7 +4895,7 @@ func (s *state) addr(n ir.Node) *ssa.Value {
|
||||||
case ir.ODOTPTR:
|
case ir.ODOTPTR:
|
||||||
p := s.exprPtr(n.Left(), n.Bounded(), n.Pos())
|
p := s.exprPtr(n.Left(), n.Bounded(), n.Pos())
|
||||||
return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p)
|
return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p)
|
||||||
case ir.OCLOSUREVAR:
|
case ir.OCLOSUREREAD:
|
||||||
return s.newValue1I(ssa.OpOffPtr, t, n.Offset(),
|
return s.newValue1I(ssa.OpOffPtr, t, n.Offset(),
|
||||||
s.entryNewValue0(ssa.OpGetClosurePtr, s.f.Config.Types.BytePtr))
|
s.entryNewValue0(ssa.OpGetClosurePtr, s.f.Config.Types.BytePtr))
|
||||||
case ir.OCONVNOP:
|
case ir.OCONVNOP:
|
||||||
|
|
|
||||||
|
|
@ -1948,7 +1948,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
|
||||||
n.SetType(types.NewPtr(t.Elem()))
|
n.SetType(types.NewPtr(t.Elem()))
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCLOSUREVAR:
|
case ir.OCLOSUREREAD:
|
||||||
ok |= ctxExpr
|
ok |= ctxExpr
|
||||||
|
|
||||||
case ir.OCFUNC:
|
case ir.OCFUNC:
|
||||||
|
|
@ -3099,7 +3099,7 @@ func islvalue(n ir.Node) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case ir.ODEREF, ir.ODOTPTR, ir.OCLOSUREVAR:
|
case ir.ODEREF, ir.ODOTPTR, ir.OCLOSUREREAD:
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case ir.ODOT:
|
case ir.ODOT:
|
||||||
|
|
@ -3186,7 +3186,7 @@ func samesafeexpr(l ir.Node, r ir.Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch l.Op() {
|
switch l.Op() {
|
||||||
case ir.ONAME, ir.OCLOSUREVAR:
|
case ir.ONAME, ir.OCLOSUREREAD:
|
||||||
return l == r
|
return l == r
|
||||||
|
|
||||||
case ir.ODOT, ir.ODOTPTR:
|
case ir.ODOT, ir.ODOTPTR:
|
||||||
|
|
|
||||||
|
|
@ -555,7 +555,7 @@ opswitch:
|
||||||
case ir.ORECOVER:
|
case ir.ORECOVER:
|
||||||
n = mkcall("gorecover", n.Type(), init, ir.Nod(ir.OADDR, nodfp, nil))
|
n = mkcall("gorecover", n.Type(), init, ir.Nod(ir.OADDR, nodfp, nil))
|
||||||
|
|
||||||
case ir.OCLOSUREVAR, ir.OCFUNC:
|
case ir.OCLOSUREREAD, ir.OCFUNC:
|
||||||
|
|
||||||
case ir.OCALLINTER, ir.OCALLFUNC, ir.OCALLMETH:
|
case ir.OCALLINTER, ir.OCALLFUNC, ir.OCALLMETH:
|
||||||
if n.Op() == ir.OCALLINTER {
|
if n.Op() == ir.OCALLINTER {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ package ir
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
|
"cmd/internal/src"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A miniStmt is a miniNode with extra fields common to expressions.
|
// A miniStmt is a miniNode with extra fields common to expressions.
|
||||||
|
|
@ -45,3 +47,40 @@ func (n *miniExpr) SetBounded(b bool) { n.flags.set(miniExprBounded, b) }
|
||||||
func (n *miniExpr) Init() Nodes { return n.init }
|
func (n *miniExpr) Init() Nodes { return n.init }
|
||||||
func (n *miniExpr) PtrInit() *Nodes { return &n.init }
|
func (n *miniExpr) PtrInit() *Nodes { return &n.init }
|
||||||
func (n *miniExpr) SetInit(x Nodes) { n.init = x }
|
func (n *miniExpr) SetInit(x Nodes) { n.init = x }
|
||||||
|
|
||||||
|
// A ClosureExpr is a function literal expression.
|
||||||
|
type ClosureExpr struct {
|
||||||
|
miniExpr
|
||||||
|
fn *Func
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClosureExpr(pos src.XPos, fn *Func) *ClosureExpr {
|
||||||
|
n := &ClosureExpr{fn: fn}
|
||||||
|
n.op = OCLOSURE
|
||||||
|
n.pos = pos
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *ClosureExpr) String() string { return fmt.Sprint(n) }
|
||||||
|
func (n *ClosureExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||||
|
func (n *ClosureExpr) RawCopy() Node { c := *n; return &c }
|
||||||
|
func (n *ClosureExpr) Func() *Func { return n.fn }
|
||||||
|
|
||||||
|
// A ClosureRead denotes reading a variable stored within a closure struct.
|
||||||
|
type ClosureRead struct {
|
||||||
|
miniExpr
|
||||||
|
offset int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClosureRead(typ *types.Type, offset int64) *ClosureRead {
|
||||||
|
n := &ClosureRead{offset: offset}
|
||||||
|
n.typ = typ
|
||||||
|
n.op = OCLOSUREREAD
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *ClosureRead) String() string { return fmt.Sprint(n) }
|
||||||
|
func (n *ClosureRead) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||||
|
func (n *ClosureRead) RawCopy() Node { c := *n; return &c }
|
||||||
|
func (n *ClosureRead) Type() *types.Type { return n.typ }
|
||||||
|
func (n *ClosureRead) Offset() int64 { return n.offset }
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,8 @@ type Func struct {
|
||||||
body Nodes
|
body Nodes
|
||||||
iota int64
|
iota int64
|
||||||
|
|
||||||
Nname *Name // ONAME node
|
Nname *Name // ONAME node
|
||||||
OClosure Node // OCLOSURE node
|
OClosure *ClosureExpr // OCLOSURE node
|
||||||
|
|
||||||
Shortname *types.Sym
|
Shortname *types.Sym
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -601,20 +601,20 @@ const (
|
||||||
OTARRAY // []int, [8]int, [N]int or [...]int
|
OTARRAY // []int, [8]int, [N]int or [...]int
|
||||||
|
|
||||||
// misc
|
// misc
|
||||||
ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
|
ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
|
||||||
OINLCALL // intermediary representation of an inlined call.
|
OINLCALL // intermediary representation of an inlined call.
|
||||||
OEFACE // itable and data words of an empty-interface value.
|
OEFACE // itable and data words of an empty-interface value.
|
||||||
OITAB // itable word of an interface value.
|
OITAB // itable word of an interface value.
|
||||||
OIDATA // data word of an interface value in Left
|
OIDATA // data word of an interface value in Left
|
||||||
OSPTR // base pointer of a slice or string.
|
OSPTR // base pointer of a slice or string.
|
||||||
OCLOSUREVAR // variable reference at beginning of closure function
|
OCLOSUREREAD // read from inside closure struct at beginning of closure function
|
||||||
OCFUNC // reference to c function pointer (not go func value)
|
OCFUNC // reference to c function pointer (not go func value)
|
||||||
OCHECKNIL // emit code to ensure pointer/interface not nil
|
OCHECKNIL // emit code to ensure pointer/interface not nil
|
||||||
OVARDEF // variable is about to be fully initialized
|
OVARDEF // variable is about to be fully initialized
|
||||||
OVARKILL // variable is dead
|
OVARKILL // variable is dead
|
||||||
OVARLIVE // variable is alive
|
OVARLIVE // variable is alive
|
||||||
ORESULT // result of a function call; Xoffset is stack offset
|
ORESULT // result of a function call; Xoffset is stack offset
|
||||||
OINLMARK // start of an inlined body, with file/line of caller. Xoffset is an index into the inline tree.
|
OINLMARK // start of an inlined body, with file/line of caller. Xoffset is an index into the inline tree.
|
||||||
|
|
||||||
// arch-specific opcodes
|
// arch-specific opcodes
|
||||||
ORETJMP // return to other function
|
ORETJMP // return to other function
|
||||||
|
|
@ -1162,8 +1162,6 @@ var okForNod = [OEND]bool{
|
||||||
OCFUNC: true,
|
OCFUNC: true,
|
||||||
OCHECKNIL: true,
|
OCHECKNIL: true,
|
||||||
OCLOSE: true,
|
OCLOSE: true,
|
||||||
OCLOSURE: true,
|
|
||||||
OCLOSUREVAR: true,
|
|
||||||
OCOMPLEX: true,
|
OCOMPLEX: true,
|
||||||
OCOMPLIT: true,
|
OCOMPLIT: true,
|
||||||
OCONV: true,
|
OCONV: true,
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ func _() {
|
||||||
_ = x[OITAB-141]
|
_ = x[OITAB-141]
|
||||||
_ = x[OIDATA-142]
|
_ = x[OIDATA-142]
|
||||||
_ = x[OSPTR-143]
|
_ = x[OSPTR-143]
|
||||||
_ = x[OCLOSUREVAR-144]
|
_ = x[OCLOSUREREAD-144]
|
||||||
_ = x[OCFUNC-145]
|
_ = x[OCFUNC-145]
|
||||||
_ = x[OCHECKNIL-146]
|
_ = x[OCHECKNIL-146]
|
||||||
_ = x[OVARDEF-147]
|
_ = x[OVARDEF-147]
|
||||||
|
|
@ -165,9 +165,9 @@ func _() {
|
||||||
_ = x[OEND-154]
|
_ = x[OEND-154]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNEWOBJNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFMETHEXPRBLOCKBREAKCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKRETJMPGETGEND"
|
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNEWOBJNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFMETHEXPRBLOCKBREAKCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDINLCALLEFACEITABIDATASPTRCLOSUREREADCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKRETJMPGETGEND"
|
||||||
|
|
||||||
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 126, 129, 139, 146, 153, 160, 164, 168, 176, 184, 193, 201, 204, 209, 216, 223, 229, 238, 246, 254, 260, 264, 273, 280, 284, 287, 294, 302, 310, 317, 323, 326, 332, 339, 347, 351, 358, 366, 368, 370, 372, 374, 376, 378, 383, 388, 396, 399, 408, 411, 415, 423, 430, 439, 452, 455, 458, 461, 464, 467, 470, 476, 479, 485, 488, 494, 498, 501, 505, 510, 515, 521, 526, 530, 535, 543, 551, 557, 566, 577, 584, 588, 595, 602, 610, 614, 618, 622, 629, 636, 644, 650, 658, 663, 668, 672, 680, 685, 690, 694, 697, 705, 709, 711, 716, 718, 723, 729, 735, 741, 747, 752, 756, 763, 769, 774, 780, 783, 790, 795, 799, 804, 808, 818, 823, 831, 837, 844, 851, 857, 864, 870, 874, 877}
|
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 126, 129, 139, 146, 153, 160, 164, 168, 176, 184, 193, 201, 204, 209, 216, 223, 229, 238, 246, 254, 260, 264, 273, 280, 284, 287, 294, 302, 310, 317, 323, 326, 332, 339, 347, 351, 358, 366, 368, 370, 372, 374, 376, 378, 383, 388, 396, 399, 408, 411, 415, 423, 430, 439, 452, 455, 458, 461, 464, 467, 470, 476, 479, 485, 488, 494, 498, 501, 505, 510, 515, 521, 526, 530, 535, 543, 551, 557, 566, 577, 584, 588, 595, 602, 610, 614, 618, 622, 629, 636, 644, 650, 658, 663, 668, 672, 680, 685, 690, 694, 697, 705, 709, 711, 716, 718, 723, 729, 735, 741, 747, 752, 756, 763, 769, 774, 780, 783, 790, 795, 799, 804, 808, 819, 824, 832, 838, 845, 852, 858, 865, 871, 875, 878}
|
||||||
|
|
||||||
func (i Op) String() string {
|
func (i Op) String() string {
|
||||||
if i >= Op(len(_Op_index)-1) {
|
if i >= Op(len(_Op_index)-1) {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ func TestSizeof(t *testing.T) {
|
||||||
_32bit uintptr // size on 32bit platforms
|
_32bit uintptr // size on 32bit platforms
|
||||||
_64bit uintptr // size on 64bit platforms
|
_64bit uintptr // size on 64bit platforms
|
||||||
}{
|
}{
|
||||||
{Func{}, 172, 296},
|
{Func{}, 168, 288},
|
||||||
{Name{}, 128, 224},
|
{Name{}, 128, 224},
|
||||||
{node{}, 84, 144},
|
{node{}, 84, 144},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue