1
2
3
4
5 package noder
6
7 import (
8 "fmt"
9 "go/constant"
10 "go/token"
11 "go/version"
12 "internal/buildcfg"
13 "internal/pkgbits"
14 "os"
15 "strings"
16
17 "cmd/compile/internal/base"
18 "cmd/compile/internal/ir"
19 "cmd/compile/internal/syntax"
20 "cmd/compile/internal/types"
21 "cmd/compile/internal/types2"
22 )
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 type pkgWriter struct {
64 pkgbits.PkgEncoder
65
66 m posMap
67 curpkg *types2.Package
68 info *types2.Info
69 rangeFuncBodyClosures map[*syntax.FuncLit]bool
70
71
72
73 posBasesIdx map[*syntax.PosBase]pkgbits.Index
74 pkgsIdx map[*types2.Package]pkgbits.Index
75 typsIdx map[types2.Type]pkgbits.Index
76 objsIdx map[types2.Object]pkgbits.Index
77
78
79
80 funDecls map[*types2.Func]*syntax.FuncDecl
81 typDecls map[*types2.TypeName]typeDeclGen
82
83
84
85 linknames map[types2.Object]string
86
87
88
89 cgoPragmas [][]string
90 }
91
92
93
94 func newPkgWriter(m posMap, pkg *types2.Package, info *types2.Info, otherInfo map[*syntax.FuncLit]bool) *pkgWriter {
95 return &pkgWriter{
96 PkgEncoder: pkgbits.NewPkgEncoder(base.Debug.SyncFrames),
97
98 m: m,
99 curpkg: pkg,
100 info: info,
101 rangeFuncBodyClosures: otherInfo,
102
103 pkgsIdx: make(map[*types2.Package]pkgbits.Index),
104 objsIdx: make(map[types2.Object]pkgbits.Index),
105 typsIdx: make(map[types2.Type]pkgbits.Index),
106
107 posBasesIdx: make(map[*syntax.PosBase]pkgbits.Index),
108
109 funDecls: make(map[*types2.Func]*syntax.FuncDecl),
110 typDecls: make(map[*types2.TypeName]typeDeclGen),
111
112 linknames: make(map[types2.Object]string),
113 }
114 }
115
116
117 func (pw *pkgWriter) errorf(p poser, msg string, args ...interface{}) {
118 base.ErrorfAt(pw.m.pos(p), 0, msg, args...)
119 }
120
121
122 func (pw *pkgWriter) fatalf(p poser, msg string, args ...interface{}) {
123 base.FatalfAt(pw.m.pos(p), msg, args...)
124 }
125
126
127
128 func (pw *pkgWriter) unexpected(what string, p poser) {
129 pw.fatalf(p, "unexpected %s: %v (%T)", what, p, p)
130 }
131
132 func (pw *pkgWriter) typeAndValue(x syntax.Expr) syntax.TypeAndValue {
133 tv, ok := pw.maybeTypeAndValue(x)
134 if !ok {
135 pw.fatalf(x, "missing Types entry: %v", syntax.String(x))
136 }
137 return tv
138 }
139
140 func (pw *pkgWriter) maybeTypeAndValue(x syntax.Expr) (syntax.TypeAndValue, bool) {
141 tv := x.GetTypeInfo()
142
143
144
145
146 if name, ok := x.(*syntax.Name); ok {
147 if inst, ok := pw.info.Instances[name]; ok {
148 tv.Type = inst.Type
149 }
150 }
151
152 return tv, tv.Type != nil
153 }
154
155
156 func (pw *pkgWriter) typeOf(expr syntax.Expr) types2.Type {
157 tv := pw.typeAndValue(expr)
158 if !tv.IsValue() {
159 pw.fatalf(expr, "expected value: %v", syntax.String(expr))
160 }
161 return tv.Type
162 }
163
164
165 type writer struct {
166 p *pkgWriter
167
168 pkgbits.Encoder
169
170
171 sig *types2.Signature
172
173
174
175
176
177
178
179 localsIdx map[*types2.Var]int
180
181
182
183 closureVars []posVar
184 closureVarsIdx map[*types2.Var]int
185
186 dict *writerDict
187
188
189
190 derived bool
191 }
192
193
194 type writerDict struct {
195
196
197 implicits []*types2.TypeParam
198
199
200
201 derived []derivedInfo
202
203
204
205 derivedIdx map[types2.Type]pkgbits.Index
206
207
208 typeParamMethodExprs []writerMethodExprInfo
209 subdicts []objInfo
210 rtypes []typeInfo
211 itabs []itabInfo
212 }
213
214 type itabInfo struct {
215 typ typeInfo
216 iface typeInfo
217 }
218
219
220
221
222
223 func (dict *writerDict) typeParamIndex(typ *types2.TypeParam) int {
224 for idx, implicit := range dict.implicits {
225 if implicit == typ {
226 return idx
227 }
228 }
229
230 return len(dict.implicits) + typ.Index()
231 }
232
233
234 type derivedInfo struct {
235 idx pkgbits.Index
236 needed bool
237 }
238
239
240
241
242
243
244
245
246
247 type typeInfo struct {
248 idx pkgbits.Index
249 derived bool
250 }
251
252
253
254 type objInfo struct {
255 idx pkgbits.Index
256 explicits []typeInfo
257 }
258
259
260
261
262 type selectorInfo struct {
263 pkgIdx pkgbits.Index
264 nameIdx pkgbits.Index
265 }
266
267
268
269 func (info objInfo) anyDerived() bool {
270 for _, explicit := range info.explicits {
271 if explicit.derived {
272 return true
273 }
274 }
275 return false
276 }
277
278
279
280 func (info objInfo) equals(other objInfo) bool {
281 if info.idx != other.idx {
282 return false
283 }
284 assert(len(info.explicits) == len(other.explicits))
285 for i, targ := range info.explicits {
286 if targ != other.explicits[i] {
287 return false
288 }
289 }
290 return true
291 }
292
293 type writerMethodExprInfo struct {
294 typeParamIdx int
295 methodInfo selectorInfo
296 }
297
298
299
300
301 func (dict *writerDict) typeParamMethodExprIdx(typeParamIdx int, methodInfo selectorInfo) int {
302 newInfo := writerMethodExprInfo{typeParamIdx, methodInfo}
303
304 for idx, oldInfo := range dict.typeParamMethodExprs {
305 if oldInfo == newInfo {
306 return idx
307 }
308 }
309
310 idx := len(dict.typeParamMethodExprs)
311 dict.typeParamMethodExprs = append(dict.typeParamMethodExprs, newInfo)
312 return idx
313 }
314
315
316
317
318 func (dict *writerDict) subdictIdx(newInfo objInfo) int {
319 for idx, oldInfo := range dict.subdicts {
320 if oldInfo.equals(newInfo) {
321 return idx
322 }
323 }
324
325 idx := len(dict.subdicts)
326 dict.subdicts = append(dict.subdicts, newInfo)
327 return idx
328 }
329
330
331
332
333 func (dict *writerDict) rtypeIdx(newInfo typeInfo) int {
334 for idx, oldInfo := range dict.rtypes {
335 if oldInfo == newInfo {
336 return idx
337 }
338 }
339
340 idx := len(dict.rtypes)
341 dict.rtypes = append(dict.rtypes, newInfo)
342 return idx
343 }
344
345
346
347
348 func (dict *writerDict) itabIdx(typInfo, ifaceInfo typeInfo) int {
349 newInfo := itabInfo{typInfo, ifaceInfo}
350
351 for idx, oldInfo := range dict.itabs {
352 if oldInfo == newInfo {
353 return idx
354 }
355 }
356
357 idx := len(dict.itabs)
358 dict.itabs = append(dict.itabs, newInfo)
359 return idx
360 }
361
362 func (pw *pkgWriter) newWriter(k pkgbits.RelocKind, marker pkgbits.SyncMarker) *writer {
363 return &writer{
364 Encoder: pw.NewEncoder(k, marker),
365 p: pw,
366 }
367 }
368
369
370
371
372 func (w *writer) pos(p poser) {
373 w.Sync(pkgbits.SyncPos)
374 pos := p.Pos()
375
376
377 if !w.Bool(pos.IsKnown()) {
378 return
379 }
380
381
382 w.posBase(pos.Base())
383 w.Uint(pos.Line())
384 w.Uint(pos.Col())
385 }
386
387
388
389 func (w *writer) posBase(b *syntax.PosBase) {
390 w.Reloc(pkgbits.RelocPosBase, w.p.posBaseIdx(b))
391 }
392
393
394 func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) pkgbits.Index {
395 if idx, ok := pw.posBasesIdx[b]; ok {
396 return idx
397 }
398
399 w := pw.newWriter(pkgbits.RelocPosBase, pkgbits.SyncPosBase)
400 w.p.posBasesIdx[b] = w.Idx
401
402 w.String(trimFilename(b))
403
404 if !w.Bool(b.IsFileBase()) {
405 w.pos(b)
406 w.Uint(b.Line())
407 w.Uint(b.Col())
408 }
409
410 return w.Flush()
411 }
412
413
414
415
416 func (w *writer) pkg(pkg *types2.Package) {
417 w.pkgRef(w.p.pkgIdx(pkg))
418 }
419
420 func (w *writer) pkgRef(idx pkgbits.Index) {
421 w.Sync(pkgbits.SyncPkg)
422 w.Reloc(pkgbits.RelocPkg, idx)
423 }
424
425
426
427 func (pw *pkgWriter) pkgIdx(pkg *types2.Package) pkgbits.Index {
428 if idx, ok := pw.pkgsIdx[pkg]; ok {
429 return idx
430 }
431
432 w := pw.newWriter(pkgbits.RelocPkg, pkgbits.SyncPkgDef)
433 pw.pkgsIdx[pkg] = w.Idx
434
435
436
437
438
439 switch pkg {
440 case nil:
441 w.String("builtin")
442 case types2.Unsafe:
443 w.String("unsafe")
444 default:
445
446 var path string
447 if pkg != w.p.curpkg {
448 path = pkg.Path()
449 }
450 base.Assertf(path != "builtin" && path != "unsafe", "unexpected path for user-defined package: %q", path)
451 w.String(path)
452 w.String(pkg.Name())
453
454 w.Len(len(pkg.Imports()))
455 for _, imp := range pkg.Imports() {
456 w.pkg(imp)
457 }
458 }
459
460 return w.Flush()
461 }
462
463
464
465 var (
466 anyTypeName = types2.Universe.Lookup("any").(*types2.TypeName)
467 comparableTypeName = types2.Universe.Lookup("comparable").(*types2.TypeName)
468 runeTypeName = types2.Universe.Lookup("rune").(*types2.TypeName)
469 )
470
471
472 func (w *writer) typ(typ types2.Type) {
473 w.typInfo(w.p.typIdx(typ, w.dict))
474 }
475
476
477
478 func (w *writer) typInfo(info typeInfo) {
479 w.Sync(pkgbits.SyncType)
480 if w.Bool(info.derived) {
481 w.Len(int(info.idx))
482 w.derived = true
483 } else {
484 w.Reloc(pkgbits.RelocType, info.idx)
485 }
486 }
487
488
489
490
491
492
493 func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
494
495
496
497
498 for {
499 if alias, ok := typ.(*types2.Alias); ok && !isGlobal(alias.Obj()) {
500 typ = alias.Rhs()
501 } else {
502 break
503 }
504 }
505
506 if idx, ok := pw.typsIdx[typ]; ok {
507 return typeInfo{idx: idx, derived: false}
508 }
509 if dict != nil {
510 if idx, ok := dict.derivedIdx[typ]; ok {
511 return typeInfo{idx: idx, derived: true}
512 }
513 }
514
515 w := pw.newWriter(pkgbits.RelocType, pkgbits.SyncTypeIdx)
516 w.dict = dict
517
518 switch typ := typ.(type) {
519 default:
520 base.Fatalf("unexpected type: %v (%T)", typ, typ)
521
522 case *types2.Basic:
523 switch kind := typ.Kind(); {
524 case kind == types2.Invalid:
525 base.Fatalf("unexpected types2.Invalid")
526
527 case types2.Typ[kind] == typ:
528 w.Code(pkgbits.TypeBasic)
529 w.Len(int(kind))
530
531 default:
532
533 obj := types2.Universe.Lookup(typ.Name()).(*types2.TypeName)
534 assert(obj.Type() == typ)
535
536 w.Code(pkgbits.TypeNamed)
537 w.namedType(obj, nil)
538 }
539
540 case *types2.Named:
541 w.Code(pkgbits.TypeNamed)
542 w.namedType(splitNamed(typ))
543
544 case *types2.Alias:
545 w.Code(pkgbits.TypeNamed)
546 w.namedType(splitAlias(typ))
547
548 case *types2.TypeParam:
549 w.derived = true
550 w.Code(pkgbits.TypeTypeParam)
551 w.Len(w.dict.typeParamIndex(typ))
552
553 case *types2.Array:
554 w.Code(pkgbits.TypeArray)
555 w.Uint64(uint64(typ.Len()))
556 w.typ(typ.Elem())
557
558 case *types2.Chan:
559 w.Code(pkgbits.TypeChan)
560 w.Len(int(typ.Dir()))
561 w.typ(typ.Elem())
562
563 case *types2.Map:
564 w.Code(pkgbits.TypeMap)
565 w.typ(typ.Key())
566 w.typ(typ.Elem())
567
568 case *types2.Pointer:
569 w.Code(pkgbits.TypePointer)
570 w.typ(typ.Elem())
571
572 case *types2.Signature:
573 base.Assertf(typ.TypeParams() == nil, "unexpected type params: %v", typ)
574 w.Code(pkgbits.TypeSignature)
575 w.signature(typ)
576
577 case *types2.Slice:
578 w.Code(pkgbits.TypeSlice)
579 w.typ(typ.Elem())
580
581 case *types2.Struct:
582 w.Code(pkgbits.TypeStruct)
583 w.structType(typ)
584
585 case *types2.Interface:
586
587
588
589
590 if types2.Unalias(typ) == types2.Unalias(anyTypeName.Type()) {
591 w.Code(pkgbits.TypeNamed)
592 w.obj(anyTypeName, nil)
593 break
594 }
595
596 w.Code(pkgbits.TypeInterface)
597 w.interfaceType(typ)
598
599 case *types2.Union:
600 w.Code(pkgbits.TypeUnion)
601 w.unionType(typ)
602 }
603
604 if w.derived {
605 idx := pkgbits.Index(len(dict.derived))
606 dict.derived = append(dict.derived, derivedInfo{idx: w.Flush()})
607 dict.derivedIdx[typ] = idx
608 return typeInfo{idx: idx, derived: true}
609 }
610
611 pw.typsIdx[typ] = w.Idx
612 return typeInfo{idx: w.Flush(), derived: false}
613 }
614
615
616 func (w *writer) namedType(obj *types2.TypeName, targs *types2.TypeList) {
617
618
619 if w.p.hasImplicitTypeParams(obj) {
620 w.derived = true
621 }
622
623 w.obj(obj, targs)
624 }
625
626 func (w *writer) structType(typ *types2.Struct) {
627 w.Len(typ.NumFields())
628 for i := 0; i < typ.NumFields(); i++ {
629 f := typ.Field(i)
630 w.pos(f)
631 w.selector(f)
632 w.typ(f.Type())
633 w.String(typ.Tag(i))
634 w.Bool(f.Embedded())
635 }
636 }
637
638 func (w *writer) unionType(typ *types2.Union) {
639 w.Len(typ.Len())
640 for i := 0; i < typ.Len(); i++ {
641 t := typ.Term(i)
642 w.Bool(t.Tilde())
643 w.typ(t.Type())
644 }
645 }
646
647 func (w *writer) interfaceType(typ *types2.Interface) {
648
649
650
651 if typ.NumEmbeddeds() == 0 && !typ.IsMethodSet() {
652
653
654
655 assert(typ == comparableTypeName.Type().(*types2.Named).Underlying())
656
657
658 w.Len(0)
659 w.Len(1)
660 w.Bool(false)
661 w.typ(comparableTypeName.Type())
662 return
663 }
664
665 w.Len(typ.NumExplicitMethods())
666 w.Len(typ.NumEmbeddeds())
667
668 if typ.NumExplicitMethods() == 0 && typ.NumEmbeddeds() == 1 {
669 w.Bool(typ.IsImplicit())
670 } else {
671
672
673
674 assert(!typ.IsImplicit())
675 }
676
677 for i := 0; i < typ.NumExplicitMethods(); i++ {
678 m := typ.ExplicitMethod(i)
679 sig := m.Type().(*types2.Signature)
680 assert(sig.TypeParams() == nil)
681
682 w.pos(m)
683 w.selector(m)
684 w.signature(sig)
685 }
686
687 for i := 0; i < typ.NumEmbeddeds(); i++ {
688 w.typ(typ.EmbeddedType(i))
689 }
690 }
691
692 func (w *writer) signature(sig *types2.Signature) {
693 w.Sync(pkgbits.SyncSignature)
694 w.params(sig.Params())
695 w.params(sig.Results())
696 w.Bool(sig.Variadic())
697 }
698
699 func (w *writer) params(typ *types2.Tuple) {
700 w.Sync(pkgbits.SyncParams)
701 w.Len(typ.Len())
702 for i := 0; i < typ.Len(); i++ {
703 w.param(typ.At(i))
704 }
705 }
706
707 func (w *writer) param(param *types2.Var) {
708 w.Sync(pkgbits.SyncParam)
709 w.pos(param)
710 w.localIdent(param)
711 w.typ(param.Type())
712 }
713
714
715
716
717
718
719
720
721 func (w *writer) obj(obj types2.Object, explicits *types2.TypeList) {
722 w.objInfo(w.p.objInstIdx(obj, explicits, w.dict))
723 }
724
725
726
727 func (w *writer) objInfo(info objInfo) {
728 w.Sync(pkgbits.SyncObject)
729 w.Bool(false)
730 w.Reloc(pkgbits.RelocObj, info.idx)
731
732 w.Len(len(info.explicits))
733 for _, info := range info.explicits {
734 w.typInfo(info)
735 }
736 }
737
738
739
740
741 func (pw *pkgWriter) objInstIdx(obj types2.Object, explicits *types2.TypeList, dict *writerDict) objInfo {
742 explicitInfos := make([]typeInfo, explicits.Len())
743 for i := range explicitInfos {
744 explicitInfos[i] = pw.typIdx(explicits.At(i), dict)
745 }
746 return objInfo{idx: pw.objIdx(obj), explicits: explicitInfos}
747 }
748
749
750
751 func (pw *pkgWriter) objIdx(obj types2.Object) pkgbits.Index {
752
753
754
755 if idx, ok := pw.objsIdx[obj]; ok {
756 return idx
757 }
758
759 dict := &writerDict{
760 derivedIdx: make(map[types2.Type]pkgbits.Index),
761 }
762
763 if isDefinedType(obj) && obj.Pkg() == pw.curpkg {
764 decl, ok := pw.typDecls[obj.(*types2.TypeName)]
765 assert(ok)
766 dict.implicits = decl.implicits
767 }
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792 w := pw.newWriter(pkgbits.RelocObj, pkgbits.SyncObject1)
793 wext := pw.newWriter(pkgbits.RelocObjExt, pkgbits.SyncObject1)
794 wname := pw.newWriter(pkgbits.RelocName, pkgbits.SyncObject1)
795 wdict := pw.newWriter(pkgbits.RelocObjDict, pkgbits.SyncObject1)
796
797 pw.objsIdx[obj] = w.Idx
798 assert(wext.Idx == w.Idx)
799 assert(wname.Idx == w.Idx)
800 assert(wdict.Idx == w.Idx)
801
802 w.dict = dict
803 wext.dict = dict
804
805 code := w.doObj(wext, obj)
806 w.Flush()
807 wext.Flush()
808
809 wname.qualifiedIdent(obj)
810 wname.Code(code)
811 wname.Flush()
812
813 wdict.objDict(obj, w.dict)
814 wdict.Flush()
815
816 return w.Idx
817 }
818
819
820
821 func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
822 if obj.Pkg() != w.p.curpkg {
823 return pkgbits.ObjStub
824 }
825
826 switch obj := obj.(type) {
827 default:
828 w.p.unexpected("object", obj)
829 panic("unreachable")
830
831 case *types2.Const:
832 w.pos(obj)
833 w.typ(obj.Type())
834 w.Value(obj.Val())
835 return pkgbits.ObjConst
836
837 case *types2.Func:
838 decl, ok := w.p.funDecls[obj]
839 assert(ok)
840 sig := obj.Type().(*types2.Signature)
841
842 w.pos(obj)
843 w.typeParamNames(sig.TypeParams())
844 w.signature(sig)
845 w.pos(decl)
846 wext.funcExt(obj)
847 return pkgbits.ObjFunc
848
849 case *types2.TypeName:
850 if obj.IsAlias() {
851 w.pos(obj)
852 t := obj.Type()
853 if alias, ok := t.(*types2.Alias); ok {
854 t = alias.Rhs()
855 }
856 w.typ(t)
857 return pkgbits.ObjAlias
858 }
859
860 named := obj.Type().(*types2.Named)
861 assert(named.TypeArgs() == nil)
862
863 w.pos(obj)
864 w.typeParamNames(named.TypeParams())
865 wext.typeExt(obj)
866 w.typ(named.Underlying())
867
868 w.Len(named.NumMethods())
869 for i := 0; i < named.NumMethods(); i++ {
870 w.method(wext, named.Method(i))
871 }
872
873 return pkgbits.ObjType
874
875 case *types2.Var:
876 w.pos(obj)
877 w.typ(obj.Type())
878 wext.varExt(obj)
879 return pkgbits.ObjVar
880 }
881 }
882
883
884 func (w *writer) objDict(obj types2.Object, dict *writerDict) {
885
886
887
888
889 w.dict = dict
890
891 w.Len(len(dict.implicits))
892
893 tparams := objTypeParams(obj)
894 ntparams := tparams.Len()
895 w.Len(ntparams)
896 for i := 0; i < ntparams; i++ {
897 w.typ(tparams.At(i).Constraint())
898 }
899
900 nderived := len(dict.derived)
901 w.Len(nderived)
902 for _, typ := range dict.derived {
903 w.Reloc(pkgbits.RelocType, typ.idx)
904 w.Bool(typ.needed)
905 }
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922 for _, implicit := range dict.implicits {
923 w.Bool(implicit.Underlying().(*types2.Interface).IsMethodSet())
924 }
925 for i := 0; i < ntparams; i++ {
926 tparam := tparams.At(i)
927 w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet())
928 }
929
930 w.Len(len(dict.typeParamMethodExprs))
931 for _, info := range dict.typeParamMethodExprs {
932 w.Len(info.typeParamIdx)
933 w.selectorInfo(info.methodInfo)
934 }
935
936 w.Len(len(dict.subdicts))
937 for _, info := range dict.subdicts {
938 w.objInfo(info)
939 }
940
941 w.Len(len(dict.rtypes))
942 for _, info := range dict.rtypes {
943 w.typInfo(info)
944 }
945
946 w.Len(len(dict.itabs))
947 for _, info := range dict.itabs {
948 w.typInfo(info.typ)
949 w.typInfo(info.iface)
950 }
951
952 assert(len(dict.derived) == nderived)
953 }
954
955 func (w *writer) typeParamNames(tparams *types2.TypeParamList) {
956 w.Sync(pkgbits.SyncTypeParamNames)
957
958 ntparams := tparams.Len()
959 for i := 0; i < ntparams; i++ {
960 tparam := tparams.At(i).Obj()
961 w.pos(tparam)
962 w.localIdent(tparam)
963 }
964 }
965
966 func (w *writer) method(wext *writer, meth *types2.Func) {
967 decl, ok := w.p.funDecls[meth]
968 assert(ok)
969 sig := meth.Type().(*types2.Signature)
970
971 w.Sync(pkgbits.SyncMethod)
972 w.pos(meth)
973 w.selector(meth)
974 w.typeParamNames(sig.RecvTypeParams())
975 w.param(sig.Recv())
976 w.signature(sig)
977
978 w.pos(decl)
979 wext.funcExt(meth)
980 }
981
982
983
984 func (w *writer) qualifiedIdent(obj types2.Object) {
985 w.Sync(pkgbits.SyncSym)
986
987 name := obj.Name()
988 if isDefinedType(obj) && obj.Pkg() == w.p.curpkg {
989 decl, ok := w.p.typDecls[obj.(*types2.TypeName)]
990 assert(ok)
991 if decl.gen != 0 {
992
993
994
995
996
997 name = fmt.Sprintf("%s·%v", name, decl.gen)
998 }
999 }
1000
1001 w.pkg(obj.Pkg())
1002 w.String(name)
1003 }
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013 func (w *writer) localIdent(obj types2.Object) {
1014 assert(!isGlobal(obj))
1015 w.Sync(pkgbits.SyncLocalIdent)
1016 w.pkg(obj.Pkg())
1017 w.String(obj.Name())
1018 }
1019
1020
1021
1022 func (w *writer) selector(obj types2.Object) {
1023 w.selectorInfo(w.p.selectorIdx(obj))
1024 }
1025
1026 func (w *writer) selectorInfo(info selectorInfo) {
1027 w.Sync(pkgbits.SyncSelector)
1028 w.pkgRef(info.pkgIdx)
1029 w.StringRef(info.nameIdx)
1030 }
1031
1032 func (pw *pkgWriter) selectorIdx(obj types2.Object) selectorInfo {
1033 pkgIdx := pw.pkgIdx(obj.Pkg())
1034 nameIdx := pw.StringIdx(obj.Name())
1035 return selectorInfo{pkgIdx: pkgIdx, nameIdx: nameIdx}
1036 }
1037
1038
1039
1040 func (w *writer) funcExt(obj *types2.Func) {
1041 decl, ok := w.p.funDecls[obj]
1042 assert(ok)
1043
1044
1045
1046
1047
1048 pragma := asPragmaFlag(decl.Pragma)
1049 if pragma&ir.Systemstack != 0 && pragma&ir.Nosplit != 0 {
1050 w.p.errorf(decl, "go:nosplit and go:systemstack cannot be combined")
1051 }
1052 wi := asWasmImport(decl.Pragma)
1053
1054 if decl.Body != nil {
1055 if pragma&ir.Noescape != 0 {
1056 w.p.errorf(decl, "can only use //go:noescape with external func implementations")
1057 }
1058 if wi != nil {
1059 w.p.errorf(decl, "can only use //go:wasmimport with external func implementations")
1060 }
1061 if (pragma&ir.UintptrKeepAlive != 0 && pragma&ir.UintptrEscapes == 0) && pragma&ir.Nosplit == 0 {
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 w.p.errorf(decl, "go:uintptrkeepalive requires go:nosplit")
1076 }
1077 } else {
1078 if base.Flag.Complete || decl.Name.Value == "init" {
1079
1080
1081
1082 if _, ok := w.p.linknames[obj]; !ok && wi == nil {
1083 w.p.errorf(decl, "missing function body")
1084 }
1085 }
1086 }
1087
1088 sig, block := obj.Type().(*types2.Signature), decl.Body
1089 body, closureVars := w.p.bodyIdx(sig, block, w.dict)
1090 if len(closureVars) > 0 {
1091 fmt.Fprintln(os.Stderr, "CLOSURE", closureVars)
1092 }
1093 assert(len(closureVars) == 0)
1094
1095 w.Sync(pkgbits.SyncFuncExt)
1096 w.pragmaFlag(pragma)
1097 w.linkname(obj)
1098
1099 if buildcfg.GOARCH == "wasm" {
1100 if wi != nil {
1101 w.String(wi.Module)
1102 w.String(wi.Name)
1103 } else {
1104 w.String("")
1105 w.String("")
1106 }
1107 }
1108
1109 w.Bool(false)
1110 w.Reloc(pkgbits.RelocBody, body)
1111 w.Sync(pkgbits.SyncEOF)
1112 }
1113
1114 func (w *writer) typeExt(obj *types2.TypeName) {
1115 decl, ok := w.p.typDecls[obj]
1116 assert(ok)
1117
1118 w.Sync(pkgbits.SyncTypeExt)
1119
1120 w.pragmaFlag(asPragmaFlag(decl.Pragma))
1121
1122
1123 w.Int64(-1)
1124 w.Int64(-1)
1125 }
1126
1127 func (w *writer) varExt(obj *types2.Var) {
1128 w.Sync(pkgbits.SyncVarExt)
1129 w.linkname(obj)
1130 }
1131
1132 func (w *writer) linkname(obj types2.Object) {
1133 w.Sync(pkgbits.SyncLinkname)
1134 w.Int64(-1)
1135 w.String(w.p.linknames[obj])
1136 }
1137
1138 func (w *writer) pragmaFlag(p ir.PragmaFlag) {
1139 w.Sync(pkgbits.SyncPragma)
1140 w.Int(int(p))
1141 }
1142
1143
1144
1145
1146
1147 func (pw *pkgWriter) bodyIdx(sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx pkgbits.Index, closureVars []posVar) {
1148 w := pw.newWriter(pkgbits.RelocBody, pkgbits.SyncFuncBody)
1149 w.sig = sig
1150 w.dict = dict
1151
1152 w.declareParams(sig)
1153 if w.Bool(block != nil) {
1154 w.stmts(block.List)
1155 w.pos(block.Rbrace)
1156 }
1157
1158 return w.Flush(), w.closureVars
1159 }
1160
1161 func (w *writer) declareParams(sig *types2.Signature) {
1162 addLocals := func(params *types2.Tuple) {
1163 for i := 0; i < params.Len(); i++ {
1164 w.addLocal(params.At(i))
1165 }
1166 }
1167
1168 if recv := sig.Recv(); recv != nil {
1169 w.addLocal(recv)
1170 }
1171 addLocals(sig.Params())
1172 addLocals(sig.Results())
1173 }
1174
1175
1176 func (w *writer) addLocal(obj *types2.Var) {
1177 idx := len(w.localsIdx)
1178
1179 w.Sync(pkgbits.SyncAddLocal)
1180 if w.p.SyncMarkers() {
1181 w.Int(idx)
1182 }
1183 w.varDictIndex(obj)
1184
1185 if w.localsIdx == nil {
1186 w.localsIdx = make(map[*types2.Var]int)
1187 }
1188 w.localsIdx[obj] = idx
1189 }
1190
1191
1192
1193 func (w *writer) useLocal(pos syntax.Pos, obj *types2.Var) {
1194 w.Sync(pkgbits.SyncUseObjLocal)
1195
1196 if idx, ok := w.localsIdx[obj]; w.Bool(ok) {
1197 w.Len(idx)
1198 return
1199 }
1200
1201 idx, ok := w.closureVarsIdx[obj]
1202 if !ok {
1203 if w.closureVarsIdx == nil {
1204 w.closureVarsIdx = make(map[*types2.Var]int)
1205 }
1206 idx = len(w.closureVars)
1207 w.closureVars = append(w.closureVars, posVar{pos, obj})
1208 w.closureVarsIdx[obj] = idx
1209 }
1210 w.Len(idx)
1211 }
1212
1213 func (w *writer) openScope(pos syntax.Pos) {
1214 w.Sync(pkgbits.SyncOpenScope)
1215 w.pos(pos)
1216 }
1217
1218 func (w *writer) closeScope(pos syntax.Pos) {
1219 w.Sync(pkgbits.SyncCloseScope)
1220 w.pos(pos)
1221 w.closeAnotherScope()
1222 }
1223
1224 func (w *writer) closeAnotherScope() {
1225 w.Sync(pkgbits.SyncCloseAnotherScope)
1226 }
1227
1228
1229
1230
1231 func (w *writer) stmt(stmt syntax.Stmt) {
1232 var stmts []syntax.Stmt
1233 if stmt != nil {
1234 stmts = []syntax.Stmt{stmt}
1235 }
1236 w.stmts(stmts)
1237 }
1238
1239 func (w *writer) stmts(stmts []syntax.Stmt) {
1240 dead := false
1241 w.Sync(pkgbits.SyncStmts)
1242 var lastLabel = -1
1243 for i, stmt := range stmts {
1244 if _, ok := stmt.(*syntax.LabeledStmt); ok {
1245 lastLabel = i
1246 }
1247 }
1248 for i, stmt := range stmts {
1249 if dead && i > lastLabel {
1250
1251
1252
1253 if _, ok := stmt.(*syntax.LabeledStmt); !ok {
1254 continue
1255 }
1256 }
1257 w.stmt1(stmt)
1258 dead = w.p.terminates(stmt)
1259 }
1260 w.Code(stmtEnd)
1261 w.Sync(pkgbits.SyncStmtsEnd)
1262 }
1263
1264 func (w *writer) stmt1(stmt syntax.Stmt) {
1265 switch stmt := stmt.(type) {
1266 default:
1267 w.p.unexpected("statement", stmt)
1268
1269 case nil, *syntax.EmptyStmt:
1270 return
1271
1272 case *syntax.AssignStmt:
1273 switch {
1274 case stmt.Rhs == nil:
1275 w.Code(stmtIncDec)
1276 w.op(binOps[stmt.Op])
1277 w.expr(stmt.Lhs)
1278 w.pos(stmt)
1279
1280 case stmt.Op != 0 && stmt.Op != syntax.Def:
1281 w.Code(stmtAssignOp)
1282 w.op(binOps[stmt.Op])
1283 w.expr(stmt.Lhs)
1284 w.pos(stmt)
1285
1286 var typ types2.Type
1287 if stmt.Op != syntax.Shl && stmt.Op != syntax.Shr {
1288 typ = w.p.typeOf(stmt.Lhs)
1289 }
1290 w.implicitConvExpr(typ, stmt.Rhs)
1291
1292 default:
1293 w.assignStmt(stmt, stmt.Lhs, stmt.Rhs)
1294 }
1295
1296 case *syntax.BlockStmt:
1297 w.Code(stmtBlock)
1298 w.blockStmt(stmt)
1299
1300 case *syntax.BranchStmt:
1301 w.Code(stmtBranch)
1302 w.pos(stmt)
1303 w.op(branchOps[stmt.Tok])
1304 w.optLabel(stmt.Label)
1305
1306 case *syntax.CallStmt:
1307 w.Code(stmtCall)
1308 w.pos(stmt)
1309 w.op(callOps[stmt.Tok])
1310 w.expr(stmt.Call)
1311 if stmt.Tok == syntax.Defer {
1312 w.optExpr(stmt.DeferAt)
1313 }
1314
1315 case *syntax.DeclStmt:
1316 for _, decl := range stmt.DeclList {
1317 w.declStmt(decl)
1318 }
1319
1320 case *syntax.ExprStmt:
1321 w.Code(stmtExpr)
1322 w.expr(stmt.X)
1323
1324 case *syntax.ForStmt:
1325 w.Code(stmtFor)
1326 w.forStmt(stmt)
1327
1328 case *syntax.IfStmt:
1329 w.Code(stmtIf)
1330 w.ifStmt(stmt)
1331
1332 case *syntax.LabeledStmt:
1333 w.Code(stmtLabel)
1334 w.pos(stmt)
1335 w.label(stmt.Label)
1336 w.stmt1(stmt.Stmt)
1337
1338 case *syntax.ReturnStmt:
1339 w.Code(stmtReturn)
1340 w.pos(stmt)
1341
1342 resultTypes := w.sig.Results()
1343 dstType := func(i int) types2.Type {
1344 return resultTypes.At(i).Type()
1345 }
1346 w.multiExpr(stmt, dstType, syntax.UnpackListExpr(stmt.Results))
1347
1348 case *syntax.SelectStmt:
1349 w.Code(stmtSelect)
1350 w.selectStmt(stmt)
1351
1352 case *syntax.SendStmt:
1353 chanType := types2.CoreType(w.p.typeOf(stmt.Chan)).(*types2.Chan)
1354
1355 w.Code(stmtSend)
1356 w.pos(stmt)
1357 w.expr(stmt.Chan)
1358 w.implicitConvExpr(chanType.Elem(), stmt.Value)
1359
1360 case *syntax.SwitchStmt:
1361 w.Code(stmtSwitch)
1362 w.switchStmt(stmt)
1363 }
1364 }
1365
1366 func (w *writer) assignList(expr syntax.Expr) {
1367 exprs := syntax.UnpackListExpr(expr)
1368 w.Len(len(exprs))
1369
1370 for _, expr := range exprs {
1371 w.assign(expr)
1372 }
1373 }
1374
1375 func (w *writer) assign(expr syntax.Expr) {
1376 expr = syntax.Unparen(expr)
1377
1378 if name, ok := expr.(*syntax.Name); ok {
1379 if name.Value == "_" {
1380 w.Code(assignBlank)
1381 return
1382 }
1383
1384 if obj, ok := w.p.info.Defs[name]; ok {
1385 obj := obj.(*types2.Var)
1386
1387 w.Code(assignDef)
1388 w.pos(obj)
1389 w.localIdent(obj)
1390 w.typ(obj.Type())
1391
1392
1393
1394 w.addLocal(obj)
1395 return
1396 }
1397 }
1398
1399 w.Code(assignExpr)
1400 w.expr(expr)
1401 }
1402
1403 func (w *writer) declStmt(decl syntax.Decl) {
1404 switch decl := decl.(type) {
1405 default:
1406 w.p.unexpected("declaration", decl)
1407
1408 case *syntax.ConstDecl, *syntax.TypeDecl:
1409
1410 case *syntax.VarDecl:
1411 w.assignStmt(decl, namesAsExpr(decl.NameList), decl.Values)
1412 }
1413 }
1414
1415
1416 func (w *writer) assignStmt(pos poser, lhs0, rhs0 syntax.Expr) {
1417 lhs := syntax.UnpackListExpr(lhs0)
1418 rhs := syntax.UnpackListExpr(rhs0)
1419
1420 w.Code(stmtAssign)
1421 w.pos(pos)
1422
1423
1424 w.Len(len(lhs))
1425 for _, expr := range lhs {
1426 w.assign(expr)
1427 }
1428
1429 dstType := func(i int) types2.Type {
1430 dst := lhs[i]
1431
1432
1433
1434
1435 if name, ok := syntax.Unparen(dst).(*syntax.Name); ok {
1436 if name.Value == "_" {
1437 return nil
1438 } else if def, ok := w.p.info.Defs[name].(*types2.Var); ok {
1439 return def.Type()
1440 } else if use, ok := w.p.info.Uses[name].(*types2.Var); ok {
1441 return use.Type()
1442 } else {
1443 w.p.fatalf(dst, "cannot find type of destination object: %v", dst)
1444 }
1445 }
1446
1447 return w.p.typeOf(dst)
1448 }
1449
1450 w.multiExpr(pos, dstType, rhs)
1451 }
1452
1453 func (w *writer) blockStmt(stmt *syntax.BlockStmt) {
1454 w.Sync(pkgbits.SyncBlockStmt)
1455 w.openScope(stmt.Pos())
1456 w.stmts(stmt.List)
1457 w.closeScope(stmt.Rbrace)
1458 }
1459
1460 func (w *writer) forStmt(stmt *syntax.ForStmt) {
1461 w.Sync(pkgbits.SyncForStmt)
1462 w.openScope(stmt.Pos())
1463
1464 if rang, ok := stmt.Init.(*syntax.RangeClause); w.Bool(ok) {
1465 w.pos(rang)
1466 w.assignList(rang.Lhs)
1467 w.expr(rang.X)
1468
1469 xtyp := w.p.typeOf(rang.X)
1470 if _, isMap := types2.CoreType(xtyp).(*types2.Map); isMap {
1471 w.rtype(xtyp)
1472 }
1473 {
1474 lhs := syntax.UnpackListExpr(rang.Lhs)
1475 assign := func(i int, src types2.Type) {
1476 if i >= len(lhs) {
1477 return
1478 }
1479 dst := syntax.Unparen(lhs[i])
1480 if name, ok := dst.(*syntax.Name); ok && name.Value == "_" {
1481 return
1482 }
1483
1484 var dstType types2.Type
1485 if rang.Def {
1486
1487
1488 dstType = w.p.info.Defs[dst.(*syntax.Name)].(*types2.Var).Type()
1489 } else {
1490 dstType = w.p.typeOf(dst)
1491 }
1492
1493 w.convRTTI(src, dstType)
1494 }
1495
1496 keyType, valueType := types2.RangeKeyVal(w.p.typeOf(rang.X))
1497 assign(0, keyType)
1498 assign(1, valueType)
1499 }
1500
1501 } else {
1502 if stmt.Cond != nil && w.p.staticBool(&stmt.Cond) < 0 {
1503 stmt.Post = nil
1504 stmt.Body.List = nil
1505 }
1506
1507 w.pos(stmt)
1508 w.stmt(stmt.Init)
1509 w.optExpr(stmt.Cond)
1510 w.stmt(stmt.Post)
1511 }
1512
1513 w.blockStmt(stmt.Body)
1514 w.Bool(w.distinctVars(stmt))
1515 w.closeAnotherScope()
1516 }
1517
1518 func (w *writer) distinctVars(stmt *syntax.ForStmt) bool {
1519 lv := base.Debug.LoopVar
1520 fileVersion := w.p.info.FileVersions[stmt.Pos().Base()]
1521 is122 := fileVersion == "" || version.Compare(fileVersion, "go1.22") >= 0
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534 return is122 || lv > 0 && lv != 3
1535 }
1536
1537 func (w *writer) ifStmt(stmt *syntax.IfStmt) {
1538 cond := w.p.staticBool(&stmt.Cond)
1539
1540 w.Sync(pkgbits.SyncIfStmt)
1541 w.openScope(stmt.Pos())
1542 w.pos(stmt)
1543 w.stmt(stmt.Init)
1544 w.expr(stmt.Cond)
1545 w.Int(cond)
1546 if cond >= 0 {
1547 w.blockStmt(stmt.Then)
1548 } else {
1549 w.pos(stmt.Then.Rbrace)
1550 }
1551 if cond <= 0 {
1552 w.stmt(stmt.Else)
1553 }
1554 w.closeAnotherScope()
1555 }
1556
1557 func (w *writer) selectStmt(stmt *syntax.SelectStmt) {
1558 w.Sync(pkgbits.SyncSelectStmt)
1559
1560 w.pos(stmt)
1561 w.Len(len(stmt.Body))
1562 for i, clause := range stmt.Body {
1563 if i > 0 {
1564 w.closeScope(clause.Pos())
1565 }
1566 w.openScope(clause.Pos())
1567
1568 w.pos(clause)
1569 w.stmt(clause.Comm)
1570 w.stmts(clause.Body)
1571 }
1572 if len(stmt.Body) > 0 {
1573 w.closeScope(stmt.Rbrace)
1574 }
1575 }
1576
1577 func (w *writer) switchStmt(stmt *syntax.SwitchStmt) {
1578 w.Sync(pkgbits.SyncSwitchStmt)
1579
1580 w.openScope(stmt.Pos())
1581 w.pos(stmt)
1582 w.stmt(stmt.Init)
1583
1584 var iface, tagType types2.Type
1585 var tagTypeIsChan bool
1586 if guard, ok := stmt.Tag.(*syntax.TypeSwitchGuard); w.Bool(ok) {
1587 iface = w.p.typeOf(guard.X)
1588
1589 w.pos(guard)
1590 if tag := guard.Lhs; w.Bool(tag != nil) {
1591 w.pos(tag)
1592
1593
1594 w.Sync(pkgbits.SyncLocalIdent)
1595 w.pkg(w.p.curpkg)
1596 w.String(tag.Value)
1597 }
1598 w.expr(guard.X)
1599 } else {
1600 tag := stmt.Tag
1601
1602 var tagValue constant.Value
1603 if tag != nil {
1604 tv := w.p.typeAndValue(tag)
1605 tagType = tv.Type
1606 tagValue = tv.Value
1607 _, tagTypeIsChan = tagType.Underlying().(*types2.Chan)
1608 } else {
1609 tagType = types2.Typ[types2.Bool]
1610 tagValue = constant.MakeBool(true)
1611 }
1612
1613 if tagValue != nil {
1614
1615
1616 func() {
1617 var target *syntax.CaseClause
1618 Outer:
1619 for _, clause := range stmt.Body {
1620 if clause.Cases == nil {
1621 target = clause
1622 }
1623 for _, cas := range syntax.UnpackListExpr(clause.Cases) {
1624 tv := w.p.typeAndValue(cas)
1625 if tv.Value == nil {
1626 return
1627 }
1628 if constant.Compare(tagValue, token.EQL, tv.Value) {
1629 target = clause
1630 break Outer
1631 }
1632 }
1633 }
1634
1635
1636 if target != nil {
1637 if hasFallthrough(target.Body) {
1638 return
1639 }
1640
1641
1642 target.Cases = nil
1643 stmt.Body = []*syntax.CaseClause{target}
1644 } else {
1645 stmt.Body = nil
1646 }
1647
1648
1649 tag = nil
1650 stmt.Tag = nil
1651 tagType = types2.Typ[types2.Bool]
1652 }()
1653 }
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664 if !tagTypeIsChan {
1665 Outer:
1666 for _, clause := range stmt.Body {
1667 for _, cas := range syntax.UnpackListExpr(clause.Cases) {
1668 if casType := w.p.typeOf(cas); !types2.AssignableTo(casType, tagType) {
1669 tagType = types2.NewInterfaceType(nil, nil)
1670 break Outer
1671 }
1672 }
1673 }
1674 }
1675
1676 if w.Bool(tag != nil) {
1677 w.implicitConvExpr(tagType, tag)
1678 }
1679 }
1680
1681 w.Len(len(stmt.Body))
1682 for i, clause := range stmt.Body {
1683 if i > 0 {
1684 w.closeScope(clause.Pos())
1685 }
1686 w.openScope(clause.Pos())
1687
1688 w.pos(clause)
1689
1690 cases := syntax.UnpackListExpr(clause.Cases)
1691 if iface != nil {
1692 w.Len(len(cases))
1693 for _, cas := range cases {
1694 if w.Bool(isNil(w.p, cas)) {
1695 continue
1696 }
1697 w.exprType(iface, cas)
1698 }
1699 } else {
1700
1701
1702
1703 w.Sync(pkgbits.SyncExprList)
1704 w.Sync(pkgbits.SyncExprs)
1705 w.Len(len(cases))
1706 for _, cas := range cases {
1707 typ := tagType
1708 if tagTypeIsChan {
1709 typ = nil
1710 }
1711 w.implicitConvExpr(typ, cas)
1712 }
1713 }
1714
1715 if obj, ok := w.p.info.Implicits[clause]; ok {
1716
1717
1718
1719
1720
1721 pos := clause.Pos()
1722 if typs := syntax.UnpackListExpr(clause.Cases); len(typs) != 0 {
1723 pos = typeExprEndPos(typs[len(typs)-1])
1724 }
1725 w.pos(pos)
1726
1727 obj := obj.(*types2.Var)
1728 w.typ(obj.Type())
1729 w.addLocal(obj)
1730 }
1731
1732 w.stmts(clause.Body)
1733 }
1734 if len(stmt.Body) > 0 {
1735 w.closeScope(stmt.Rbrace)
1736 }
1737
1738 w.closeScope(stmt.Rbrace)
1739 }
1740
1741 func (w *writer) label(label *syntax.Name) {
1742 w.Sync(pkgbits.SyncLabel)
1743
1744
1745 w.String(label.Value)
1746 }
1747
1748 func (w *writer) optLabel(label *syntax.Name) {
1749 w.Sync(pkgbits.SyncOptLabel)
1750 if w.Bool(label != nil) {
1751 w.label(label)
1752 }
1753 }
1754
1755
1756
1757
1758 func (w *writer) expr(expr syntax.Expr) {
1759 base.Assertf(expr != nil, "missing expression")
1760
1761 expr = syntax.Unparen(expr)
1762
1763 obj, inst := lookupObj(w.p, expr)
1764 targs := inst.TypeArgs
1765
1766 if tv, ok := w.p.maybeTypeAndValue(expr); ok {
1767 if tv.IsRuntimeHelper() {
1768 if pkg := obj.Pkg(); pkg != nil && pkg.Name() == "runtime" {
1769 objName := obj.Name()
1770 w.Code(exprRuntimeBuiltin)
1771 w.String(objName)
1772 return
1773 }
1774 }
1775
1776 if tv.IsType() {
1777 w.p.fatalf(expr, "unexpected type expression %v", syntax.String(expr))
1778 }
1779
1780 if tv.Value != nil {
1781 w.Code(exprConst)
1782 w.pos(expr)
1783 typ := idealType(tv)
1784 assert(typ != nil)
1785 w.typ(typ)
1786 w.Value(tv.Value)
1787 return
1788 }
1789
1790 if _, isNil := obj.(*types2.Nil); isNil {
1791 w.Code(exprZero)
1792 w.pos(expr)
1793 w.typ(tv.Type)
1794 return
1795 }
1796
1797
1798
1799
1800
1801 if typ := tv.Type; !tv.IsBuiltin() && !isTuple(typ) && !isUntyped(typ) {
1802 w.Code(exprReshape)
1803 w.typ(typ)
1804
1805 }
1806 }
1807
1808 if obj != nil {
1809 if targs.Len() != 0 {
1810 obj := obj.(*types2.Func)
1811
1812 w.Code(exprFuncInst)
1813 w.pos(expr)
1814 w.funcInst(obj, targs)
1815 return
1816 }
1817
1818 if isGlobal(obj) {
1819 w.Code(exprGlobal)
1820 w.obj(obj, nil)
1821 return
1822 }
1823
1824 obj := obj.(*types2.Var)
1825 assert(!obj.IsField())
1826
1827 w.Code(exprLocal)
1828 w.useLocal(expr.Pos(), obj)
1829 return
1830 }
1831
1832 switch expr := expr.(type) {
1833 default:
1834 w.p.unexpected("expression", expr)
1835
1836 case *syntax.CompositeLit:
1837 w.Code(exprCompLit)
1838 w.compLit(expr)
1839
1840 case *syntax.FuncLit:
1841 w.Code(exprFuncLit)
1842 w.funcLit(expr)
1843
1844 case *syntax.SelectorExpr:
1845 sel, ok := w.p.info.Selections[expr]
1846 assert(ok)
1847
1848 switch sel.Kind() {
1849 default:
1850 w.p.fatalf(expr, "unexpected selection kind: %v", sel.Kind())
1851
1852 case types2.FieldVal:
1853 w.Code(exprFieldVal)
1854 w.expr(expr.X)
1855 w.pos(expr)
1856 w.selector(sel.Obj())
1857
1858 case types2.MethodVal:
1859 w.Code(exprMethodVal)
1860 typ := w.recvExpr(expr, sel)
1861 w.pos(expr)
1862 w.methodExpr(expr, typ, sel)
1863
1864 case types2.MethodExpr:
1865 w.Code(exprMethodExpr)
1866
1867 tv := w.p.typeAndValue(expr.X)
1868 assert(tv.IsType())
1869
1870 index := sel.Index()
1871 implicits := index[:len(index)-1]
1872
1873 typ := tv.Type
1874 w.typ(typ)
1875
1876 w.Len(len(implicits))
1877 for _, ix := range implicits {
1878 w.Len(ix)
1879 typ = deref2(typ).Underlying().(*types2.Struct).Field(ix).Type()
1880 }
1881
1882 recv := sel.Obj().(*types2.Func).Type().(*types2.Signature).Recv().Type()
1883 if w.Bool(isPtrTo(typ, recv)) {
1884 typ = recv
1885 } else if w.Bool(isPtrTo(recv, typ)) {
1886 typ = recv
1887 }
1888
1889 w.pos(expr)
1890 w.methodExpr(expr, typ, sel)
1891 }
1892
1893 case *syntax.IndexExpr:
1894 _ = w.p.typeOf(expr.Index)
1895
1896 xtyp := w.p.typeOf(expr.X)
1897
1898 var keyType types2.Type
1899 if mapType, ok := types2.CoreType(xtyp).(*types2.Map); ok {
1900 keyType = mapType.Key()
1901 }
1902
1903 w.Code(exprIndex)
1904 w.expr(expr.X)
1905 w.pos(expr)
1906 w.implicitConvExpr(keyType, expr.Index)
1907 if keyType != nil {
1908 w.rtype(xtyp)
1909 }
1910
1911 case *syntax.SliceExpr:
1912 w.Code(exprSlice)
1913 w.expr(expr.X)
1914 w.pos(expr)
1915 for _, n := range &expr.Index {
1916 w.optExpr(n)
1917 }
1918
1919 case *syntax.AssertExpr:
1920 iface := w.p.typeOf(expr.X)
1921
1922 w.Code(exprAssert)
1923 w.expr(expr.X)
1924 w.pos(expr)
1925 w.exprType(iface, expr.Type)
1926 w.rtype(iface)
1927
1928 case *syntax.Operation:
1929 if expr.Y == nil {
1930 w.Code(exprUnaryOp)
1931 w.op(unOps[expr.Op])
1932 w.pos(expr)
1933 w.expr(expr.X)
1934 break
1935 }
1936
1937 var commonType types2.Type
1938 switch expr.Op {
1939 case syntax.Shl, syntax.Shr:
1940
1941 default:
1942 xtyp := w.p.typeOf(expr.X)
1943 ytyp := w.p.typeOf(expr.Y)
1944 switch {
1945 case types2.AssignableTo(xtyp, ytyp):
1946 commonType = ytyp
1947 case types2.AssignableTo(ytyp, xtyp):
1948 commonType = xtyp
1949 default:
1950 w.p.fatalf(expr, "failed to find common type between %v and %v", xtyp, ytyp)
1951 }
1952 }
1953
1954 w.Code(exprBinaryOp)
1955 w.op(binOps[expr.Op])
1956 w.implicitConvExpr(commonType, expr.X)
1957 w.pos(expr)
1958 w.implicitConvExpr(commonType, expr.Y)
1959
1960 case *syntax.CallExpr:
1961 tv := w.p.typeAndValue(expr.Fun)
1962 if tv.IsType() {
1963 assert(len(expr.ArgList) == 1)
1964 assert(!expr.HasDots)
1965 w.convertExpr(tv.Type, expr.ArgList[0], false)
1966 break
1967 }
1968
1969 var rtype types2.Type
1970 if tv.IsBuiltin() {
1971 switch obj, _ := lookupObj(w.p, syntax.Unparen(expr.Fun)); obj.Name() {
1972 case "make":
1973 assert(len(expr.ArgList) >= 1)
1974 assert(!expr.HasDots)
1975
1976 w.Code(exprMake)
1977 w.pos(expr)
1978 w.exprType(nil, expr.ArgList[0])
1979 w.exprs(expr.ArgList[1:])
1980
1981 typ := w.p.typeOf(expr)
1982 switch coreType := types2.CoreType(typ).(type) {
1983 default:
1984 w.p.fatalf(expr, "unexpected core type: %v", coreType)
1985 case *types2.Chan:
1986 w.rtype(typ)
1987 case *types2.Map:
1988 w.rtype(typ)
1989 case *types2.Slice:
1990 w.rtype(sliceElem(typ))
1991 }
1992
1993 return
1994
1995 case "new":
1996 assert(len(expr.ArgList) == 1)
1997 assert(!expr.HasDots)
1998
1999 w.Code(exprNew)
2000 w.pos(expr)
2001 w.exprType(nil, expr.ArgList[0])
2002 return
2003
2004 case "Sizeof":
2005 assert(len(expr.ArgList) == 1)
2006 assert(!expr.HasDots)
2007
2008 w.Code(exprSizeof)
2009 w.pos(expr)
2010 w.typ(w.p.typeOf(expr.ArgList[0]))
2011 return
2012
2013 case "Alignof":
2014 assert(len(expr.ArgList) == 1)
2015 assert(!expr.HasDots)
2016
2017 w.Code(exprAlignof)
2018 w.pos(expr)
2019 w.typ(w.p.typeOf(expr.ArgList[0]))
2020 return
2021
2022 case "Offsetof":
2023 assert(len(expr.ArgList) == 1)
2024 assert(!expr.HasDots)
2025 selector := syntax.Unparen(expr.ArgList[0]).(*syntax.SelectorExpr)
2026 index := w.p.info.Selections[selector].Index()
2027
2028 w.Code(exprOffsetof)
2029 w.pos(expr)
2030 w.typ(deref2(w.p.typeOf(selector.X)))
2031 w.Len(len(index) - 1)
2032 for _, idx := range index {
2033 w.Len(idx)
2034 }
2035 return
2036
2037 case "append":
2038 rtype = sliceElem(w.p.typeOf(expr))
2039 case "copy":
2040 typ := w.p.typeOf(expr.ArgList[0])
2041 if tuple, ok := typ.(*types2.Tuple); ok {
2042 typ = tuple.At(0).Type()
2043 }
2044 rtype = sliceElem(typ)
2045 case "delete":
2046 typ := w.p.typeOf(expr.ArgList[0])
2047 if tuple, ok := typ.(*types2.Tuple); ok {
2048 typ = tuple.At(0).Type()
2049 }
2050 rtype = typ
2051 case "Slice":
2052 rtype = sliceElem(w.p.typeOf(expr))
2053 }
2054 }
2055
2056 writeFunExpr := func() {
2057 fun := syntax.Unparen(expr.Fun)
2058
2059 if selector, ok := fun.(*syntax.SelectorExpr); ok {
2060 if sel, ok := w.p.info.Selections[selector]; ok && sel.Kind() == types2.MethodVal {
2061 w.Bool(true)
2062 typ := w.recvExpr(selector, sel)
2063 w.methodExpr(selector, typ, sel)
2064 return
2065 }
2066 }
2067
2068 w.Bool(false)
2069
2070 if obj, inst := lookupObj(w.p, fun); w.Bool(obj != nil && inst.TypeArgs.Len() != 0) {
2071 obj := obj.(*types2.Func)
2072
2073 w.pos(fun)
2074 w.funcInst(obj, inst.TypeArgs)
2075 return
2076 }
2077
2078 w.expr(fun)
2079 }
2080
2081 sigType := types2.CoreType(tv.Type).(*types2.Signature)
2082 paramTypes := sigType.Params()
2083
2084 w.Code(exprCall)
2085 writeFunExpr()
2086 w.pos(expr)
2087
2088 paramType := func(i int) types2.Type {
2089 if sigType.Variadic() && !expr.HasDots && i >= paramTypes.Len()-1 {
2090 return paramTypes.At(paramTypes.Len() - 1).Type().(*types2.Slice).Elem()
2091 }
2092 return paramTypes.At(i).Type()
2093 }
2094
2095 w.multiExpr(expr, paramType, expr.ArgList)
2096 w.Bool(expr.HasDots)
2097 if rtype != nil {
2098 w.rtype(rtype)
2099 }
2100 }
2101 }
2102
2103 func sliceElem(typ types2.Type) types2.Type {
2104 return types2.CoreType(typ).(*types2.Slice).Elem()
2105 }
2106
2107 func (w *writer) optExpr(expr syntax.Expr) {
2108 if w.Bool(expr != nil) {
2109 w.expr(expr)
2110 }
2111 }
2112
2113
2114
2115
2116 func (w *writer) recvExpr(expr *syntax.SelectorExpr, sel *types2.Selection) types2.Type {
2117 index := sel.Index()
2118 implicits := index[:len(index)-1]
2119
2120 w.Code(exprRecv)
2121 w.expr(expr.X)
2122 w.pos(expr)
2123 w.Len(len(implicits))
2124
2125 typ := w.p.typeOf(expr.X)
2126 for _, ix := range implicits {
2127 typ = deref2(typ).Underlying().(*types2.Struct).Field(ix).Type()
2128 w.Len(ix)
2129 }
2130
2131 recv := sel.Obj().(*types2.Func).Type().(*types2.Signature).Recv().Type()
2132 if w.Bool(isPtrTo(typ, recv)) {
2133 typ = recv
2134 } else if w.Bool(isPtrTo(recv, typ)) {
2135 typ = recv
2136 }
2137
2138 return typ
2139 }
2140
2141
2142 func (w *writer) funcInst(obj *types2.Func, targs *types2.TypeList) {
2143 info := w.p.objInstIdx(obj, targs, w.dict)
2144
2145
2146
2147
2148 if w.Bool(info.anyDerived()) {
2149 w.Len(w.dict.subdictIdx(info))
2150 return
2151 }
2152
2153
2154
2155
2156 w.objInfo(info)
2157 }
2158
2159
2160
2161
2162
2163
2164
2165 func (w *writer) methodExpr(expr *syntax.SelectorExpr, recv types2.Type, sel *types2.Selection) {
2166 fun := sel.Obj().(*types2.Func)
2167 sig := fun.Type().(*types2.Signature)
2168
2169 w.typ(recv)
2170 w.typ(sig)
2171 w.pos(expr)
2172 w.selector(fun)
2173
2174
2175
2176 if typeParam, ok := types2.Unalias(recv).(*types2.TypeParam); w.Bool(ok) {
2177 typeParamIdx := w.dict.typeParamIndex(typeParam)
2178 methodInfo := w.p.selectorIdx(fun)
2179
2180 w.Len(w.dict.typeParamMethodExprIdx(typeParamIdx, methodInfo))
2181 return
2182 }
2183
2184 if isInterface(recv) != isInterface(sig.Recv().Type()) {
2185 w.p.fatalf(expr, "isInterface inconsistency: %v and %v", recv, sig.Recv().Type())
2186 }
2187
2188 if !isInterface(recv) {
2189 if named, ok := types2.Unalias(deref2(recv)).(*types2.Named); ok {
2190 obj, targs := splitNamed(named)
2191 info := w.p.objInstIdx(obj, targs, w.dict)
2192
2193
2194
2195
2196
2197 if w.p.hasImplicitTypeParams(obj) || info.anyDerived() {
2198 w.Bool(true)
2199 w.Len(w.dict.subdictIdx(info))
2200 return
2201 }
2202
2203
2204
2205
2206 if targs.Len() != 0 {
2207 w.Bool(false)
2208 w.Bool(true)
2209 w.objInfo(info)
2210 return
2211 }
2212 }
2213 }
2214
2215 w.Bool(false)
2216 w.Bool(false)
2217 }
2218
2219
2220
2221
2222
2223 func (w *writer) multiExpr(pos poser, dstType func(int) types2.Type, exprs []syntax.Expr) {
2224 w.Sync(pkgbits.SyncMultiExpr)
2225
2226 if len(exprs) == 1 {
2227 expr := exprs[0]
2228 if tuple, ok := w.p.typeOf(expr).(*types2.Tuple); ok {
2229 assert(tuple.Len() > 1)
2230 w.Bool(true)
2231 w.pos(pos)
2232 w.expr(expr)
2233
2234 w.Len(tuple.Len())
2235 for i := 0; i < tuple.Len(); i++ {
2236 src := tuple.At(i).Type()
2237
2238
2239 w.typ(src)
2240 if dst := dstType(i); w.Bool(dst != nil && !types2.Identical(src, dst)) {
2241 if src == nil || dst == nil {
2242 w.p.fatalf(pos, "src is %v, dst is %v", src, dst)
2243 }
2244 if !types2.AssignableTo(src, dst) {
2245 w.p.fatalf(pos, "%v is not assignable to %v", src, dst)
2246 }
2247 w.typ(dst)
2248 w.convRTTI(src, dst)
2249 }
2250 }
2251 return
2252 }
2253 }
2254
2255 w.Bool(false)
2256 w.Len(len(exprs))
2257 for i, expr := range exprs {
2258 w.implicitConvExpr(dstType(i), expr)
2259 }
2260 }
2261
2262
2263
2264
2265 func (w *writer) implicitConvExpr(dst types2.Type, expr syntax.Expr) {
2266 w.convertExpr(dst, expr, true)
2267 }
2268
2269 func (w *writer) convertExpr(dst types2.Type, expr syntax.Expr, implicit bool) {
2270 src := w.p.typeOf(expr)
2271
2272
2273 identical := dst == nil || types2.Identical(src, dst)
2274 if implicit && identical {
2275 w.expr(expr)
2276 return
2277 }
2278
2279 if implicit && !types2.AssignableTo(src, dst) {
2280 w.p.fatalf(expr, "%v is not assignable to %v", src, dst)
2281 }
2282
2283 w.Code(exprConvert)
2284 w.Bool(implicit)
2285 w.typ(dst)
2286 w.pos(expr)
2287 w.convRTTI(src, dst)
2288 w.Bool(isTypeParam(dst))
2289 w.Bool(identical)
2290 w.expr(expr)
2291 }
2292
2293 func (w *writer) compLit(lit *syntax.CompositeLit) {
2294 typ := w.p.typeOf(lit)
2295
2296 w.Sync(pkgbits.SyncCompLit)
2297 w.pos(lit)
2298 w.typ(typ)
2299
2300 if ptr, ok := types2.CoreType(typ).(*types2.Pointer); ok {
2301 typ = ptr.Elem()
2302 }
2303 var keyType, elemType types2.Type
2304 var structType *types2.Struct
2305 switch typ0 := typ; typ := types2.CoreType(typ).(type) {
2306 default:
2307 w.p.fatalf(lit, "unexpected composite literal type: %v", typ)
2308 case *types2.Array:
2309 elemType = typ.Elem()
2310 case *types2.Map:
2311 w.rtype(typ0)
2312 keyType, elemType = typ.Key(), typ.Elem()
2313 case *types2.Slice:
2314 elemType = typ.Elem()
2315 case *types2.Struct:
2316 structType = typ
2317 }
2318
2319 w.Len(len(lit.ElemList))
2320 for i, elem := range lit.ElemList {
2321 elemType := elemType
2322 if structType != nil {
2323 if kv, ok := elem.(*syntax.KeyValueExpr); ok {
2324
2325 w.pos(kv.Key)
2326 i = fieldIndex(w.p.info, structType, kv.Key.(*syntax.Name))
2327 elem = kv.Value
2328 } else {
2329 w.pos(elem)
2330 }
2331 elemType = structType.Field(i).Type()
2332 w.Len(i)
2333 } else {
2334 if kv, ok := elem.(*syntax.KeyValueExpr); w.Bool(ok) {
2335
2336 w.pos(kv.Key)
2337 w.implicitConvExpr(keyType, kv.Key)
2338 elem = kv.Value
2339 }
2340 }
2341 w.implicitConvExpr(elemType, elem)
2342 }
2343 }
2344
2345 func (w *writer) funcLit(expr *syntax.FuncLit) {
2346 sig := w.p.typeOf(expr).(*types2.Signature)
2347
2348 body, closureVars := w.p.bodyIdx(sig, expr.Body, w.dict)
2349
2350 w.Sync(pkgbits.SyncFuncLit)
2351 w.pos(expr)
2352 w.signature(sig)
2353 w.Bool(w.p.rangeFuncBodyClosures[expr])
2354
2355 w.Len(len(closureVars))
2356 for _, cv := range closureVars {
2357 w.pos(cv.pos)
2358 w.useLocal(cv.pos, cv.var_)
2359 }
2360
2361 w.Reloc(pkgbits.RelocBody, body)
2362 }
2363
2364 type posVar struct {
2365 pos syntax.Pos
2366 var_ *types2.Var
2367 }
2368
2369 func (p posVar) String() string {
2370 return p.pos.String() + ":" + p.var_.String()
2371 }
2372
2373 func (w *writer) exprList(expr syntax.Expr) {
2374 w.Sync(pkgbits.SyncExprList)
2375 w.exprs(syntax.UnpackListExpr(expr))
2376 }
2377
2378 func (w *writer) exprs(exprs []syntax.Expr) {
2379 w.Sync(pkgbits.SyncExprs)
2380 w.Len(len(exprs))
2381 for _, expr := range exprs {
2382 w.expr(expr)
2383 }
2384 }
2385
2386
2387
2388 func (w *writer) rtype(typ types2.Type) {
2389 typ = types2.Default(typ)
2390
2391 info := w.p.typIdx(typ, w.dict)
2392 w.rtypeInfo(info)
2393 }
2394
2395 func (w *writer) rtypeInfo(info typeInfo) {
2396 w.Sync(pkgbits.SyncRType)
2397
2398 if w.Bool(info.derived) {
2399 w.Len(w.dict.rtypeIdx(info))
2400 } else {
2401 w.typInfo(info)
2402 }
2403 }
2404
2405
2406
2407 func (w *writer) varDictIndex(obj *types2.Var) {
2408 info := w.p.typIdx(obj.Type(), w.dict)
2409 if w.Bool(info.derived) {
2410 w.Len(w.dict.rtypeIdx(info))
2411 }
2412 }
2413
2414
2415 func isUntyped(typ types2.Type) bool {
2416
2417 basic, ok := typ.(*types2.Basic)
2418 return ok && basic.Info()&types2.IsUntyped != 0
2419 }
2420
2421
2422 func isTuple(typ types2.Type) bool {
2423
2424 _, ok := typ.(*types2.Tuple)
2425 return ok
2426 }
2427
2428 func (w *writer) itab(typ, iface types2.Type) {
2429 typ = types2.Default(typ)
2430 iface = types2.Default(iface)
2431
2432 typInfo := w.p.typIdx(typ, w.dict)
2433 ifaceInfo := w.p.typIdx(iface, w.dict)
2434
2435 w.rtypeInfo(typInfo)
2436 w.rtypeInfo(ifaceInfo)
2437 if w.Bool(typInfo.derived || ifaceInfo.derived) {
2438 w.Len(w.dict.itabIdx(typInfo, ifaceInfo))
2439 }
2440 }
2441
2442
2443
2444 func (w *writer) convRTTI(src, dst types2.Type) {
2445 w.Sync(pkgbits.SyncConvRTTI)
2446 w.itab(src, dst)
2447 }
2448
2449 func (w *writer) exprType(iface types2.Type, typ syntax.Expr) {
2450 base.Assertf(iface == nil || isInterface(iface), "%v must be nil or an interface type", iface)
2451
2452 tv := w.p.typeAndValue(typ)
2453 assert(tv.IsType())
2454
2455 w.Sync(pkgbits.SyncExprType)
2456 w.pos(typ)
2457
2458 if w.Bool(iface != nil && !iface.Underlying().(*types2.Interface).Empty()) {
2459 w.itab(tv.Type, iface)
2460 } else {
2461 w.rtype(tv.Type)
2462
2463 info := w.p.typIdx(tv.Type, w.dict)
2464 w.Bool(info.derived)
2465 }
2466 }
2467
2468
2469
2470
2471 func isInterface(typ types2.Type) bool {
2472 if _, ok := types2.Unalias(typ).(*types2.TypeParam); ok {
2473
2474
2475
2476 base.Fatalf("%v is a type parameter", typ)
2477 }
2478
2479 _, ok := typ.Underlying().(*types2.Interface)
2480 return ok
2481 }
2482
2483
2484 func (w *writer) op(op ir.Op) {
2485
2486
2487
2488 assert(op != 0)
2489 w.Sync(pkgbits.SyncOp)
2490 w.Len(int(op))
2491 }
2492
2493
2494
2495
2496
2497
2498 type typeDeclGen struct {
2499 *syntax.TypeDecl
2500 gen int
2501
2502
2503 implicits []*types2.TypeParam
2504 }
2505
2506 type fileImports struct {
2507 importedEmbed, importedUnsafe bool
2508 }
2509
2510
2511
2512
2513
2514
2515
2516 type declCollector struct {
2517 pw *pkgWriter
2518 typegen *int
2519 file *fileImports
2520 withinFunc bool
2521 implicits []*types2.TypeParam
2522 }
2523
2524 func (c *declCollector) withTParams(obj types2.Object) *declCollector {
2525 tparams := objTypeParams(obj)
2526 n := tparams.Len()
2527 if n == 0 {
2528 return c
2529 }
2530
2531 copy := *c
2532 copy.implicits = copy.implicits[:len(copy.implicits):len(copy.implicits)]
2533 for i := 0; i < n; i++ {
2534 copy.implicits = append(copy.implicits, tparams.At(i))
2535 }
2536 return ©
2537 }
2538
2539 func (c *declCollector) Visit(n syntax.Node) syntax.Visitor {
2540 pw := c.pw
2541
2542 switch n := n.(type) {
2543 case *syntax.File:
2544 pw.checkPragmas(n.Pragma, ir.GoBuildPragma, false)
2545
2546 case *syntax.ImportDecl:
2547 pw.checkPragmas(n.Pragma, 0, false)
2548
2549 switch pw.info.PkgNameOf(n).Imported().Path() {
2550 case "embed":
2551 c.file.importedEmbed = true
2552 case "unsafe":
2553 c.file.importedUnsafe = true
2554 }
2555
2556 case *syntax.ConstDecl:
2557 pw.checkPragmas(n.Pragma, 0, false)
2558
2559 case *syntax.FuncDecl:
2560 pw.checkPragmas(n.Pragma, funcPragmas, false)
2561
2562 obj := pw.info.Defs[n.Name].(*types2.Func)
2563 pw.funDecls[obj] = n
2564
2565 return c.withTParams(obj)
2566
2567 case *syntax.TypeDecl:
2568 obj := pw.info.Defs[n.Name].(*types2.TypeName)
2569 d := typeDeclGen{TypeDecl: n, implicits: c.implicits}
2570
2571 if n.Alias {
2572 pw.checkPragmas(n.Pragma, 0, false)
2573 } else {
2574 pw.checkPragmas(n.Pragma, 0, false)
2575
2576
2577 if c.withinFunc {
2578 *c.typegen++
2579 d.gen = *c.typegen
2580 }
2581 }
2582
2583 pw.typDecls[obj] = d
2584
2585
2586
2587
2588
2589 return c.withTParams(obj)
2590
2591 case *syntax.VarDecl:
2592 pw.checkPragmas(n.Pragma, 0, true)
2593
2594 if p, ok := n.Pragma.(*pragmas); ok && len(p.Embeds) > 0 {
2595 if err := checkEmbed(n, c.file.importedEmbed, c.withinFunc); err != nil {
2596 pw.errorf(p.Embeds[0].Pos, "%s", err)
2597 }
2598 }
2599
2600 case *syntax.BlockStmt:
2601 if !c.withinFunc {
2602 copy := *c
2603 copy.withinFunc = true
2604 return ©
2605 }
2606 }
2607
2608 return c
2609 }
2610
2611 func (pw *pkgWriter) collectDecls(noders []*noder) {
2612 var typegen int
2613 for _, p := range noders {
2614 var file fileImports
2615
2616 syntax.Walk(p.file, &declCollector{
2617 pw: pw,
2618 typegen: &typegen,
2619 file: &file,
2620 })
2621
2622 pw.cgoPragmas = append(pw.cgoPragmas, p.pragcgobuf...)
2623
2624 for _, l := range p.linknames {
2625 if !file.importedUnsafe {
2626 pw.errorf(l.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
2627 continue
2628 }
2629 if strings.Contains(l.remote, "[") && strings.Contains(l.remote, "]") {
2630 pw.errorf(l.pos, "//go:linkname reference of an instantiation is not allowed")
2631 continue
2632 }
2633
2634 switch obj := pw.curpkg.Scope().Lookup(l.local).(type) {
2635 case *types2.Func, *types2.Var:
2636 if _, ok := pw.linknames[obj]; !ok {
2637 pw.linknames[obj] = l.remote
2638 } else {
2639 pw.errorf(l.pos, "duplicate //go:linkname for %s", l.local)
2640 }
2641
2642 default:
2643 if types.AllowsGoVersion(1, 18) {
2644 pw.errorf(l.pos, "//go:linkname must refer to declared function or variable")
2645 }
2646 }
2647 }
2648 }
2649 }
2650
2651 func (pw *pkgWriter) checkPragmas(p syntax.Pragma, allowed ir.PragmaFlag, embedOK bool) {
2652 if p == nil {
2653 return
2654 }
2655 pragma := p.(*pragmas)
2656
2657 for _, pos := range pragma.Pos {
2658 if pos.Flag&^allowed != 0 {
2659 pw.errorf(pos.Pos, "misplaced compiler directive")
2660 }
2661 }
2662
2663 if !embedOK {
2664 for _, e := range pragma.Embeds {
2665 pw.errorf(e.Pos, "misplaced go:embed directive")
2666 }
2667 }
2668 }
2669
2670 func (w *writer) pkgInit(noders []*noder) {
2671 w.Len(len(w.p.cgoPragmas))
2672 for _, cgoPragma := range w.p.cgoPragmas {
2673 w.Strings(cgoPragma)
2674 }
2675
2676 w.pkgInitOrder()
2677
2678 w.Sync(pkgbits.SyncDecls)
2679 for _, p := range noders {
2680 for _, decl := range p.file.DeclList {
2681 w.pkgDecl(decl)
2682 }
2683 }
2684 w.Code(declEnd)
2685
2686 w.Sync(pkgbits.SyncEOF)
2687 }
2688
2689 func (w *writer) pkgInitOrder() {
2690
2691 w.Len(len(w.p.info.InitOrder))
2692 for _, init := range w.p.info.InitOrder {
2693 w.Len(len(init.Lhs))
2694 for _, v := range init.Lhs {
2695 w.obj(v, nil)
2696 }
2697 w.expr(init.Rhs)
2698 }
2699 }
2700
2701 func (w *writer) pkgDecl(decl syntax.Decl) {
2702 switch decl := decl.(type) {
2703 default:
2704 w.p.unexpected("declaration", decl)
2705
2706 case *syntax.ImportDecl:
2707
2708 case *syntax.ConstDecl:
2709 w.Code(declOther)
2710 w.pkgObjs(decl.NameList...)
2711
2712 case *syntax.FuncDecl:
2713 if decl.Name.Value == "_" {
2714 break
2715 }
2716
2717 obj := w.p.info.Defs[decl.Name].(*types2.Func)
2718 sig := obj.Type().(*types2.Signature)
2719
2720 if sig.RecvTypeParams() != nil || sig.TypeParams() != nil {
2721 break
2722 }
2723
2724 if recv := sig.Recv(); recv != nil {
2725 w.Code(declMethod)
2726 w.typ(recvBase(recv))
2727 w.selector(obj)
2728 break
2729 }
2730
2731 w.Code(declFunc)
2732 w.pkgObjs(decl.Name)
2733
2734 case *syntax.TypeDecl:
2735 if len(decl.TParamList) != 0 {
2736 break
2737 }
2738
2739 if decl.Name.Value == "_" {
2740 break
2741 }
2742
2743 name := w.p.info.Defs[decl.Name].(*types2.TypeName)
2744
2745
2746 if iface, ok := name.Type().Underlying().(*types2.Interface); ok && !iface.IsMethodSet() {
2747 break
2748 }
2749
2750 w.Code(declOther)
2751 w.pkgObjs(decl.Name)
2752
2753 case *syntax.VarDecl:
2754 w.Code(declVar)
2755 w.pkgObjs(decl.NameList...)
2756
2757 var embeds []pragmaEmbed
2758 if p, ok := decl.Pragma.(*pragmas); ok {
2759 embeds = p.Embeds
2760 }
2761 w.Len(len(embeds))
2762 for _, embed := range embeds {
2763 w.pos(embed.Pos)
2764 w.Strings(embed.Patterns)
2765 }
2766 }
2767 }
2768
2769 func (w *writer) pkgObjs(names ...*syntax.Name) {
2770 w.Sync(pkgbits.SyncDeclNames)
2771 w.Len(len(names))
2772
2773 for _, name := range names {
2774 obj, ok := w.p.info.Defs[name]
2775 assert(ok)
2776
2777 w.Sync(pkgbits.SyncDeclName)
2778 w.obj(obj, nil)
2779 }
2780 }
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790 func (pw *pkgWriter) staticBool(ep *syntax.Expr) int {
2791 if val := pw.typeAndValue(*ep).Value; val != nil {
2792 if constant.BoolVal(val) {
2793 return +1
2794 } else {
2795 return -1
2796 }
2797 }
2798
2799 if e, ok := (*ep).(*syntax.Operation); ok {
2800 switch e.Op {
2801 case syntax.Not:
2802 return pw.staticBool(&e.X)
2803
2804 case syntax.AndAnd:
2805 x := pw.staticBool(&e.X)
2806 if x < 0 {
2807 *ep = e.X
2808 return x
2809 }
2810
2811 y := pw.staticBool(&e.Y)
2812 if x > 0 || y < 0 {
2813 if pw.typeAndValue(e.X).Value != nil {
2814 *ep = e.Y
2815 }
2816 return y
2817 }
2818
2819 case syntax.OrOr:
2820 x := pw.staticBool(&e.X)
2821 if x > 0 {
2822 *ep = e.X
2823 return x
2824 }
2825
2826 y := pw.staticBool(&e.Y)
2827 if x < 0 || y > 0 {
2828 if pw.typeAndValue(e.X).Value != nil {
2829 *ep = e.Y
2830 }
2831 return y
2832 }
2833 }
2834 }
2835
2836 return 0
2837 }
2838
2839
2840
2841
2842 func (pw *pkgWriter) hasImplicitTypeParams(obj *types2.TypeName) bool {
2843 if obj.Pkg() == pw.curpkg {
2844 decl, ok := pw.typDecls[obj]
2845 assert(ok)
2846 if len(decl.implicits) != 0 {
2847 return true
2848 }
2849 }
2850 return false
2851 }
2852
2853
2854 func isDefinedType(obj types2.Object) bool {
2855 if obj, ok := obj.(*types2.TypeName); ok {
2856 return !obj.IsAlias()
2857 }
2858 return false
2859 }
2860
2861
2862
2863
2864 func isGlobal(obj types2.Object) bool {
2865 return obj.Parent() == obj.Pkg().Scope()
2866 }
2867
2868
2869
2870
2871 func lookupObj(p *pkgWriter, expr syntax.Expr) (obj types2.Object, inst types2.Instance) {
2872 if index, ok := expr.(*syntax.IndexExpr); ok {
2873 args := syntax.UnpackListExpr(index.Index)
2874 if len(args) == 1 {
2875 tv := p.typeAndValue(args[0])
2876 if tv.IsValue() {
2877 return
2878 }
2879 }
2880
2881 expr = index.X
2882 }
2883
2884
2885 if sel, ok := expr.(*syntax.SelectorExpr); ok {
2886 if !isPkgQual(p.info, sel) {
2887 return
2888 }
2889 expr = sel.Sel
2890 }
2891
2892 if name, ok := expr.(*syntax.Name); ok {
2893 obj = p.info.Uses[name]
2894 inst = p.info.Instances[name]
2895 }
2896 return
2897 }
2898
2899
2900
2901 func isPkgQual(info *types2.Info, sel *syntax.SelectorExpr) bool {
2902 if name, ok := sel.X.(*syntax.Name); ok {
2903 _, isPkgName := info.Uses[name].(*types2.PkgName)
2904 return isPkgName
2905 }
2906 return false
2907 }
2908
2909
2910
2911 func isNil(p *pkgWriter, expr syntax.Expr) bool {
2912 tv := p.typeAndValue(expr)
2913 return tv.IsNil()
2914 }
2915
2916
2917
2918 func (pw *pkgWriter) isBuiltin(expr syntax.Expr, builtin string) bool {
2919 if name, ok := syntax.Unparen(expr).(*syntax.Name); ok && name.Value == builtin {
2920 return pw.typeAndValue(name).IsBuiltin()
2921 }
2922 return false
2923 }
2924
2925
2926 func recvBase(recv *types2.Var) *types2.Named {
2927 typ := types2.Unalias(recv.Type())
2928 if ptr, ok := typ.(*types2.Pointer); ok {
2929 typ = types2.Unalias(ptr.Elem())
2930 }
2931 return typ.(*types2.Named)
2932 }
2933
2934
2935 func namesAsExpr(names []*syntax.Name) syntax.Expr {
2936 if len(names) == 1 {
2937 return names[0]
2938 }
2939
2940 exprs := make([]syntax.Expr, len(names))
2941 for i, name := range names {
2942 exprs[i] = name
2943 }
2944 return &syntax.ListExpr{ElemList: exprs}
2945 }
2946
2947
2948 func fieldIndex(info *types2.Info, str *types2.Struct, key *syntax.Name) int {
2949 field := info.Uses[key].(*types2.Var)
2950
2951 for i := 0; i < str.NumFields(); i++ {
2952 if str.Field(i) == field {
2953 return i
2954 }
2955 }
2956
2957 panic(fmt.Sprintf("%s: %v is not a field of %v", key.Pos(), field, str))
2958 }
2959
2960
2961 func objTypeParams(obj types2.Object) *types2.TypeParamList {
2962 switch obj := obj.(type) {
2963 case *types2.Func:
2964 sig := obj.Type().(*types2.Signature)
2965 if sig.Recv() != nil {
2966 return sig.RecvTypeParams()
2967 }
2968 return sig.TypeParams()
2969 case *types2.TypeName:
2970 if !obj.IsAlias() {
2971 return obj.Type().(*types2.Named).TypeParams()
2972 }
2973 if alias, ok := obj.Type().(*types2.Alias); ok {
2974 return alias.TypeParams()
2975 }
2976 }
2977 return nil
2978 }
2979
2980
2981
2982 func splitNamed(typ *types2.Named) (*types2.TypeName, *types2.TypeList) {
2983 base.Assertf(typ.TypeParams().Len() == typ.TypeArgs().Len(), "use of uninstantiated type: %v", typ)
2984
2985 orig := typ.Origin()
2986 base.Assertf(orig.TypeArgs() == nil, "origin %v of %v has type arguments", orig, typ)
2987 base.Assertf(typ.Obj() == orig.Obj(), "%v has object %v, but %v has object %v", typ, typ.Obj(), orig, orig.Obj())
2988
2989 return typ.Obj(), typ.TypeArgs()
2990 }
2991
2992
2993 func splitAlias(typ *types2.Alias) (*types2.TypeName, *types2.TypeList) {
2994 orig := typ.Origin()
2995 base.Assertf(typ.Obj() == orig.Obj(), "alias type %v has object %v, but %v has object %v", typ, typ.Obj(), orig, orig.Obj())
2996
2997 return typ.Obj(), typ.TypeArgs()
2998 }
2999
3000 func asPragmaFlag(p syntax.Pragma) ir.PragmaFlag {
3001 if p == nil {
3002 return 0
3003 }
3004 return p.(*pragmas).Flag
3005 }
3006
3007 func asWasmImport(p syntax.Pragma) *WasmImport {
3008 if p == nil {
3009 return nil
3010 }
3011 return p.(*pragmas).WasmImport
3012 }
3013
3014
3015 func isPtrTo(from, to types2.Type) bool {
3016 ptr, ok := types2.Unalias(from).(*types2.Pointer)
3017 return ok && types2.Identical(ptr.Elem(), to)
3018 }
3019
3020
3021
3022 func hasFallthrough(stmts []syntax.Stmt) bool {
3023 last, ok := lastNonEmptyStmt(stmts).(*syntax.BranchStmt)
3024 return ok && last.Tok == syntax.Fallthrough
3025 }
3026
3027
3028
3029 func lastNonEmptyStmt(stmts []syntax.Stmt) syntax.Stmt {
3030 for i := len(stmts) - 1; i >= 0; i-- {
3031 stmt := stmts[i]
3032 if _, ok := stmt.(*syntax.EmptyStmt); !ok {
3033 return stmt
3034 }
3035 }
3036 return nil
3037 }
3038
3039
3040
3041 func (pw *pkgWriter) terminates(stmt syntax.Stmt) bool {
3042 switch stmt := stmt.(type) {
3043 case *syntax.BranchStmt:
3044 if stmt.Tok == syntax.Goto {
3045 return true
3046 }
3047 case *syntax.ReturnStmt:
3048 return true
3049 case *syntax.ExprStmt:
3050 if call, ok := syntax.Unparen(stmt.X).(*syntax.CallExpr); ok {
3051 if pw.isBuiltin(call.Fun, "panic") {
3052 return true
3053 }
3054 }
3055
3056
3057
3058
3059
3060
3061
3062
3063 case *syntax.IfStmt:
3064 cond := pw.staticBool(&stmt.Cond)
3065 return (cond < 0 || pw.terminates(stmt.Then)) && (cond > 0 || pw.terminates(stmt.Else))
3066 case *syntax.BlockStmt:
3067 return pw.terminates(lastNonEmptyStmt(stmt.List))
3068 }
3069
3070 return false
3071 }
3072
View as plain text