How to use init method of is Package

Best Is code snippet using is.init

sinit.go

Source:sinit.go Github

copy

Full Screen

...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) {...

Full Screen

Full Screen

initialize.go

Source:initialize.go Github

copy

Full Screen

...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, &lt)152	return &lt153}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]...

Full Screen

Full Screen

init

Using AI Code Generation

copy

Full Screen

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() {

Full Screen

Full Screen

init

Using AI Code Generation

copy

Full Screen

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}

Full Screen

Full Screen

init

Using AI Code Generation

copy

Full Screen

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("

Full Screen

Full Screen

init

Using AI Code Generation

copy

Full Screen

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}

Full Screen

Full Screen

Automation Testing Tutorials

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.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful