1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235 package typecheck
236
237 import (
238 "bytes"
239 "crypto/md5"
240 "encoding/binary"
241 "fmt"
242 "go/constant"
243 "io"
244 "math/big"
245 "sort"
246 "strconv"
247 "strings"
248
249 "cmd/compile/internal/base"
250 "cmd/compile/internal/ir"
251 "cmd/compile/internal/types"
252 "cmd/internal/goobj"
253 "cmd/internal/src"
254 )
255
256
257
258
259
260
261
262 const (
263 iexportVersionGo1_11 = 0
264 iexportVersionPosCol = 1
265 iexportVersionGenerics = 2
266 iexportVersionGo1_18 = 2
267
268 iexportVersionCurrent = 2
269 )
270
271
272
273 const predeclReserved = 32
274
275
276
277 type itag uint64
278
279 const (
280
281 definedType itag = iota
282 pointerType
283 sliceType
284 arrayType
285 chanType
286 mapType
287 signatureType
288 structType
289 interfaceType
290 typeParamType
291 instanceType
292 unionType
293 )
294
295 const (
296 debug = false
297 magic = 0x6742937dc293105
298 )
299
300
301
302 func WriteExports(out io.Writer, extensions bool) {
303 if extensions {
304
305
306 crawlExports(Target.Exports)
307 }
308
309 p := iexporter{
310 allPkgs: map[*types.Pkg]bool{},
311 stringIndex: map[string]uint64{},
312 declIndex: map[*types.Sym]uint64{},
313 inlineIndex: map[*types.Sym]uint64{},
314 typIndex: map[*types.Type]uint64{},
315 extensions: extensions,
316 }
317
318 for i, pt := range predeclared() {
319 p.typIndex[pt] = uint64(i)
320 }
321 if len(p.typIndex) > predeclReserved {
322 base.Fatalf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)
323 }
324
325
326 for _, n := range Target.Exports {
327 p.pushDecl(n)
328 }
329
330
331
332
333 for !p.declTodo.Empty() {
334 p.doDecl(p.declTodo.PopLeft())
335 }
336
337
338 dataLen := uint64(p.data0.Len())
339 w := p.newWriter()
340 w.writeIndex(p.declIndex, true)
341 w.writeIndex(p.inlineIndex, false)
342 w.flush()
343
344 if *base.Flag.LowerV {
345 fmt.Printf("export: hdr strings %v, data %v, index %v\n", p.strings.Len(), dataLen, p.data0.Len())
346 }
347
348
349 var hdr intWriter
350 hdr.WriteByte('i')
351 hdr.uint64(iexportVersionCurrent)
352 hdr.uint64(uint64(p.strings.Len()))
353 hdr.uint64(dataLen)
354
355
356 h := md5.New()
357 wr := io.MultiWriter(out, h)
358 io.Copy(wr, &hdr)
359 io.Copy(wr, &p.strings)
360 io.Copy(wr, &p.data0)
361
362
363
364 copy(base.Ctxt.Fingerprint[:], h.Sum(nil)[:])
365 out.Write(base.Ctxt.Fingerprint[:])
366 }
367
368
369
370
371
372 func (w *exportWriter) writeIndex(index map[*types.Sym]uint64, mainIndex bool) {
373
374 pkgSyms := map[*types.Pkg][]*types.Sym{}
375
376
377
378
379 if mainIndex {
380 pkgSyms[types.LocalPkg] = nil
381 for pkg := range w.p.allPkgs {
382 pkgSyms[pkg] = nil
383 }
384 }
385
386
387 for sym := range index {
388 pkgSyms[sym.Pkg] = append(pkgSyms[sym.Pkg], sym)
389 }
390
391
392 var pkgs []*types.Pkg
393 for pkg := range pkgSyms {
394 pkgs = append(pkgs, pkg)
395 }
396 sort.Slice(pkgs, func(i, j int) bool {
397 return pkgs[i].Path < pkgs[j].Path
398 })
399
400 w.uint64(uint64(len(pkgs)))
401 for _, pkg := range pkgs {
402 w.string(pkg.Path)
403 if mainIndex {
404 w.string(pkg.Name)
405 w.uint64(uint64(pkg.Height))
406 }
407
408
409 syms := pkgSyms[pkg]
410 sort.Slice(syms, func(i, j int) bool {
411 return syms[i].Name < syms[j].Name
412 })
413
414 w.uint64(uint64(len(syms)))
415 for _, sym := range syms {
416 w.string(sym.Name)
417 w.uint64(index[sym])
418 }
419 }
420 }
421
422 type iexporter struct {
423
424
425
426 allPkgs map[*types.Pkg]bool
427
428 declTodo ir.NameQueue
429
430 strings intWriter
431 stringIndex map[string]uint64
432
433 data0 intWriter
434 declIndex map[*types.Sym]uint64
435 inlineIndex map[*types.Sym]uint64
436 typIndex map[*types.Type]uint64
437
438 extensions bool
439 }
440
441
442
443 func (p *iexporter) stringOff(s string) uint64 {
444 off, ok := p.stringIndex[s]
445 if !ok {
446 off = uint64(p.strings.Len())
447 p.stringIndex[s] = off
448
449 if *base.Flag.LowerV {
450 fmt.Printf("export: str %v %.40q\n", off, s)
451 }
452
453 p.strings.uint64(uint64(len(s)))
454 p.strings.WriteString(s)
455 }
456 return off
457 }
458
459
460 func (p *iexporter) pushDecl(n *ir.Name) {
461 if n.Sym() == nil || n.Sym().Def != n && n.Op() != ir.OTYPE {
462 base.Fatalf("weird Sym: %v, %v", n, n.Sym())
463 }
464
465
466 if n.Sym().Pkg == types.BuiltinPkg || n.Sym().Pkg == types.UnsafePkg {
467 return
468 }
469
470 if _, ok := p.declIndex[n.Sym()]; ok {
471 return
472 }
473
474 p.declIndex[n.Sym()] = ^uint64(0)
475 p.declTodo.PushRight(n)
476 }
477
478
479 type exportWriter struct {
480 p *iexporter
481
482 data intWriter
483 currPkg *types.Pkg
484 prevFile string
485 prevLine int64
486 prevColumn int64
487
488
489
490
491
492 dclIndex map[*ir.Name]int
493 maxDclIndex int
494 maxClosureVarIndex int
495 }
496
497 func (p *iexporter) doDecl(n *ir.Name) {
498 w := p.newWriter()
499 w.setPkg(n.Sym().Pkg, false)
500
501 switch n.Op() {
502 case ir.ONAME:
503 switch n.Class {
504 case ir.PEXTERN:
505
506 w.tag('V')
507 w.pos(n.Pos())
508 w.typ(n.Type())
509 if w.p.extensions {
510 w.varExt(n)
511 }
512
513 case ir.PFUNC:
514 if ir.IsMethod(n) {
515 base.Fatalf("unexpected method: %v", n)
516 }
517
518
519 if n.Type().TParams().NumFields() == 0 {
520 w.tag('F')
521 } else {
522 w.tag('G')
523 }
524 w.pos(n.Pos())
525
526
527
528
529
530
531 if n.Type().TParams().NumFields() > 0 {
532 w.tparamList(n.Type().TParams().FieldSlice())
533 }
534 w.signature(n.Type())
535 if w.p.extensions {
536 w.funcExt(n)
537 }
538
539 default:
540 base.Fatalf("unexpected class: %v, %v", n, n.Class)
541 }
542
543 case ir.OLITERAL:
544
545 if n.Typecheck() == 0 {
546 base.FatalfAt(n.Pos(), "missed typecheck: %v", n)
547 }
548
549
550 w.tag('C')
551 w.pos(n.Pos())
552 w.value(n.Type(), n.Val())
553 if w.p.extensions {
554 w.constExt(n)
555 }
556
557 case ir.OTYPE:
558 if n.Type().IsTypeParam() && n.Type().Underlying() == n.Type() {
559
560
561
562
563 w.tag('P')
564
565
566 w.pos(n.Pos())
567 if iexportVersionCurrent >= iexportVersionGo1_18 {
568 implicit := n.Type().Bound().IsImplicit()
569 w.bool(implicit)
570 }
571 w.typ(n.Type().Bound())
572 break
573 }
574
575 if n.Alias() {
576
577 w.tag('A')
578 w.pos(n.Pos())
579 w.typ(n.Type())
580 break
581 }
582
583
584 if len(n.Type().RParams()) == 0 {
585 w.tag('T')
586 } else {
587 w.tag('U')
588 }
589 w.pos(n.Pos())
590
591 if len(n.Type().RParams()) > 0 {
592
593 w.typeList(n.Type().RParams())
594 }
595
596 underlying := n.Type().Underlying()
597 if underlying == types.ErrorType.Underlying() {
598
599
600
601
602
603
604 underlying = types.ErrorType
605 }
606 if underlying == types.ComparableType.Underlying() {
607
608 underlying = types.ComparableType
609 }
610 if base.Flag.G > 0 && underlying == types.AnyType.Underlying() {
611
612 underlying = types.AnyType
613 }
614 w.typ(underlying)
615
616 t := n.Type()
617 if t.IsInterface() {
618 if w.p.extensions {
619 w.typeExt(t)
620 }
621 break
622 }
623
624
625 methods := append([]*types.Field(nil), t.Methods().Slice()...)
626 if base.Debug.UnifiedQuirks != 0 {
627 sort.Sort(types.MethodsByName(methods))
628 }
629
630 w.uint64(uint64(len(methods)))
631 for _, m := range methods {
632 w.pos(m.Pos)
633 w.selector(m.Sym)
634 w.param(m.Type.Recv())
635 w.signature(m.Type)
636 }
637
638 if w.p.extensions {
639 w.typeExt(t)
640 for _, m := range methods {
641 w.methExt(m)
642 }
643 }
644
645 default:
646 base.Fatalf("unexpected node: %v", n)
647 }
648
649 w.finish("dcl", p.declIndex, n.Sym())
650 }
651
652 func (w *exportWriter) tag(tag byte) {
653 w.data.WriteByte(tag)
654 }
655
656 func (w *exportWriter) finish(what string, index map[*types.Sym]uint64, sym *types.Sym) {
657 off := w.flush()
658 if *base.Flag.LowerV {
659 fmt.Printf("export: %v %v %v\n", what, off, sym)
660 }
661 index[sym] = off
662 }
663
664 func (p *iexporter) doInline(f *ir.Name) {
665 w := p.newWriter()
666 w.setPkg(fnpkg(f), false)
667
668 w.dclIndex = make(map[*ir.Name]int, len(f.Func.Inl.Dcl))
669 w.funcBody(f.Func)
670
671 w.finish("inl", p.inlineIndex, f.Sym())
672 }
673
674 func (w *exportWriter) pos(pos src.XPos) {
675 p := base.Ctxt.PosTable.Pos(pos)
676 file := p.Base().AbsFilename()
677 line := int64(p.RelLine())
678 column := int64(p.RelCol())
679
680
681
682
683
684
685
686
687
688
689
690 deltaColumn := (column - w.prevColumn) << 1
691 deltaLine := (line - w.prevLine) << 1
692
693 if file != w.prevFile {
694 deltaLine |= 1
695 }
696 if deltaLine != 0 {
697 deltaColumn |= 1
698 }
699
700 w.int64(deltaColumn)
701 if deltaColumn&1 != 0 {
702 w.int64(deltaLine)
703 if deltaLine&1 != 0 {
704 w.string(file)
705 }
706 }
707
708 w.prevFile = file
709 w.prevLine = line
710 w.prevColumn = column
711 }
712
713 func (w *exportWriter) pkg(pkg *types.Pkg) {
714
715 if pkg == ir.Pkgs.Go {
716 base.Fatalf("export of pseudo-package: %q", pkg.Path)
717 }
718
719
720 w.p.allPkgs[pkg] = true
721
722 w.string(pkg.Path)
723 }
724
725 func (w *exportWriter) qualifiedIdent(n *ir.Name) {
726
727 w.p.pushDecl(n)
728
729 s := n.Sym()
730 w.string(s.Name)
731 w.pkg(s.Pkg)
732 }
733
734 const blankMarker = "$"
735
736
737
738
739
740
741 func TparamExportName(prefix string, name string, index int) string {
742 if name == "_" {
743 name = blankMarker + strconv.Itoa(index)
744 }
745 return prefix + "." + name
746 }
747
748
749
750
751 func TparamName(exportName string) string {
752
753 ix := strings.LastIndex(exportName, ".")
754 if ix < 0 {
755 return ""
756 }
757 name := exportName[ix+1:]
758 if strings.HasPrefix(name, blankMarker) {
759 return "_"
760 }
761 return name
762 }
763
764 func (w *exportWriter) selector(s *types.Sym) {
765 if w.currPkg == nil {
766 base.Fatalf("missing currPkg")
767 }
768
769
770
771
772
773
774 pkg := w.currPkg
775 if types.IsExported(s.Name) {
776 pkg = types.LocalPkg
777 }
778 if s.Pkg != pkg {
779 base.Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
780 }
781
782 w.string(s.Name)
783 }
784
785 func (w *exportWriter) typ(t *types.Type) {
786 w.data.uint64(w.p.typOff(t))
787 }
788
789
790
791
792
793
794
795
796
797
798 func (w *exportWriter) exoticType(t *types.Type) {
799 switch {
800 case t == nil:
801
802 w.data.uint64(exoticTypeNil)
803 case t.IsStruct() && t.StructType().Funarg != types.FunargNone:
804
805
806
807
808 w.data.uint64(exoticTypeTuple)
809 w.uint64(uint64(t.StructType().Funarg))
810 w.uint64(uint64(t.NumFields()))
811 for _, f := range t.FieldSlice() {
812 w.pos(f.Pos)
813 s := f.Sym
814 if s == nil {
815 w.uint64(0)
816 } else if s.Pkg == nil {
817 w.uint64(exoticTypeSymNoPkg)
818 w.string(s.Name)
819 } else {
820 w.uint64(exoticTypeSymWithPkg)
821 w.pkg(s.Pkg)
822 w.string(s.Name)
823 }
824 w.typ(f.Type)
825 if f.Embedded != 0 || f.Note != "" {
826 panic("extra info in funarg struct field")
827 }
828 }
829 case t.Kind() == types.TFUNC && t.Recv() != nil:
830 w.data.uint64(exoticTypeRecv)
831
832 isFakeRecv := t.Recv().Type == types.FakeRecvType()
833 w.bool(isFakeRecv)
834 if !isFakeRecv {
835 w.exoticParam(t.Recv())
836 }
837 w.exoticSignature(t)
838
839 default:
840
841 w.data.uint64(exoticTypeRegular)
842 w.typ(t)
843 }
844 }
845
846 const (
847 exoticTypeNil = iota
848 exoticTypeTuple
849 exoticTypeRecv
850 exoticTypeRegular
851 )
852 const (
853 exoticTypeSymNil = iota
854 exoticTypeSymNoPkg
855 exoticTypeSymWithPkg
856 )
857
858
859
860
861
862
863 func (w *exportWriter) exoticSelector(s *types.Sym) {
864 pkg := w.currPkg
865 if types.IsExported(s.Name) {
866 pkg = types.LocalPkg
867 }
868
869 w.string(s.Name)
870 if s.Pkg == pkg {
871 w.uint64(0)
872 } else {
873 w.uint64(1)
874 w.pkg(s.Pkg)
875 }
876 }
877
878 func (w *exportWriter) exoticSignature(t *types.Type) {
879 hasPkg := t.Pkg() != nil
880 w.bool(hasPkg)
881 if hasPkg {
882 w.pkg(t.Pkg())
883 }
884 w.exoticParamList(t.Params().FieldSlice())
885 w.exoticParamList(t.Results().FieldSlice())
886 }
887
888 func (w *exportWriter) exoticParamList(fs []*types.Field) {
889 w.uint64(uint64(len(fs)))
890 for _, f := range fs {
891 w.exoticParam(f)
892 }
893
894 }
895 func (w *exportWriter) exoticParam(f *types.Field) {
896 w.pos(f.Pos)
897 w.exoticSym(f.Sym)
898 w.uint64(uint64(f.Offset))
899 w.exoticType(f.Type)
900 w.bool(f.IsDDD())
901 }
902
903 func (w *exportWriter) exoticField(f *types.Field) {
904 w.pos(f.Pos)
905 w.exoticSym(f.Sym)
906 w.uint64(uint64(f.Offset))
907 w.exoticType(f.Type)
908 w.string(f.Note)
909 }
910
911 func (w *exportWriter) exoticSym(s *types.Sym) {
912 if s == nil {
913 w.string("")
914 return
915 }
916 if s.Name == "" {
917 base.Fatalf("empty symbol name")
918 }
919 w.string(s.Name)
920 if !types.IsExported(s.Name) {
921 w.pkg(s.Pkg)
922 }
923 }
924
925 func (p *iexporter) newWriter() *exportWriter {
926 return &exportWriter{p: p}
927 }
928
929 func (w *exportWriter) flush() uint64 {
930 off := uint64(w.p.data0.Len())
931 io.Copy(&w.p.data0, &w.data)
932 return off
933 }
934
935 func (p *iexporter) typOff(t *types.Type) uint64 {
936 off, ok := p.typIndex[t]
937 if !ok {
938 w := p.newWriter()
939 w.doTyp(t)
940 rawOff := w.flush()
941 if *base.Flag.LowerV {
942 fmt.Printf("export: typ %v %v\n", rawOff, t)
943 }
944 off = predeclReserved + rawOff
945 p.typIndex[t] = off
946 }
947 return off
948 }
949
950 func (w *exportWriter) startType(k itag) {
951 w.data.uint64(uint64(k))
952 }
953
954 func (w *exportWriter) doTyp(t *types.Type) {
955 s := t.Sym()
956 if s != nil && t.OrigType() != nil {
957 assert(base.Flag.G > 0)
958
959
960 if strings.Index(s.Name, "[") < 0 {
961 base.Fatalf("incorrect name for instantiated type")
962 }
963 w.startType(instanceType)
964 w.pos(t.Pos())
965
966
967
968
969
970
971 w.typeList(t.RParams())
972
973 baseType := t.OrigType()
974 w.typ(baseType)
975 return
976 }
977
978
979
980
981 if t.IsTypeParam() && t.Underlying() == t {
982 assert(base.Flag.G > 0)
983 if s.Pkg == types.BuiltinPkg || s.Pkg == types.UnsafePkg {
984 base.Fatalf("builtin type missing from typIndex: %v", t)
985 }
986
987
988 w.startType(typeParamType)
989 w.qualifiedIdent(t.Obj().(*ir.Name))
990 return
991 }
992
993 if s != nil {
994 if s.Pkg == types.BuiltinPkg || s.Pkg == types.UnsafePkg {
995 base.Fatalf("builtin type missing from typIndex: %v", t)
996 }
997
998 w.startType(definedType)
999 w.qualifiedIdent(t.Obj().(*ir.Name))
1000 return
1001 }
1002
1003 switch t.Kind() {
1004 case types.TPTR:
1005 w.startType(pointerType)
1006 w.typ(t.Elem())
1007
1008 case types.TSLICE:
1009 w.startType(sliceType)
1010 w.typ(t.Elem())
1011
1012 case types.TARRAY:
1013 w.startType(arrayType)
1014 w.uint64(uint64(t.NumElem()))
1015 w.typ(t.Elem())
1016
1017 case types.TCHAN:
1018 w.startType(chanType)
1019 w.uint64(uint64(t.ChanDir()))
1020 w.typ(t.Elem())
1021
1022 case types.TMAP:
1023 w.startType(mapType)
1024 w.typ(t.Key())
1025 w.typ(t.Elem())
1026
1027 case types.TFUNC:
1028 w.startType(signatureType)
1029 w.setPkg(t.Pkg(), true)
1030 w.signature(t)
1031
1032 case types.TSTRUCT:
1033 w.startType(structType)
1034 w.setPkg(t.Pkg(), true)
1035
1036 w.uint64(uint64(t.NumFields()))
1037 for _, f := range t.FieldSlice() {
1038 w.pos(f.Pos)
1039 w.selector(f.Sym)
1040 w.typ(f.Type)
1041 w.bool(f.Embedded != 0)
1042 w.string(f.Note)
1043 }
1044
1045 case types.TINTER:
1046 var embeddeds, methods []*types.Field
1047 for _, m := range t.Methods().Slice() {
1048 if m.Sym != nil {
1049 methods = append(methods, m)
1050 } else {
1051 embeddeds = append(embeddeds, m)
1052 }
1053 }
1054
1055
1056
1057
1058 if base.Debug.UnifiedQuirks != 0 {
1059 sort.Sort(types.MethodsByName(methods))
1060 sort.Stable(types.EmbeddedsByName(embeddeds))
1061 }
1062
1063 w.startType(interfaceType)
1064 w.setPkg(t.Pkg(), true)
1065
1066 w.uint64(uint64(len(embeddeds)))
1067 for _, f := range embeddeds {
1068 w.pos(f.Pos)
1069 w.typ(f.Type)
1070 }
1071
1072 w.uint64(uint64(len(methods)))
1073 for _, f := range methods {
1074 w.pos(f.Pos)
1075 w.selector(f.Sym)
1076 w.signature(f.Type)
1077 }
1078
1079 case types.TUNION:
1080 assert(base.Flag.G > 0)
1081
1082
1083 w.startType(unionType)
1084 nt := t.NumTerms()
1085 w.uint64(uint64(nt))
1086 for i := 0; i < nt; i++ {
1087 typ, tilde := t.Term(i)
1088 w.bool(tilde)
1089 w.typ(typ)
1090 }
1091
1092 default:
1093 base.Fatalf("unexpected type: %v", t)
1094 }
1095 }
1096
1097 func (w *exportWriter) setPkg(pkg *types.Pkg, write bool) {
1098 if pkg == types.NoPkg {
1099 base.Fatalf("missing pkg")
1100 }
1101
1102 if write {
1103 w.pkg(pkg)
1104 }
1105
1106 w.currPkg = pkg
1107 }
1108
1109 func (w *exportWriter) signature(t *types.Type) {
1110 w.paramList(t.Params().FieldSlice())
1111 w.paramList(t.Results().FieldSlice())
1112 if n := t.Params().NumFields(); n > 0 {
1113 w.bool(t.Params().Field(n - 1).IsDDD())
1114 }
1115 }
1116
1117 func (w *exportWriter) typeList(ts []*types.Type) {
1118 w.uint64(uint64(len(ts)))
1119 for _, rparam := range ts {
1120 w.typ(rparam)
1121 }
1122 }
1123
1124 func (w *exportWriter) tparamList(fs []*types.Field) {
1125 w.uint64(uint64(len(fs)))
1126 for _, f := range fs {
1127 if !f.Type.IsTypeParam() {
1128 base.Fatalf("unexpected non-typeparam")
1129 }
1130 w.typ(f.Type)
1131 }
1132 }
1133
1134 func (w *exportWriter) paramList(fs []*types.Field) {
1135 w.uint64(uint64(len(fs)))
1136 for _, f := range fs {
1137 w.param(f)
1138 }
1139 }
1140
1141 func (w *exportWriter) param(f *types.Field) {
1142 w.pos(f.Pos)
1143 w.localIdent(types.OrigSym(f.Sym))
1144 w.typ(f.Type)
1145 }
1146
1147 func constTypeOf(typ *types.Type) constant.Kind {
1148 switch typ {
1149 case types.UntypedInt, types.UntypedRune:
1150 return constant.Int
1151 case types.UntypedFloat:
1152 return constant.Float
1153 case types.UntypedComplex:
1154 return constant.Complex
1155 }
1156
1157 switch typ.Kind() {
1158 case types.TBOOL:
1159 return constant.Bool
1160 case types.TSTRING:
1161 return constant.String
1162 case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64,
1163 types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINTPTR:
1164 return constant.Int
1165 case types.TFLOAT32, types.TFLOAT64:
1166 return constant.Float
1167 case types.TCOMPLEX64, types.TCOMPLEX128:
1168 return constant.Complex
1169 }
1170
1171 base.Fatalf("unexpected constant type: %v", typ)
1172 return 0
1173 }
1174
1175 func (w *exportWriter) value(typ *types.Type, v constant.Value) {
1176 w.typ(typ)
1177
1178 if iexportVersionCurrent >= iexportVersionGo1_18 {
1179 w.int64(int64(v.Kind()))
1180 }
1181
1182 var kind constant.Kind
1183 var valType *types.Type
1184
1185 if typ.IsTypeParam() {
1186 kind = v.Kind()
1187 if iexportVersionCurrent < iexportVersionGo1_18 {
1188
1189
1190
1191
1192
1193 w.int64(int64(kind))
1194 }
1195
1196 switch kind {
1197 case constant.Int:
1198 valType = types.Types[types.TINT64]
1199 case constant.Float:
1200 valType = types.Types[types.TFLOAT64]
1201 case constant.Complex:
1202 valType = types.Types[types.TCOMPLEX128]
1203 }
1204 } else {
1205 ir.AssertValidTypeForConst(typ, v)
1206 kind = constTypeOf(typ)
1207 valType = typ
1208 }
1209
1210
1211
1212
1213
1214
1215 switch kind {
1216 case constant.Bool:
1217 w.bool(constant.BoolVal(v))
1218 case constant.String:
1219 w.string(constant.StringVal(v))
1220 case constant.Int:
1221 w.mpint(v, valType)
1222 case constant.Float:
1223 w.mpfloat(v, valType)
1224 case constant.Complex:
1225 w.mpfloat(constant.Real(v), valType)
1226 w.mpfloat(constant.Imag(v), valType)
1227 }
1228 }
1229
1230 func intSize(typ *types.Type) (signed bool, maxBytes uint) {
1231 if typ.IsUntyped() {
1232 return true, ir.ConstPrec / 8
1233 }
1234
1235 switch typ.Kind() {
1236 case types.TFLOAT32, types.TCOMPLEX64:
1237 return true, 3
1238 case types.TFLOAT64, types.TCOMPLEX128:
1239 return true, 7
1240 }
1241
1242 signed = typ.IsSigned()
1243 maxBytes = uint(typ.Size())
1244
1245
1246
1247 switch typ.Kind() {
1248 case types.TINT, types.TUINT, types.TUINTPTR:
1249 maxBytes = 8
1250 }
1251
1252 return
1253 }
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273 func (w *exportWriter) mpint(x constant.Value, typ *types.Type) {
1274 signed, maxBytes := intSize(typ)
1275
1276 negative := constant.Sign(x) < 0
1277 if !signed && negative {
1278 base.Fatalf("negative unsigned integer; type %v, value %v", typ, x)
1279 }
1280
1281 b := constant.Bytes(x)
1282 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
1283 b[i], b[j] = b[j], b[i]
1284 }
1285
1286 if len(b) > 0 && b[0] == 0 {
1287 base.Fatalf("leading zeros")
1288 }
1289 if uint(len(b)) > maxBytes {
1290 base.Fatalf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)
1291 }
1292
1293 maxSmall := 256 - maxBytes
1294 if signed {
1295 maxSmall = 256 - 2*maxBytes
1296 }
1297 if maxBytes == 1 {
1298 maxSmall = 256
1299 }
1300
1301
1302 if len(b) <= 1 {
1303 var ux uint
1304 if len(b) == 1 {
1305 ux = uint(b[0])
1306 }
1307 if signed {
1308 ux <<= 1
1309 if negative {
1310 ux--
1311 }
1312 }
1313 if ux < maxSmall {
1314 w.data.WriteByte(byte(ux))
1315 return
1316 }
1317 }
1318
1319 n := 256 - uint(len(b))
1320 if signed {
1321 n = 256 - 2*uint(len(b))
1322 if negative {
1323 n |= 1
1324 }
1325 }
1326 if n < maxSmall || n >= 256 {
1327 base.Fatalf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)
1328 }
1329
1330 w.data.WriteByte(byte(n))
1331 w.data.Write(b)
1332 }
1333
1334
1335
1336
1337
1338
1339
1340 func (w *exportWriter) mpfloat(v constant.Value, typ *types.Type) {
1341 f := ir.BigFloat(v)
1342 if f.IsInf() {
1343 base.Fatalf("infinite constant")
1344 }
1345
1346
1347 var mant big.Float
1348 exp := int64(f.MantExp(&mant))
1349
1350
1351 prec := mant.MinPrec()
1352 mant.SetMantExp(&mant, int(prec))
1353 exp -= int64(prec)
1354
1355 manti, acc := mant.Int(nil)
1356 if acc != big.Exact {
1357 base.Fatalf("mantissa scaling failed for %f (%s)", f, acc)
1358 }
1359 w.mpint(constant.Make(manti), typ)
1360 if manti.Sign() != 0 {
1361 w.int64(exp)
1362 }
1363 }
1364
1365 func (w *exportWriter) mprat(v constant.Value) {
1366 r, ok := constant.Val(v).(*big.Rat)
1367 if !w.bool(ok) {
1368 return
1369 }
1370
1371
1372
1373 w.string(r.String())
1374 }
1375
1376 func (w *exportWriter) bool(b bool) bool {
1377 var x uint64
1378 if b {
1379 x = 1
1380 }
1381 w.uint64(x)
1382 return b
1383 }
1384
1385 func (w *exportWriter) int64(x int64) { w.data.int64(x) }
1386 func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
1387 func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
1388
1389
1390
1391 func (w *exportWriter) constExt(n *ir.Name) {
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411 switch n.Type() {
1412 case types.UntypedFloat:
1413 w.mprat(n.Val())
1414 case types.UntypedComplex:
1415 v := n.Val()
1416 w.mprat(constant.Real(v))
1417 w.mprat(constant.Imag(v))
1418 }
1419 }
1420
1421 func (w *exportWriter) varExt(n *ir.Name) {
1422 w.linkname(n.Sym())
1423 w.symIdx(n.Sym())
1424 }
1425
1426 func (w *exportWriter) funcExt(n *ir.Name) {
1427 w.linkname(n.Sym())
1428 w.symIdx(n.Sym())
1429
1430
1431
1432
1433 w.uint64(uint64(n.Func.ABI))
1434
1435 w.uint64(uint64(n.Func.Pragma))
1436
1437
1438 for _, fs := range &types.RecvsParams {
1439 for _, f := range fs(n.Type()).FieldSlice() {
1440 w.string(f.Note)
1441 }
1442 }
1443
1444
1445 if n.Type().HasTParam() && n.Func.Body != nil && n.Func.Inl == nil {
1446 base.FatalfAt(n.Pos(), "generic function is not marked inlineable")
1447 }
1448 if n.Func.Inl != nil {
1449 w.uint64(1 + uint64(n.Func.Inl.Cost))
1450 w.bool(n.Func.Inl.CanDelayResults)
1451 if n.Func.ExportInline() || n.Type().HasTParam() {
1452 if n.Type().HasTParam() {
1453
1454
1455
1456 ImportedBody(n.Func)
1457 }
1458 w.p.doInline(n)
1459 }
1460
1461
1462 w.pos(n.Func.Endlineno)
1463 } else {
1464 w.uint64(0)
1465 }
1466 }
1467
1468 func (w *exportWriter) methExt(m *types.Field) {
1469 w.bool(m.Nointerface())
1470 w.funcExt(m.Nname.(*ir.Name))
1471 }
1472
1473 func (w *exportWriter) linkname(s *types.Sym) {
1474 w.string(s.Linkname)
1475 }
1476
1477 func (w *exportWriter) symIdx(s *types.Sym) {
1478 lsym := s.Linksym()
1479 if lsym.PkgIdx > goobj.PkgIdxSelf || (lsym.PkgIdx == goobj.PkgIdxInvalid && !lsym.Indexed()) || s.Linkname != "" {
1480
1481
1482
1483 w.int64(-1)
1484 } else {
1485
1486
1487 w.int64(int64(lsym.SymIdx))
1488 }
1489 }
1490
1491 func (w *exportWriter) typeExt(t *types.Type) {
1492
1493 w.bool(t.NotInHeap())
1494
1495 if i, ok := typeSymIdx[t]; ok {
1496 w.int64(i[0])
1497 w.int64(i[1])
1498 return
1499 }
1500 w.symIdx(types.TypeSym(t))
1501 w.symIdx(types.TypeSym(t.PtrTo()))
1502 }
1503
1504
1505
1506 func (w *exportWriter) writeNames(dcl []*ir.Name) {
1507 w.int64(int64(len(dcl)))
1508 for i, n := range dcl {
1509 w.pos(n.Pos())
1510 w.localIdent(n.Sym())
1511 w.typ(n.Type())
1512 w.dclIndex[n] = w.maxDclIndex + i
1513 }
1514 w.maxDclIndex += len(dcl)
1515 }
1516
1517 func (w *exportWriter) funcBody(fn *ir.Func) {
1518
1519 w.writeNames(fn.Inl.Dcl)
1520
1521 w.stmtList(fn.Inl.Body)
1522 }
1523
1524 func (w *exportWriter) stmtList(list []ir.Node) {
1525 for _, n := range list {
1526 w.node(n)
1527 }
1528 w.op(ir.OEND)
1529 }
1530
1531 func (w *exportWriter) node(n ir.Node) {
1532 if ir.OpPrec[n.Op()] < 0 {
1533 w.stmt(n)
1534 } else {
1535 w.expr(n)
1536 }
1537 }
1538
1539 func isNonEmptyAssign(n ir.Node) bool {
1540 switch n.Op() {
1541 case ir.OAS:
1542 if n.(*ir.AssignStmt).Y != nil {
1543 return true
1544 }
1545 case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
1546 return true
1547 }
1548 return false
1549 }
1550
1551
1552
1553
1554 func (w *exportWriter) stmt(n ir.Node) {
1555 if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) && !isNonEmptyAssign(n) && n.Op() != ir.ORANGE {
1556
1557 for _, n := range n.Init() {
1558 w.stmt(n)
1559 }
1560 }
1561
1562 switch n.Op() {
1563 case ir.OBLOCK:
1564
1565
1566
1567
1568
1569
1570 n := n.(*ir.BlockStmt)
1571 for _, n := range n.List {
1572 w.stmt(n)
1573 }
1574
1575 case ir.ODCL:
1576 n := n.(*ir.Decl)
1577 if ir.IsBlank(n.X) {
1578 return
1579 }
1580 w.op(ir.ODCL)
1581 w.localName(n.X)
1582
1583 case ir.OAS:
1584
1585
1586
1587 n := n.(*ir.AssignStmt)
1588 if n.Y != nil {
1589 w.op(ir.OAS)
1590 w.pos(n.Pos())
1591 w.stmtList(n.Init())
1592 w.expr(n.X)
1593 w.expr(n.Y)
1594 w.bool(n.Def)
1595 }
1596
1597 case ir.OASOP:
1598 n := n.(*ir.AssignOpStmt)
1599 w.op(ir.OASOP)
1600 w.pos(n.Pos())
1601 w.op(n.AsOp)
1602 w.expr(n.X)
1603 if w.bool(!n.IncDec) {
1604 w.expr(n.Y)
1605 }
1606
1607 case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
1608 n := n.(*ir.AssignListStmt)
1609 if go117ExportTypes {
1610 w.op(n.Op())
1611 } else {
1612 w.op(ir.OAS2)
1613 }
1614 w.pos(n.Pos())
1615 w.stmtList(n.Init())
1616 w.exprList(n.Lhs)
1617 w.exprList(n.Rhs)
1618 w.bool(n.Def)
1619
1620 case ir.ORETURN:
1621 n := n.(*ir.ReturnStmt)
1622 w.op(ir.ORETURN)
1623 w.pos(n.Pos())
1624 w.exprList(n.Results)
1625
1626
1627
1628
1629 case ir.OGO, ir.ODEFER:
1630 n := n.(*ir.GoDeferStmt)
1631 w.op(n.Op())
1632 w.pos(n.Pos())
1633 w.expr(n.Call)
1634
1635 case ir.OIF:
1636 n := n.(*ir.IfStmt)
1637 w.op(ir.OIF)
1638 w.pos(n.Pos())
1639 w.stmtList(n.Init())
1640 w.expr(n.Cond)
1641 w.stmtList(n.Body)
1642 w.stmtList(n.Else)
1643
1644 case ir.OFOR:
1645 n := n.(*ir.ForStmt)
1646 w.op(ir.OFOR)
1647 w.pos(n.Pos())
1648 w.stmtList(n.Init())
1649 w.exprsOrNil(n.Cond, n.Post)
1650 w.stmtList(n.Body)
1651
1652 case ir.ORANGE:
1653 n := n.(*ir.RangeStmt)
1654 w.op(ir.ORANGE)
1655 w.pos(n.Pos())
1656 w.stmtList(n.Init())
1657 w.exprsOrNil(n.Key, n.Value)
1658 w.expr(n.X)
1659 w.stmtList(n.Body)
1660
1661 case ir.OSELECT:
1662 n := n.(*ir.SelectStmt)
1663 w.op(n.Op())
1664 w.pos(n.Pos())
1665 w.stmtList(n.Init())
1666 w.commList(n.Cases)
1667
1668 case ir.OSWITCH:
1669 n := n.(*ir.SwitchStmt)
1670 w.op(n.Op())
1671 w.pos(n.Pos())
1672 w.stmtList(n.Init())
1673 w.exprsOrNil(n.Tag, nil)
1674 w.caseList(n.Cases, isNamedTypeSwitch(n.Tag))
1675
1676
1677
1678
1679 case ir.OFALL:
1680 n := n.(*ir.BranchStmt)
1681 w.op(ir.OFALL)
1682 w.pos(n.Pos())
1683
1684 case ir.OBREAK, ir.OCONTINUE, ir.OGOTO, ir.OLABEL:
1685 w.op(n.Op())
1686 w.pos(n.Pos())
1687 label := ""
1688 if sym := n.Sym(); sym != nil {
1689 label = sym.Name
1690 }
1691 w.string(label)
1692
1693 default:
1694 base.Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op())
1695 }
1696 }
1697
1698 func isNamedTypeSwitch(x ir.Node) bool {
1699 guard, ok := x.(*ir.TypeSwitchGuard)
1700 return ok && guard.Tag != nil
1701 }
1702
1703 func (w *exportWriter) caseList(cases []*ir.CaseClause, namedTypeSwitch bool) {
1704 w.uint64(uint64(len(cases)))
1705 for _, cas := range cases {
1706 w.pos(cas.Pos())
1707 w.stmtList(cas.List)
1708 if namedTypeSwitch {
1709 w.localName(cas.Var)
1710 }
1711 w.stmtList(cas.Body)
1712 }
1713 }
1714
1715 func (w *exportWriter) commList(cases []*ir.CommClause) {
1716 w.uint64(uint64(len(cases)))
1717 for _, cas := range cases {
1718 w.pos(cas.Pos())
1719 defaultCase := cas.Comm == nil
1720 w.bool(defaultCase)
1721 if !defaultCase {
1722
1723 w.node(cas.Comm)
1724 }
1725 w.stmtList(cas.Body)
1726 }
1727 }
1728
1729 func (w *exportWriter) exprList(list ir.Nodes) {
1730 for _, n := range list {
1731 w.expr(n)
1732 }
1733 w.op(ir.OEND)
1734 }
1735
1736 func simplifyForExport(n ir.Node) ir.Node {
1737 switch n.Op() {
1738 case ir.OPAREN:
1739 n := n.(*ir.ParenExpr)
1740 return simplifyForExport(n.X)
1741 }
1742 return n
1743 }
1744
1745 func (w *exportWriter) expr(n ir.Node) {
1746 n = simplifyForExport(n)
1747 switch n.Op() {
1748
1749
1750 case ir.ONIL:
1751 n := n.(*ir.NilExpr)
1752
1753
1754 if !n.Type().IsTypeParam() && !n.Type().HasNil() {
1755 base.Fatalf("unexpected type for nil: %v", n.Type())
1756 }
1757 w.op(ir.ONIL)
1758 w.pos(n.Pos())
1759 w.typ(n.Type())
1760
1761 case ir.OLITERAL:
1762 w.op(ir.OLITERAL)
1763 if ir.HasUniquePos(n) {
1764 w.pos(n.Pos())
1765 } else {
1766 w.pos(src.NoXPos)
1767 }
1768 w.value(n.Type(), n.Val())
1769
1770 case ir.ONAME:
1771
1772 n := n.(*ir.Name)
1773 if (n.Class == ir.PEXTERN || n.Class == ir.PFUNC) && !ir.IsBlank(n) {
1774 w.op(ir.ONONAME)
1775
1776 w.bool(false)
1777 w.qualifiedIdent(n)
1778 if go117ExportTypes {
1779 w.typ(n.Type())
1780 }
1781 break
1782 }
1783
1784
1785
1786
1787 w.op(ir.ONAME)
1788
1789
1790
1791
1792 isBuiltin := n.BuiltinOp != ir.OXXX
1793 w.bool(isBuiltin)
1794 if isBuiltin {
1795 w.bool(n.Sym().Pkg == types.UnsafePkg)
1796 w.string(n.Sym().Name)
1797 break
1798 }
1799 w.localName(n)
1800
1801 case ir.ONONAME:
1802 w.op(ir.ONONAME)
1803
1804
1805 w.bool(true)
1806 s := n.Sym()
1807 w.string(s.Name)
1808 w.pkg(s.Pkg)
1809 if go117ExportTypes {
1810 w.typ(n.Type())
1811 }
1812
1813
1814
1815
1816 case ir.OTYPE:
1817 w.op(ir.OTYPE)
1818 w.typ(n.Type())
1819
1820 case ir.ODYNAMICTYPE:
1821 n := n.(*ir.DynamicType)
1822 w.op(ir.ODYNAMICTYPE)
1823 w.pos(n.Pos())
1824 w.expr(n.X)
1825 if n.ITab != nil {
1826 w.bool(true)
1827 w.expr(n.ITab)
1828 } else {
1829 w.bool(false)
1830 }
1831 w.typ(n.Type())
1832
1833 case ir.OTYPESW:
1834 n := n.(*ir.TypeSwitchGuard)
1835 w.op(ir.OTYPESW)
1836 w.pos(n.Pos())
1837 var s *types.Sym
1838 if n.Tag != nil {
1839 if n.Tag.Op() != ir.ONONAME {
1840 base.Fatalf("expected ONONAME, got %v", n.Tag)
1841 }
1842 s = n.Tag.Sym()
1843 }
1844 w.localIdent(s)
1845 w.expr(n.X)
1846
1847
1848
1849
1850 case ir.OCLOSURE:
1851 n := n.(*ir.ClosureExpr)
1852 w.op(ir.OCLOSURE)
1853 w.pos(n.Pos())
1854 old := w.currPkg
1855 w.setPkg(n.Type().Pkg(), true)
1856 w.signature(n.Type())
1857 w.setPkg(old, true)
1858
1859
1860
1861
1862 w.int64(int64(len(n.Func.ClosureVars)))
1863 for i, cv := range n.Func.ClosureVars {
1864 w.pos(cv.Pos())
1865 w.localName(cv.Outer)
1866
1867
1868
1869
1870 w.dclIndex[cv] = -(i + 2) - w.maxClosureVarIndex
1871 }
1872 w.maxClosureVarIndex += len(n.Func.ClosureVars)
1873
1874
1875 w.writeNames(n.Func.Dcl)
1876 w.stmtList(n.Func.Body)
1877
1878
1879
1880
1881 case ir.OPTRLIT:
1882 n := n.(*ir.AddrExpr)
1883 if go117ExportTypes {
1884 w.op(ir.OPTRLIT)
1885 } else {
1886 w.op(ir.OADDR)
1887 }
1888 w.pos(n.Pos())
1889 w.expr(n.X)
1890 if go117ExportTypes {
1891 w.typ(n.Type())
1892 }
1893
1894 case ir.OSTRUCTLIT:
1895 n := n.(*ir.CompLitExpr)
1896 w.op(ir.OSTRUCTLIT)
1897 w.pos(n.Pos())
1898 w.typ(n.Type())
1899 w.fieldList(n.List)
1900
1901 case ir.OCOMPLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
1902 n := n.(*ir.CompLitExpr)
1903 if go117ExportTypes {
1904 w.op(n.Op())
1905 } else {
1906 w.op(ir.OCOMPLIT)
1907 }
1908 w.pos(n.Pos())
1909 w.typ(n.Type())
1910 w.exprList(n.List)
1911 if go117ExportTypes && n.Op() == ir.OSLICELIT {
1912 w.uint64(uint64(n.Len))
1913 }
1914 case ir.OKEY:
1915 n := n.(*ir.KeyExpr)
1916 w.op(ir.OKEY)
1917 w.pos(n.Pos())
1918 w.expr(n.Key)
1919 w.expr(n.Value)
1920
1921
1922
1923
1924 case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OMETHVALUE, ir.OMETHEXPR:
1925 n := n.(*ir.SelectorExpr)
1926 if go117ExportTypes {
1927
1928
1929 w.op(n.Op())
1930 } else {
1931 w.op(ir.OXDOT)
1932 }
1933 w.pos(n.Pos())
1934 w.expr(n.X)
1935 w.exoticSelector(n.Sel)
1936 if go117ExportTypes {
1937 w.exoticType(n.Type())
1938 if n.Op() == ir.OXDOT {
1939
1940
1941 w.bool(n.Selection != nil)
1942 } else if n.Op() == ir.ODOT || n.Op() == ir.ODOTPTR || n.Op() == ir.ODOTINTER {
1943 w.exoticField(n.Selection)
1944 }
1945
1946
1947
1948 }
1949
1950 case ir.ODOTTYPE, ir.ODOTTYPE2:
1951 n := n.(*ir.TypeAssertExpr)
1952 if go117ExportTypes {
1953 w.op(n.Op())
1954 } else {
1955 w.op(ir.ODOTTYPE)
1956 }
1957 w.pos(n.Pos())
1958 w.expr(n.X)
1959 w.typ(n.Type())
1960
1961 case ir.ODYNAMICDOTTYPE, ir.ODYNAMICDOTTYPE2:
1962 n := n.(*ir.DynamicTypeAssertExpr)
1963 w.op(n.Op())
1964 w.pos(n.Pos())
1965 w.expr(n.X)
1966 w.expr(n.T)
1967 w.typ(n.Type())
1968
1969 case ir.OINDEX, ir.OINDEXMAP:
1970 n := n.(*ir.IndexExpr)
1971 if go117ExportTypes {
1972 w.op(n.Op())
1973 } else {
1974 w.op(ir.OINDEX)
1975 }
1976 w.pos(n.Pos())
1977 w.expr(n.X)
1978 w.expr(n.Index)
1979 if go117ExportTypes {
1980 w.exoticType(n.Type())
1981 if n.Op() == ir.OINDEXMAP {
1982 w.bool(n.Assigned)
1983 }
1984 }
1985
1986 case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR:
1987 n := n.(*ir.SliceExpr)
1988 if go117ExportTypes {
1989 w.op(n.Op())
1990 } else {
1991 w.op(ir.OSLICE)
1992 }
1993 w.pos(n.Pos())
1994 w.expr(n.X)
1995 w.exprsOrNil(n.Low, n.High)
1996 if go117ExportTypes {
1997 w.typ(n.Type())
1998 }
1999
2000 case ir.OSLICE3, ir.OSLICE3ARR:
2001 n := n.(*ir.SliceExpr)
2002 if go117ExportTypes {
2003 w.op(n.Op())
2004 } else {
2005 w.op(ir.OSLICE3)
2006 }
2007 w.pos(n.Pos())
2008 w.expr(n.X)
2009 w.exprsOrNil(n.Low, n.High)
2010 w.expr(n.Max)
2011 if go117ExportTypes {
2012 w.typ(n.Type())
2013 }
2014
2015 case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
2016
2017 n := n.(*ir.BinaryExpr)
2018 w.op(n.Op())
2019 w.pos(n.Pos())
2020 w.expr(n.X)
2021 w.expr(n.Y)
2022 if go117ExportTypes {
2023 w.typ(n.Type())
2024 } else {
2025 w.op(ir.OEND)
2026 }
2027
2028 case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
2029 n := n.(*ir.ConvExpr)
2030 if go117ExportTypes {
2031 w.op(n.Op())
2032 } else {
2033 w.op(ir.OCONV)
2034 }
2035 w.pos(n.Pos())
2036 w.typ(n.Type())
2037 w.expr(n.X)
2038
2039 case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
2040 n := n.(*ir.UnaryExpr)
2041 w.op(n.Op())
2042 w.pos(n.Pos())
2043 w.expr(n.X)
2044 if go117ExportTypes {
2045 if n.Op() != ir.OPANIC {
2046 w.typ(n.Type())
2047 }
2048 } else {
2049 w.op(ir.OEND)
2050 }
2051
2052 case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
2053 n := n.(*ir.CallExpr)
2054 w.op(n.Op())
2055 w.pos(n.Pos())
2056 w.exprList(n.Args)
2057
2058 if n.Op() == ir.OAPPEND {
2059 w.bool(n.IsDDD)
2060 } else if n.IsDDD {
2061 base.Fatalf("exporter: unexpected '...' with %v call", n.Op())
2062 }
2063 if go117ExportTypes {
2064 if n.Op() != ir.ODELETE && n.Op() != ir.OPRINT && n.Op() != ir.OPRINTN {
2065 w.typ(n.Type())
2066 }
2067 }
2068
2069 case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
2070 n := n.(*ir.CallExpr)
2071 if go117ExportTypes {
2072 w.op(n.Op())
2073 } else {
2074 w.op(ir.OCALL)
2075 }
2076 w.pos(n.Pos())
2077 w.stmtList(n.Init())
2078 w.expr(n.X)
2079 w.exprList(n.Args)
2080 w.bool(n.IsDDD)
2081 if go117ExportTypes {
2082 w.exoticType(n.Type())
2083 }
2084
2085 case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
2086 n := n.(*ir.MakeExpr)
2087 w.op(n.Op())
2088 w.pos(n.Pos())
2089 w.typ(n.Type())
2090 switch {
2091 default:
2092
2093 w.op(ir.OEND)
2094 case n.Cap != nil:
2095 w.expr(n.Len)
2096 w.expr(n.Cap)
2097 w.op(ir.OEND)
2098 case n.Len != nil && (n.Op() == ir.OMAKESLICE || !n.Len.Type().IsUntyped()):
2099
2100
2101
2102 w.expr(n.Len)
2103 w.op(ir.OEND)
2104 case n.Len != nil && go117ExportTypes:
2105 w.expr(n.Len)
2106 w.op(ir.OEND)
2107 }
2108
2109 case ir.OLINKSYMOFFSET:
2110 n := n.(*ir.LinksymOffsetExpr)
2111 w.op(ir.OLINKSYMOFFSET)
2112 w.pos(n.Pos())
2113 w.string(n.Linksym.Name)
2114 w.uint64(uint64(n.Offset_))
2115 w.typ(n.Type())
2116
2117
2118 case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV, ir.OIDATA:
2119 n := n.(*ir.UnaryExpr)
2120 w.op(n.Op())
2121 w.pos(n.Pos())
2122 w.expr(n.X)
2123 if go117ExportTypes {
2124 w.typ(n.Type())
2125 }
2126
2127 case ir.OADDR:
2128 n := n.(*ir.AddrExpr)
2129 w.op(n.Op())
2130 w.pos(n.Pos())
2131 w.expr(n.X)
2132 if go117ExportTypes {
2133 w.typ(n.Type())
2134 }
2135
2136 case ir.ODEREF:
2137 n := n.(*ir.StarExpr)
2138 w.op(n.Op())
2139 w.pos(n.Pos())
2140 w.expr(n.X)
2141 if go117ExportTypes {
2142 w.typ(n.Type())
2143 }
2144
2145 case ir.OSEND:
2146 n := n.(*ir.SendStmt)
2147 w.op(n.Op())
2148 w.pos(n.Pos())
2149 w.expr(n.Chan)
2150 w.expr(n.Value)
2151
2152
2153 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
2154 ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR, ir.OEFACE:
2155 n := n.(*ir.BinaryExpr)
2156 w.op(n.Op())
2157 w.pos(n.Pos())
2158 w.expr(n.X)
2159 w.expr(n.Y)
2160 if go117ExportTypes {
2161 w.typ(n.Type())
2162 }
2163
2164 case ir.OANDAND, ir.OOROR:
2165 n := n.(*ir.LogicalExpr)
2166 w.op(n.Op())
2167 w.pos(n.Pos())
2168 w.expr(n.X)
2169 w.expr(n.Y)
2170 if go117ExportTypes {
2171 w.typ(n.Type())
2172 }
2173
2174 case ir.OADDSTR:
2175 n := n.(*ir.AddStringExpr)
2176 w.op(ir.OADDSTR)
2177 w.pos(n.Pos())
2178 w.exprList(n.List)
2179 if go117ExportTypes {
2180 w.typ(n.Type())
2181 }
2182
2183 case ir.ODCLCONST:
2184
2185
2186
2187 case ir.OFUNCINST:
2188 n := n.(*ir.InstExpr)
2189 w.op(ir.OFUNCINST)
2190 w.pos(n.Pos())
2191 w.expr(n.X)
2192 w.uint64(uint64(len(n.Targs)))
2193 for _, targ := range n.Targs {
2194 w.typ(targ.Type())
2195 }
2196 if go117ExportTypes {
2197 w.typ(n.Type())
2198 }
2199
2200 case ir.OSELRECV2:
2201 n := n.(*ir.AssignListStmt)
2202 w.op(ir.OSELRECV2)
2203 w.pos(n.Pos())
2204 w.stmtList(n.Init())
2205 w.exprList(n.Lhs)
2206 w.exprList(n.Rhs)
2207 w.bool(n.Def)
2208
2209 default:
2210 base.Fatalf("cannot export %v (%d) node\n"+
2211 "\t==> please file an issue and assign to gri@", n.Op(), int(n.Op()))
2212 }
2213 }
2214
2215 func (w *exportWriter) op(op ir.Op) {
2216 if debug {
2217 w.uint64(magic)
2218 }
2219 w.uint64(uint64(op))
2220 }
2221
2222 func (w *exportWriter) exprsOrNil(a, b ir.Node) {
2223 ab := 0
2224 if a != nil {
2225 ab |= 1
2226 }
2227 if b != nil {
2228 ab |= 2
2229 }
2230 w.uint64(uint64(ab))
2231 if ab&1 != 0 {
2232 w.expr(a)
2233 }
2234 if ab&2 != 0 {
2235 w.node(b)
2236 }
2237 }
2238
2239 func (w *exportWriter) fieldList(list ir.Nodes) {
2240 w.uint64(uint64(len(list)))
2241 for _, n := range list {
2242 n := n.(*ir.StructKeyExpr)
2243 w.pos(n.Pos())
2244 w.exoticField(n.Field)
2245 w.expr(n.Value)
2246 }
2247 }
2248
2249 func (w *exportWriter) localName(n *ir.Name) {
2250 if ir.IsBlank(n) {
2251 w.int64(-1)
2252 return
2253 }
2254
2255 i, ok := w.dclIndex[n]
2256 if !ok {
2257 base.FatalfAt(n.Pos(), "missing from dclIndex: %+v", n)
2258 }
2259 w.int64(int64(i))
2260 }
2261
2262 func (w *exportWriter) localIdent(s *types.Sym) {
2263 if w.currPkg == nil {
2264 base.Fatalf("missing currPkg")
2265 }
2266
2267
2268 if s == nil {
2269 w.string("")
2270 return
2271 }
2272
2273 name := s.Name
2274 if name == "_" {
2275 w.string("_")
2276 return
2277 }
2278
2279
2280
2281
2282 if strings.HasPrefix(name, ".autotmp_") {
2283 w.string("$autotmp")
2284 return
2285 }
2286
2287 if i := strings.LastIndex(name, "."); i >= 0 && !strings.HasPrefix(name, LocalDictName) && !strings.HasPrefix(name, ".rcvr") {
2288 base.Fatalf("unexpected dot in identifier: %v", name)
2289 }
2290
2291 if s.Pkg != w.currPkg {
2292 base.Fatalf("weird package in name: %v => %v from %q, not %q", s, name, s.Pkg.Path, w.currPkg.Path)
2293 }
2294
2295 w.string(name)
2296 }
2297
2298 type intWriter struct {
2299 bytes.Buffer
2300 }
2301
2302 func (w *intWriter) int64(x int64) {
2303 var buf [binary.MaxVarintLen64]byte
2304 n := binary.PutVarint(buf[:], x)
2305 w.Write(buf[:n])
2306 }
2307
2308 func (w *intWriter) uint64(x uint64) {
2309 var buf [binary.MaxVarintLen64]byte
2310 n := binary.PutUvarint(buf[:], x)
2311 w.Write(buf[:n])
2312 }
2313
2314
2315
2316
2317
2318
2319
2320
2321 const go117ExportTypes = true
2322 const Go117ExportTypes = go117ExportTypes
2323
2324
2325 const LocalDictName = ".dict"
2326
View as plain text