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