Best Is code snippet using is.init
sinit.go
Source:sinit.go
...13type InitPlan struct {14 E []InitEntry15}16// An InitSchedule is used to decompose assignment statements into17// static and dynamic initialization parts. Static initializations are18// handled by populating variables' linker symbol data, while dynamic19// initializations are accumulated to be executed in order.20type InitSchedule struct {21 // out is the ordered list of dynamic initialization22 // statements.23 out []*Node24 initplans map[*Node]*InitPlan25 inittemps map[*Node]*Node26}27func (s *InitSchedule) append(n *Node) {28 s.out = append(s.out, n)29}30// staticInit adds an initialization statement n to the schedule.31func (s *InitSchedule) staticInit(n *Node) {32 if !s.tryStaticInit(n) {33 if Debug['%'] != 0 {34 Dump("nonstatic", n)35 }36 s.append(n)37 }38}39// tryStaticInit attempts to statically execute an initialization40// statement and reports whether it succeeded.41func (s *InitSchedule) tryStaticInit(n *Node) bool {42 // Only worry about simple "l = r" assignments. Multiple43 // variable/expression OAS2 assignments have already been44 // replaced by multiple simple OAS assignments, and the other45 // OAS2* assignments mostly necessitate dynamic execution46 // anyway.47 if n.Op != OAS {48 return false49 }50 if n.Left.isBlank() && candiscard(n.Right) {51 return true52 }53 lno := setlineno(n)54 defer func() { lineno = lno }()55 return s.staticassign(n.Left, n.Right)56}57// like staticassign but we are copying an already58// initialized value r.59func (s *InitSchedule) staticcopy(l *Node, r *Node) bool {60 if r.Op != ONAME {61 return false62 }63 if r.Class() == PFUNC {64 pfuncsym(l, r)65 return true66 }67 if r.Class() != PEXTERN || r.Sym.Pkg != localpkg {68 return false69 }70 if r.Name.Defn == nil { // probably zeroed but perhaps supplied externally and of unknown value71 return false72 }73 if r.Name.Defn.Op != OAS {74 return false75 }76 if r.Type.IsString() { // perhaps overwritten by cmd/link -X (#34675)77 return false78 }79 orig := r80 r = r.Name.Defn.Right81 for r.Op == OCONVNOP && !types.Identical(r.Type, l.Type) {82 r = r.Left83 }84 switch r.Op {85 case ONAME:86 if s.staticcopy(l, r) {87 return true88 }89 // We may have skipped past one or more OCONVNOPs, so90 // use conv to ensure r is assignable to l (#13263).91 s.append(nod(OAS, l, conv(r, l.Type)))92 return true93 case OLITERAL:94 if isZero(r) {95 return true96 }97 litsym(l, r, int(l.Type.Width))98 return true99 case OADDR:100 if a := r.Left; a.Op == ONAME {101 addrsym(l, a)102 return true103 }104 case OPTRLIT:105 switch r.Left.Op {106 case OARRAYLIT, OSLICELIT, OSTRUCTLIT, OMAPLIT:107 // copy pointer108 addrsym(l, s.inittemps[r])109 return true110 }111 case OSLICELIT:112 // copy slice113 a := s.inittemps[r]114 slicesym(l, a, r.Right.Int64())115 return true116 case OARRAYLIT, OSTRUCTLIT:117 p := s.initplans[r]118 n := l.copy()119 for i := range p.E {120 e := &p.E[i]121 n.Xoffset = l.Xoffset + e.Xoffset122 n.Type = e.Expr.Type123 if e.Expr.Op == OLITERAL {124 litsym(n, e.Expr, int(n.Type.Width))125 continue126 }127 ll := n.sepcopy()128 if s.staticcopy(ll, e.Expr) {129 continue130 }131 // Requires computation, but we're132 // copying someone else's computation.133 rr := orig.sepcopy()134 rr.Type = ll.Type135 rr.Xoffset += e.Xoffset136 setlineno(rr)137 s.append(nod(OAS, ll, rr))138 }139 return true140 }141 return false142}143func (s *InitSchedule) staticassign(l *Node, r *Node) bool {144 for r.Op == OCONVNOP {145 r = r.Left146 }147 switch r.Op {148 case ONAME:149 return s.staticcopy(l, r)150 case OLITERAL:151 if isZero(r) {152 return true153 }154 litsym(l, r, int(l.Type.Width))155 return true156 case OADDR:157 var nam Node158 if stataddr(&nam, r.Left) {159 addrsym(l, &nam)160 return true161 }162 fallthrough163 case OPTRLIT:164 switch r.Left.Op {165 case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT:166 // Init pointer.167 a := staticname(r.Left.Type)168 s.inittemps[r] = a169 addrsym(l, a)170 // Init underlying literal.171 if !s.staticassign(a, r.Left) {172 s.append(nod(OAS, a, r.Left))173 }174 return true175 }176 //dump("not static ptrlit", r);177 case OSTR2BYTES:178 if l.Class() == PEXTERN && r.Left.Op == OLITERAL {179 sval := strlit(r.Left)180 slicebytes(l, sval)181 return true182 }183 case OSLICELIT:184 s.initplan(r)185 // Init slice.186 bound := r.Right.Int64()187 ta := types.NewArray(r.Type.Elem(), bound)188 ta.SetNoalg(true)189 a := staticname(ta)190 s.inittemps[r] = a191 slicesym(l, a, bound)192 // Fall through to init underlying array.193 l = a194 fallthrough195 case OARRAYLIT, OSTRUCTLIT:196 s.initplan(r)197 p := s.initplans[r]198 n := l.copy()199 for i := range p.E {200 e := &p.E[i]201 n.Xoffset = l.Xoffset + e.Xoffset202 n.Type = e.Expr.Type203 if e.Expr.Op == OLITERAL {204 litsym(n, e.Expr, int(n.Type.Width))205 continue206 }207 setlineno(e.Expr)208 a := n.sepcopy()209 if !s.staticassign(a, e.Expr) {210 s.append(nod(OAS, a, e.Expr))211 }212 }213 return true214 case OMAPLIT:215 break216 case OCLOSURE:217 if hasemptycvars(r) {218 if Debug_closure > 0 {219 Warnl(r.Pos, "closure converted to global")220 }221 // Closures with no captured variables are globals,222 // so the assignment can be done at link time.223 pfuncsym(l, r.Func.Closure.Func.Nname)224 return true225 }226 closuredebugruntimecheck(r)227 case OCONVIFACE:228 // This logic is mirrored in isStaticCompositeLiteral.229 // If you change something here, change it there, and vice versa.230 // Determine the underlying concrete type and value we are converting from.231 val := r232 for val.Op == OCONVIFACE {233 val = val.Left234 }235 if val.Type.IsInterface() {236 // val is an interface type.237 // If val is nil, we can statically initialize l;238 // both words are zero and so there no work to do, so report success.239 // If val is non-nil, we have no concrete type to record,240 // and we won't be able to statically initialize its value, so report failure.241 return Isconst(val, CTNIL)242 }243 var itab *Node244 if l.Type.IsEmptyInterface() {245 itab = typename(val.Type)246 } else {247 itab = itabname(val.Type, l.Type)248 }249 // Create a copy of l to modify while we emit data.250 n := l.copy()251 // Emit itab, advance offset.252 addrsym(n, itab.Left) // itab is an OADDR node253 n.Xoffset += int64(Widthptr)254 // Emit data.255 if isdirectiface(val.Type) {256 if Isconst(val, CTNIL) {257 // Nil is zero, nothing to do.258 return true259 }260 // Copy val directly into n.261 n.Type = val.Type262 setlineno(val)263 a := n.sepcopy()264 if !s.staticassign(a, val) {265 s.append(nod(OAS, a, val))266 }267 } else {268 // Construct temp to hold val, write pointer to temp into n.269 a := staticname(val.Type)270 s.inittemps[val] = a271 if !s.staticassign(a, val) {272 s.append(nod(OAS, a, val))273 }274 addrsym(n, a)275 }276 return true277 }278 //dump("not static", r);279 return false280}281// initContext is the context in which static data is populated.282// It is either in an init function or in any other function.283// Static data populated in an init function will be written either284// zero times (as a readonly, static data symbol) or285// one time (during init function execution).286// Either way, there is no opportunity for races or further modification,287// so the data can be written to a (possibly readonly) data symbol.288// Static data populated in any other function needs to be local to289// that function to allow multiple instances of that function290// to execute concurrently without clobbering each others' data.291type initContext uint8292const (293 inInitFunction initContext = iota294 inNonInitFunction295)296func (c initContext) String() string {297 if c == inInitFunction {298 return "inInitFunction"299 }300 return "inNonInitFunction"301}302// from here down is the walk analysis303// of composite literals.304// most of the work is to generate305// data statements for the constant306// part of the composite literal.307var statuniqgen int // name generator for static temps308// staticname returns a name backed by a static data symbol.309// Callers should call n.MarkReadonly on the310// returned node for readonly nodes.311func staticname(t *types.Type) *Node {312 // Don't use lookupN; it interns the resulting string, but these are all unique.313 n := newname(lookup(fmt.Sprintf(".stmp_%d", statuniqgen)))314 statuniqgen++315 addvar(n, t, PEXTERN)316 return n317}318func isLiteral(n *Node) bool {319 // Treat nils as zeros rather than literals.320 return n.Op == OLITERAL && n.Val().Ctype() != CTNIL321}322func (n *Node) isSimpleName() bool {323 return n.Op == ONAME && n.Class() != PAUTOHEAP && n.Class() != PEXTERN324}325func litas(l *Node, r *Node, init *Nodes) {326 a := nod(OAS, l, r)327 a = typecheck(a, ctxStmt)328 a = walkexpr(a, init)329 init.Append(a)330}331// initGenType is a bitmap indicating the types of generation that will occur for a static value.332type initGenType uint8333const (334 initDynamic initGenType = 1 << iota // contains some dynamic values, for which init code will be generated335 initConst // contains some constant values, which may be written into data symbols336)337// getdyn calculates the initGenType for n.338// If top is false, getdyn is recursing.339func getdyn(n *Node, top bool) initGenType {340 switch n.Op {341 default:342 if isLiteral(n) {343 return initConst344 }345 return initDynamic346 case OSLICELIT:347 if !top {348 return initDynamic349 }350 if n.Right.Int64()/4 > int64(n.List.Len()) {351 // <25% of entries have explicit values.352 // Very rough estimation, it takes 4 bytes of instructions353 // to initialize 1 byte of result. So don't use a static354 // initializer if the dynamic initialization code would be355 // smaller than the static value.356 // See issue 23780.357 return initDynamic358 }359 case OARRAYLIT, OSTRUCTLIT:360 }361 var mode initGenType362 for _, n1 := range n.List.Slice() {363 switch n1.Op {364 case OKEY:365 n1 = n1.Right366 case OSTRUCTKEY:367 n1 = n1.Left368 }369 mode |= getdyn(n1, false)370 if mode == initDynamic|initConst {371 break372 }373 }374 return mode375}376// isStaticCompositeLiteral reports whether n is a compile-time constant.377func isStaticCompositeLiteral(n *Node) bool {378 switch n.Op {379 case OSLICELIT:380 return false381 case OARRAYLIT:382 for _, r := range n.List.Slice() {383 if r.Op == OKEY {384 r = r.Right385 }386 if !isStaticCompositeLiteral(r) {387 return false388 }389 }390 return true391 case OSTRUCTLIT:392 for _, r := range n.List.Slice() {393 if r.Op != OSTRUCTKEY {394 Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r)395 }396 if !isStaticCompositeLiteral(r.Left) {397 return false398 }399 }400 return true401 case OLITERAL:402 return true403 case OCONVIFACE:404 // See staticassign's OCONVIFACE case for comments.405 val := n406 for val.Op == OCONVIFACE {407 val = val.Left408 }409 if val.Type.IsInterface() {410 return Isconst(val, CTNIL)411 }412 if isdirectiface(val.Type) && Isconst(val, CTNIL) {413 return true414 }415 return isStaticCompositeLiteral(val)416 }417 return false418}419// initKind is a kind of static initialization: static, dynamic, or local.420// Static initialization represents literals and421// literal components of composite literals.422// Dynamic initialization represents non-literals and423// non-literal components of composite literals.424// LocalCode initialization represents initialization425// that occurs purely in generated code local to the function of use.426// Initialization code is sometimes generated in passes,427// first static then dynamic.428type initKind uint8429const (430 initKindStatic initKind = iota + 1431 initKindDynamic432 initKindLocalCode433)434// fixedlit handles struct, array, and slice literals.435// TODO: expand documentation.436func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes) {437 var splitnode func(*Node) (a *Node, value *Node)438 switch n.Op {439 case OARRAYLIT, OSLICELIT:440 var k int64441 splitnode = func(r *Node) (*Node, *Node) {442 if r.Op == OKEY {443 k = indexconst(r.Left)444 if k < 0 {445 Fatalf("fixedlit: invalid index %v", r.Left)446 }447 r = r.Right448 }449 a := nod(OINDEX, var_, nodintconst(k))450 k++451 return a, r452 }453 case OSTRUCTLIT:454 splitnode = func(r *Node) (*Node, *Node) {455 if r.Op != OSTRUCTKEY {456 Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r)457 }458 if r.Sym.IsBlank() {459 return nblank, r.Left460 }461 setlineno(r)462 return nodSym(ODOT, var_, r.Sym), r.Left463 }464 default:465 Fatalf("fixedlit bad op: %v", n.Op)466 }467 for _, r := range n.List.Slice() {468 a, value := splitnode(r)469 if a == nblank && candiscard(value) {470 continue471 }472 switch value.Op {473 case OSLICELIT:474 if (kind == initKindStatic && ctxt == inNonInitFunction) || (kind == initKindDynamic && ctxt == inInitFunction) {475 slicelit(ctxt, value, a, init)476 continue477 }478 case OARRAYLIT, OSTRUCTLIT:479 fixedlit(ctxt, kind, value, a, init)480 continue481 }482 islit := isLiteral(value)483 if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) {484 continue485 }486 // build list of assignments: var[index] = expr487 setlineno(a)488 a = nod(OAS, a, value)489 a = typecheck(a, ctxStmt)490 switch kind {491 case initKindStatic:492 genAsStatic(a)493 case initKindDynamic, initKindLocalCode:494 a = orderStmtInPlace(a, map[string][]*Node{})495 a = walkstmt(a)496 init.Append(a)497 default:498 Fatalf("fixedlit: bad kind %d", kind)499 }500 }501}502func isSmallSliceLit(n *Node) bool {503 if n.Op != OSLICELIT {504 return false505 }506 r := n.Right507 return smallintconst(r) && (n.Type.Elem().Width == 0 || r.Int64() <= smallArrayBytes/n.Type.Elem().Width)508}509func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {510 // make an array type corresponding the number of elements we have511 t := types.NewArray(n.Type.Elem(), n.Right.Int64())512 dowidth(t)513 if ctxt == inNonInitFunction {514 // put everything into static array515 vstat := staticname(t)516 fixedlit(ctxt, initKindStatic, n, vstat, init)517 fixedlit(ctxt, initKindDynamic, n, vstat, init)518 // copy static to slice519 var_ = typecheck(var_, ctxExpr|ctxAssign)520 var nam Node521 if !stataddr(&nam, var_) || nam.Class() != PEXTERN {522 Fatalf("slicelit: %v", var_)523 }524 slicesym(&nam, vstat, t.NumElem())525 return526 }527 // recipe for var = []t{...}528 // 1. make a static array529 // var vstat [...]t530 // 2. assign (data statements) the constant part531 // vstat = constpart{}532 // 3. make an auto pointer to array and allocate heap to it533 // var vauto *[...]t = new([...]t)534 // 4. copy the static array to the auto array535 // *vauto = vstat536 // 5. for each dynamic part assign to the array537 // vauto[i] = dynamic part538 // 6. assign slice of allocated heap to var539 // var = vauto[:]540 //541 // an optimization is done if there is no constant part542 // 3. var vauto *[...]t = new([...]t)543 // 5. vauto[i] = dynamic part544 // 6. var = vauto[:]545 // if the literal contains constants,546 // make static initialized array (1),(2)547 var vstat *Node548 mode := getdyn(n, true)549 if mode&initConst != 0 && !isSmallSliceLit(n) {550 vstat = staticname(t)551 if ctxt == inInitFunction {552 vstat.MarkReadonly()553 }554 fixedlit(ctxt, initKindStatic, n, vstat, init)555 }556 // make new auto *array (3 declare)557 vauto := temp(types.NewPtr(t))558 // set auto to point at new temp or heap (3 assign)559 var a *Node560 if x := prealloc[n]; x != nil {561 // temp allocated during order.go for dddarg562 if !types.Identical(t, x.Type) {563 panic("dotdotdot base type does not match order's assigned type")564 }565 if vstat == nil {566 a = nod(OAS, x, nil)567 a = typecheck(a, ctxStmt)568 init.Append(a) // zero new temp569 } else {570 // Declare that we're about to initialize all of x.571 // (Which happens at the *vauto = vstat below.)572 init.Append(nod(OVARDEF, x, nil))573 }574 a = nod(OADDR, x, nil)575 } else if n.Esc == EscNone {576 a = temp(t)577 if vstat == nil {578 a = nod(OAS, temp(t), nil)579 a = typecheck(a, ctxStmt)580 init.Append(a) // zero new temp581 a = a.Left582 } else {583 init.Append(nod(OVARDEF, a, nil))584 }585 a = nod(OADDR, a, nil)586 } else {587 a = nod(ONEW, nil, nil)588 a.List.Set1(typenod(t))589 }590 a = nod(OAS, vauto, a)591 a = typecheck(a, ctxStmt)592 a = walkexpr(a, init)593 init.Append(a)594 if vstat != nil {595 // copy static to heap (4)596 a = nod(ODEREF, vauto, nil)597 a = nod(OAS, a, vstat)598 a = typecheck(a, ctxStmt)599 a = walkexpr(a, init)600 init.Append(a)601 }602 // put dynamics into array (5)603 var index int64604 for _, value := range n.List.Slice() {605 if value.Op == OKEY {606 index = indexconst(value.Left)607 if index < 0 {608 Fatalf("slicelit: invalid index %v", value.Left)609 }610 value = value.Right611 }612 a := nod(OINDEX, vauto, nodintconst(index))613 a.SetBounded(true)614 index++615 // TODO need to check bounds?616 switch value.Op {617 case OSLICELIT:618 break619 case OARRAYLIT, OSTRUCTLIT:620 k := initKindDynamic621 if vstat == nil {622 // Generate both static and dynamic initializations.623 // See issue #31987.624 k = initKindLocalCode625 }626 fixedlit(ctxt, k, value, a, init)627 continue628 }629 if vstat != nil && isLiteral(value) { // already set by copy from static value630 continue631 }632 // build list of vauto[c] = expr633 setlineno(value)634 a = nod(OAS, a, value)635 a = typecheck(a, ctxStmt)636 a = orderStmtInPlace(a, map[string][]*Node{})637 a = walkstmt(a)638 init.Append(a)639 }640 // make slice out of heap (6)641 a = nod(OAS, var_, nod(OSLICE, vauto, nil))642 a = typecheck(a, ctxStmt)643 a = orderStmtInPlace(a, map[string][]*Node{})644 a = walkstmt(a)645 init.Append(a)646}647func maplit(n *Node, m *Node, init *Nodes) {648 // make the map var649 a := nod(OMAKE, nil, nil)650 a.Esc = n.Esc651 a.List.Set2(typenod(n.Type), nodintconst(int64(n.List.Len())))652 litas(m, a, init)653 entries := n.List.Slice()654 // The order pass already removed any dynamic (runtime-computed) entries.655 // All remaining entries are static. Double-check that.656 for _, r := range entries {657 if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {658 Fatalf("maplit: entry is not a literal: %v", r)659 }660 }661 if len(entries) > 25 {662 // For a large number of entries, put them in an array and loop.663 // build types [count]Tindex and [count]Tvalue664 tk := types.NewArray(n.Type.Key(), int64(len(entries)))665 te := types.NewArray(n.Type.Elem(), int64(len(entries)))666 tk.SetNoalg(true)667 te.SetNoalg(true)668 dowidth(tk)669 dowidth(te)670 // make and initialize static arrays671 vstatk := staticname(tk)672 vstatk.MarkReadonly()673 vstate := staticname(te)674 vstate.MarkReadonly()675 datak := nod(OARRAYLIT, nil, nil)676 datae := nod(OARRAYLIT, nil, nil)677 for _, r := range entries {678 datak.List.Append(r.Left)679 datae.List.Append(r.Right)680 }681 fixedlit(inInitFunction, initKindStatic, datak, vstatk, init)682 fixedlit(inInitFunction, initKindStatic, datae, vstate, init)683 // loop adding structure elements to map684 // for i = 0; i < len(vstatk); i++ {685 // map[vstatk[i]] = vstate[i]686 // }687 i := temp(types.Types[TINT])688 rhs := nod(OINDEX, vstate, i)689 rhs.SetBounded(true)690 kidx := nod(OINDEX, vstatk, i)691 kidx.SetBounded(true)692 lhs := nod(OINDEX, m, kidx)693 zero := nod(OAS, i, nodintconst(0))694 cond := nod(OLT, i, nodintconst(tk.NumElem()))695 incr := nod(OAS, i, nod(OADD, i, nodintconst(1)))696 body := nod(OAS, lhs, rhs)697 loop := nod(OFOR, cond, incr)698 loop.Nbody.Set1(body)699 loop.Ninit.Set1(zero)700 loop = typecheck(loop, ctxStmt)701 loop = walkstmt(loop)702 init.Append(loop)703 return704 }705 // For a small number of entries, just add them directly.706 // Build list of var[c] = expr.707 // Use temporaries so that mapassign1 can have addressable key, elem.708 // TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.709 tmpkey := temp(m.Type.Key())710 tmpelem := temp(m.Type.Elem())711 for _, r := range entries {712 index, elem := r.Left, r.Right713 setlineno(index)714 a := nod(OAS, tmpkey, index)715 a = typecheck(a, ctxStmt)716 a = walkstmt(a)717 init.Append(a)718 setlineno(elem)719 a = nod(OAS, tmpelem, elem)720 a = typecheck(a, ctxStmt)721 a = walkstmt(a)722 init.Append(a)723 setlineno(tmpelem)724 a = nod(OAS, nod(OINDEX, m, tmpkey), tmpelem)725 a = typecheck(a, ctxStmt)726 a = walkstmt(a)727 init.Append(a)728 }729 a = nod(OVARKILL, tmpkey, nil)730 a = typecheck(a, ctxStmt)731 init.Append(a)732 a = nod(OVARKILL, tmpelem, nil)733 a = typecheck(a, ctxStmt)734 init.Append(a)735}736func anylit(n *Node, var_ *Node, init *Nodes) {737 t := n.Type738 switch n.Op {739 default:740 Fatalf("anylit: not lit, op=%v node=%v", n.Op, n)741 case ONAME:742 a := nod(OAS, var_, n)743 a = typecheck(a, ctxStmt)744 init.Append(a)745 case OPTRLIT:746 if !t.IsPtr() {747 Fatalf("anylit: not ptr")748 }749 var r *Node750 if n.Right != nil {751 // n.Right is stack temporary used as backing store.752 init.Append(nod(OAS, n.Right, nil)) // zero backing store, just in case (#18410)753 r = nod(OADDR, n.Right, nil)754 r = typecheck(r, ctxExpr)755 } else {756 r = nod(ONEW, nil, nil)757 r.SetTypecheck(1)758 r.Type = t759 r.Esc = n.Esc760 }761 r = walkexpr(r, init)762 a := nod(OAS, var_, r)763 a = typecheck(a, ctxStmt)764 init.Append(a)765 var_ = nod(ODEREF, var_, nil)766 var_ = typecheck(var_, ctxExpr|ctxAssign)767 anylit(n.Left, var_, init)768 case OSTRUCTLIT, OARRAYLIT:769 if !t.IsStruct() && !t.IsArray() {770 Fatalf("anylit: not struct/array")771 }772 if var_.isSimpleName() && n.List.Len() > 4 {773 // lay out static data774 vstat := staticname(t)775 vstat.MarkReadonly()776 ctxt := inInitFunction777 if n.Op == OARRAYLIT {778 ctxt = inNonInitFunction779 }780 fixedlit(ctxt, initKindStatic, n, vstat, init)781 // copy static to var782 a := nod(OAS, var_, vstat)783 a = typecheck(a, ctxStmt)784 a = walkexpr(a, init)785 init.Append(a)786 // add expressions to automatic787 fixedlit(inInitFunction, initKindDynamic, n, var_, init)788 break789 }790 var components int64791 if n.Op == OARRAYLIT {792 components = t.NumElem()793 } else {794 components = int64(t.NumFields())795 }796 // initialization of an array or struct with unspecified components (missing fields or arrays)797 if var_.isSimpleName() || int64(n.List.Len()) < components {798 a := nod(OAS, var_, nil)799 a = typecheck(a, ctxStmt)800 a = walkexpr(a, init)801 init.Append(a)802 }803 fixedlit(inInitFunction, initKindLocalCode, n, var_, init)804 case OSLICELIT:805 slicelit(inInitFunction, n, var_, init)806 case OMAPLIT:807 if !t.IsMap() {808 Fatalf("anylit: not map")809 }810 maplit(n, var_, init)811 }812}813func oaslit(n *Node, init *Nodes) bool {814 if n.Left == nil || n.Right == nil {815 // not a special composite literal assignment816 return false817 }818 if n.Left.Type == nil || n.Right.Type == nil {819 // not a special composite literal assignment820 return false821 }822 if !n.Left.isSimpleName() {823 // not a special composite literal assignment824 return false825 }826 if !types.Identical(n.Left.Type, n.Right.Type) {827 // not a special composite literal assignment828 return false829 }830 switch n.Right.Op {831 default:832 // not a special composite literal assignment833 return false834 case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:835 if vmatch1(n.Left, n.Right) {836 // not a special composite literal assignment837 return false838 }839 anylit(n.Right, n.Left, init)840 }841 n.Op = OEMPTY842 n.Right = nil843 return true844}845func getlit(lit *Node) int {846 if smallintconst(lit) {847 return int(lit.Int64())848 }849 return -1850}851// stataddr sets nam to the static address of n and reports whether it succeeded.852func stataddr(nam *Node, n *Node) bool {853 if n == nil {854 return false855 }856 switch n.Op {857 case ONAME:858 *nam = *n859 return true860 case ODOT:861 if !stataddr(nam, n.Left) {862 break863 }864 nam.Xoffset += n.Xoffset865 nam.Type = n.Type866 return true867 case OINDEX:868 if n.Left.Type.IsSlice() {869 break870 }871 if !stataddr(nam, n.Left) {872 break873 }874 l := getlit(n.Right)875 if l < 0 {876 break877 }878 // Check for overflow.879 if n.Type.Width != 0 && thearch.MAXWIDTH/n.Type.Width <= int64(l) {880 break881 }882 nam.Xoffset += int64(l) * n.Type.Width883 nam.Type = n.Type884 return true885 }886 return false887}888func (s *InitSchedule) initplan(n *Node) {889 if s.initplans[n] != nil {890 return891 }892 p := new(InitPlan)893 s.initplans[n] = p894 switch n.Op {895 default:896 Fatalf("initplan")897 case OARRAYLIT, OSLICELIT:898 var k int64899 for _, a := range n.List.Slice() {900 if a.Op == OKEY {901 k = indexconst(a.Left)902 if k < 0 {903 Fatalf("initplan arraylit: invalid index %v", a.Left)904 }905 a = a.Right906 }907 s.addvalue(p, k*n.Type.Elem().Width, a)908 k++909 }910 case OSTRUCTLIT:911 for _, a := range n.List.Slice() {912 if a.Op != OSTRUCTKEY {913 Fatalf("initplan structlit")914 }915 if a.Sym.IsBlank() {916 continue917 }918 s.addvalue(p, a.Xoffset, a.Left)919 }920 case OMAPLIT:921 for _, a := range n.List.Slice() {922 if a.Op != OKEY {923 Fatalf("initplan maplit")924 }925 s.addvalue(p, -1, a.Right)926 }927 }928}929func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n *Node) {930 // special case: zero can be dropped entirely931 if isZero(n) {932 return933 }934 // special case: inline struct and array (not slice) literals935 if isvaluelit(n) {936 s.initplan(n)937 q := s.initplans[n]938 for _, qe := range q.E {939 // qe is a copy; we are not modifying entries in q.E940 qe.Xoffset += xoffset941 p.E = append(p.E, qe)942 }943 return944 }945 // add to plan946 p.E = append(p.E, InitEntry{Xoffset: xoffset, Expr: n})947}948func isZero(n *Node) bool {949 switch n.Op {950 case OLITERAL:951 switch u := n.Val().U.(type) {...
initialize.go
Source:initialize.go
...68 TypeTiKVSingleGather = "TiKVSingleGather"69 // TypeShowDDLJobs is the type of show ddl jobs.70 TypeShowDDLJobs = "ShowDDLJobs"71)72// Init initializes LogicalAggregation.73func (la LogicalAggregation) Init(ctx sessionctx.Context) *LogicalAggregation {74 la.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeAgg, &la)75 return &la76}77// Init initializes LogicalJoin.78func (p LogicalJoin) Init(ctx sessionctx.Context) *LogicalJoin {79 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeJoin, &p)80 return &p81}82// Init initializes DataSource.83func (ds DataSource) Init(ctx sessionctx.Context) *DataSource {84 ds.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeTableScan, &ds)85 return &ds86}87// Init initializes TiKVSingleGather.88func (sg TiKVSingleGather) Init(ctx sessionctx.Context) *TiKVSingleGather {89 sg.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeTiKVSingleGather, &sg)90 return &sg91}92// Init initializes LogicalTableScan.93func (ts LogicalTableScan) Init(ctx sessionctx.Context) *LogicalTableScan {94 ts.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeTableScan, &ts)95 return &ts96}97// Init initializes LogicalIndexScan.98func (is LogicalIndexScan) Init(ctx sessionctx.Context) *LogicalIndexScan {99 is.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeIdxScan, &is)100 return &is101}102// Init initializes LogicalSelection.103func (p LogicalSelection) Init(ctx sessionctx.Context) *LogicalSelection {104 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeSel, &p)105 return &p106}107// Init initializes PhysicalSelection.108func (p PhysicalSelection) Init(ctx sessionctx.Context, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalSelection {109 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeSel, &p)110 p.childrenReqProps = props111 p.stats = stats112 return &p113}114// Init initializes LogicalUnionScan.115func (p LogicalUnionScan) Init(ctx sessionctx.Context) *LogicalUnionScan {116 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeUnionScan, &p)117 return &p118}119// Init initializes LogicalProjection.120func (p LogicalProjection) Init(ctx sessionctx.Context) *LogicalProjection {121 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeProj, &p)122 return &p123}124// Init initializes PhysicalProjection.125func (p PhysicalProjection) Init(ctx sessionctx.Context, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalProjection {126 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeProj, &p)127 p.childrenReqProps = props128 p.stats = stats129 return &p130}131// Init initializes LogicalSort.132func (ls LogicalSort) Init(ctx sessionctx.Context) *LogicalSort {133 ls.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeSort, &ls)134 return &ls135}136// Init initializes PhysicalSort.137func (p PhysicalSort) Init(ctx sessionctx.Context, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalSort {138 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeSort, &p)139 p.childrenReqProps = props140 p.stats = stats141 return &p142}143// Init initializes NominalSort.144func (p NominalSort) Init(ctx sessionctx.Context, props ...*property.PhysicalProperty) *NominalSort {145 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeSort, &p)146 p.childrenReqProps = props147 return &p148}149// Init initializes LogicalTopN.150func (lt LogicalTopN) Init(ctx sessionctx.Context) *LogicalTopN {151 lt.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeTopN, <)152 return <153}154// Init initializes PhysicalTopN.155func (p PhysicalTopN) Init(ctx sessionctx.Context, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalTopN {156 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeTopN, &p)157 p.childrenReqProps = props158 p.stats = stats159 return &p160}161// Init initializes LogicalLimit.162func (p LogicalLimit) Init(ctx sessionctx.Context) *LogicalLimit {163 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeLimit, &p)164 return &p165}166// Init initializes PhysicalLimit.167func (p PhysicalLimit) Init(ctx sessionctx.Context, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalLimit {168 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeLimit, &p)169 p.childrenReqProps = props170 p.stats = stats171 return &p172}173// Init initializes LogicalTableDual.174func (p LogicalTableDual) Init(ctx sessionctx.Context) *LogicalTableDual {175 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeDual, &p)176 return &p177}178// Init initializes PhysicalTableDual.179func (p PhysicalTableDual) Init(ctx sessionctx.Context, stats *property.StatsInfo) *PhysicalTableDual {180 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeDual, &p)181 p.stats = stats182 return &p183}184// Init initializes Delete.185func (p Delete) Init(ctx sessionctx.Context) *Delete {186 p.basePlan = newBasePlan(ctx, TypeDelete)187 return &p188}189// Init initializes Insert.190func (p Insert) Init(ctx sessionctx.Context) *Insert {191 p.basePlan = newBasePlan(ctx, TypeInsert)192 return &p193}194// Init initializes LogicalShow.195func (p LogicalShow) Init(ctx sessionctx.Context) *LogicalShow {196 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeShow, &p)197 return &p198}199// Init initializes LogicalShowDDLJobs.200func (p LogicalShowDDLJobs) Init(ctx sessionctx.Context) *LogicalShowDDLJobs {201 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeShowDDLJobs, &p)202 return &p203}204// Init initializes PhysicalShow.205func (p PhysicalShow) Init(ctx sessionctx.Context) *PhysicalShow {206 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeShow, &p)207 // Just use pseudo stats to avoid panic.208 p.stats = &property.StatsInfo{RowCount: 1}209 return &p210}211// Init initializes PhysicalShowDDLJobs.212func (p PhysicalShowDDLJobs) Init(ctx sessionctx.Context) *PhysicalShowDDLJobs {213 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeShowDDLJobs, &p)214 // Just use pseudo stats to avoid panic.215 p.stats = &property.StatsInfo{RowCount: 1}216 return &p217}218// Init initializes PhysicalTableScan.219func (p PhysicalTableScan) Init(ctx sessionctx.Context) *PhysicalTableScan {220 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeTableScan, &p)221 return &p222}223// Init initializes PhysicalIndexScan.224func (p PhysicalIndexScan) Init(ctx sessionctx.Context) *PhysicalIndexScan {225 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeIdxScan, &p)226 return &p227}228// Init initializes LogicalMemTable.229func (p LogicalMemTable) Init(ctx sessionctx.Context) *LogicalMemTable {230 p.baseLogicalPlan = newBaseLogicalPlan(ctx, TypeMemTableScan, &p)231 return &p232}233// Init initializes PhysicalMemTable.234func (p PhysicalMemTable) Init(ctx sessionctx.Context, stats *property.StatsInfo) *PhysicalMemTable {235 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeMemTableScan, &p)236 p.stats = stats237 return &p238}239// Init initializes PhysicalHashJoin.240func (p PhysicalHashJoin) Init(ctx sessionctx.Context, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalHashJoin {241 tp := TypeHashRightJoin242 if p.InnerChildIdx == 1 {243 tp = TypeHashLeftJoin244 }245 p.basePhysicalPlan = newBasePhysicalPlan(ctx, tp, &p)246 p.childrenReqProps = props247 p.stats = stats248 return &p249}250// Init initializes PhysicalMergeJoin.251func (p PhysicalMergeJoin) Init(ctx sessionctx.Context, stats *property.StatsInfo) *PhysicalMergeJoin {252 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeMergeJoin, &p)253 p.stats = stats254 return &p255}256// Init initializes basePhysicalAgg.257func (base basePhysicalAgg) Init(ctx sessionctx.Context, stats *property.StatsInfo) *basePhysicalAgg {258 base.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeHashAgg, &base)259 base.stats = stats260 return &base261}262func (base basePhysicalAgg) initForHash(ctx sessionctx.Context, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalHashAgg {263 p := &PhysicalHashAgg{base}264 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeHashAgg, p)265 p.childrenReqProps = props266 p.stats = stats267 return p268}269// Init initializes PhysicalUnionScan.270func (p PhysicalUnionScan) Init(ctx sessionctx.Context, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalUnionScan {271 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeUnionScan, &p)272 p.childrenReqProps = props273 p.stats = stats274 return &p275}276// Init initializes PhysicalIndexLookUpReader.277func (p PhysicalIndexLookUpReader) Init(ctx sessionctx.Context) *PhysicalIndexLookUpReader {278 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeIndexLookUp, &p)279 p.TablePlans = flattenPushDownPlan(p.tablePlan)280 p.IndexPlans = flattenPushDownPlan(p.indexPlan)281 p.schema = p.tablePlan.Schema()282 return &p283}284// Init initializes PhysicalTableReader.285func (p PhysicalTableReader) Init(ctx sessionctx.Context) *PhysicalTableReader {286 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeTableReader, &p)287 if p.tablePlan != nil {288 p.TablePlans = flattenPushDownPlan(p.tablePlan)289 p.schema = p.tablePlan.Schema()290 }291 return &p292}293// Init initializes PhysicalIndexReader.294func (p PhysicalIndexReader) Init(ctx sessionctx.Context) *PhysicalIndexReader {295 p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeIndexReader, &p)296 p.SetSchema(nil)297 return &p298}299// flattenPushDownPlan converts a plan tree to a list, whose head is the leaf node like table scan.300func flattenPushDownPlan(p PhysicalPlan) []PhysicalPlan {301 plans := make([]PhysicalPlan, 0, 5)302 for {303 plans = append(plans, p)304 if len(p.Children()) == 0 {305 break306 }307 p = p.Children()[0]...
init
Using AI Code Generation
1import (2func main() {3 fmt.Println("main method")4}5import (6func init() {7 fmt.Println("init method")8}9import (10func init() {11 fmt.Println("init method")12}13func main() {14 fmt.Println("main method")15}16import (17func init() {18 fmt.Println("init method")19}20func main() {21 fmt.Println("main method")22}23import (24func init() {25 fmt.Println("init method")26}27func main() {28 fmt.Println("main method")29}30import (31func init() {32 fmt.Println("init method")33}34func main() {35 fmt.Println("main method")36}37import (38func init() {39 fmt.Println("init method")40}41func main() {42 fmt.Println("main method")43}44import (45func init() {46 fmt.Println("init method")47}48func main() {49 fmt.Println("main method")50}51import (52func init() {53 fmt.Println("init method")54}55func main() {56 fmt.Println("main method")57}58import (59func init() {60 fmt.Println("init method")61}62func main() {63 fmt.Println("main method")64}65import (66func init() {67 fmt.Println("init method")68}69func main() {70 fmt.Println("main method")71}72import (73func init() {74 fmt.Println("init method")75}76func main() {77 fmt.Println("main method")78}79import (80func init() {81 fmt.Println("init method")82}83func main() {84 fmt.Println("main method")85}86import (87func init() {88 fmt.Println("init method")89}90func main() {
init
Using AI Code Generation
1import (2func main() {3 fmt.Println("Hello, playground")4}5import (6func init() {7 fmt.Println("init method")8}9func main() {10 fmt.Println("Hello, playground")11}
init
Using AI Code Generation
1import "fmt"2func main() {3 fmt.Println("Hello, World!")4 fmt.Println("Hello, World!")5 fmt.Println("Hello, World!")6}7import "fmt"8func main() {9 fmt.Println("Hello, World!")10 fmt.Println("Hello, World!")11}12import "fmt"13func main() {14 fmt.Println("Hello, World!")15}16import "fmt"17func main() {18 fmt.Println("Hello, World!")19}20import "fmt"21func main() {22 fmt.Println("Hello, World!")23}24import "fmt"25func main() {26 fmt.Println("Hello, World!")27}28import "fmt"29func main() {30 fmt.Println("Hello, World!")31}32import "fmt"33func main() {34 fmt.Println("Hello, World!")35}36import "fmt"37func main() {38 fmt.Println("Hello, World!")39}40import "fmt"41func main() {42 fmt.Println("Hello, World!")43}44import "fmt"45func main() {46 fmt.Println("Hello, World!")47}48import "fmt"49func main() {50 fmt.Println("Hello, World!")51}52import "fmt"53func main() {54 fmt.Println("Hello, World!")55}56import "fmt"57func main() {58 fmt.Println("Hello, World!")59}60import "fmt"61func main() {62 fmt.Println("Hello, World!")63}64import "fmt"65func main() {66 fmt.Println("Hello, World!")67}68import "fmt"69func main() {70 fmt.Println("Hello, World!")71}72import "fmt"73func main() {74 fmt.Println("
init
Using AI Code Generation
1import (2func main() {3 fmt.Println("initpkg.init:", initpkg.Init)4 fmt.Println("initpkg.Init2:", initpkg.Init2)5}6import "fmt"7var Init = init()8func init() int {9 fmt.Println("initpkg.init")10}11var Init2 = init()12import "fmt"13func init() {14 fmt.Println("initpkg.init2")15}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!