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 package typecheck
203
204 import (
205 "bufio"
206 "bytes"
207 "crypto/md5"
208 "encoding/binary"
209 "fmt"
210 "go/constant"
211 "io"
212 "math/big"
213 "sort"
214 "strings"
215
216 "cmd/compile/internal/base"
217 "cmd/compile/internal/ir"
218 "cmd/compile/internal/types"
219 "cmd/internal/goobj"
220 "cmd/internal/src"
221 )
222
223
224
225
226 const iexportVersion = 1
227
228
229
230 const predeclReserved = 32
231
232
233
234 type itag uint64
235
236 const (
237
238 definedType itag = iota
239 pointerType
240 sliceType
241 arrayType
242 chanType
243 mapType
244 signatureType
245 structType
246 interfaceType
247 )
248
249 const (
250 debug = false
251 magic = 0x6742937dc293105
252 )
253
254 func WriteExports(out *bufio.Writer) {
255 p := iexporter{
256 allPkgs: map[*types.Pkg]bool{},
257 stringIndex: map[string]uint64{},
258 declIndex: map[*types.Sym]uint64{},
259 inlineIndex: map[*types.Sym]uint64{},
260 typIndex: map[*types.Type]uint64{},
261 }
262
263 for i, pt := range predeclared() {
264 p.typIndex[pt] = uint64(i)
265 }
266 if len(p.typIndex) > predeclReserved {
267 base.Fatalf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)
268 }
269
270
271 for _, n := range Target.Exports {
272 p.pushDecl(n)
273 }
274
275
276
277
278 for !p.declTodo.Empty() {
279 p.doDecl(p.declTodo.PopLeft())
280 }
281
282
283 dataLen := uint64(p.data0.Len())
284 w := p.newWriter()
285 w.writeIndex(p.declIndex, true)
286 w.writeIndex(p.inlineIndex, false)
287 w.flush()
288
289 if *base.Flag.LowerV {
290 fmt.Printf("export: hdr strings %v, data %v, index %v\n", p.strings.Len(), dataLen, p.data0.Len())
291 }
292
293
294 var hdr intWriter
295 hdr.WriteByte('i')
296 hdr.uint64(iexportVersion)
297 hdr.uint64(uint64(p.strings.Len()))
298 hdr.uint64(dataLen)
299
300
301 h := md5.New()
302 wr := io.MultiWriter(out, h)
303 io.Copy(wr, &hdr)
304 io.Copy(wr, &p.strings)
305 io.Copy(wr, &p.data0)
306
307
308
309 copy(base.Ctxt.Fingerprint[:], h.Sum(nil)[:])
310 out.Write(base.Ctxt.Fingerprint[:])
311 }
312
313
314
315
316
317 func (w *exportWriter) writeIndex(index map[*types.Sym]uint64, mainIndex bool) {
318
319 pkgSyms := map[*types.Pkg][]*types.Sym{}
320
321
322
323
324 if mainIndex {
325 pkgSyms[types.LocalPkg] = nil
326 for pkg := range w.p.allPkgs {
327 pkgSyms[pkg] = nil
328 }
329 }
330
331
332 for sym := range index {
333 pkgSyms[sym.Pkg] = append(pkgSyms[sym.Pkg], sym)
334 }
335
336
337 var pkgs []*types.Pkg
338 for pkg := range pkgSyms {
339 pkgs = append(pkgs, pkg)
340 }
341 sort.Slice(pkgs, func(i, j int) bool {
342 return pkgs[i].Path < pkgs[j].Path
343 })
344
345 w.uint64(uint64(len(pkgs)))
346 for _, pkg := range pkgs {
347 w.string(pkg.Path)
348 if mainIndex {
349 w.string(pkg.Name)
350 w.uint64(uint64(pkg.Height))
351 }
352
353
354 syms := pkgSyms[pkg]
355 sort.Slice(syms, func(i, j int) bool {
356 return syms[i].Name < syms[j].Name
357 })
358
359 w.uint64(uint64(len(syms)))
360 for _, sym := range syms {
361 w.string(sym.Name)
362 w.uint64(index[sym])
363 }
364 }
365 }
366
367 type iexporter struct {
368
369
370
371 allPkgs map[*types.Pkg]bool
372
373 declTodo ir.NameQueue
374
375 strings intWriter
376 stringIndex map[string]uint64
377
378 data0 intWriter
379 declIndex map[*types.Sym]uint64
380 inlineIndex map[*types.Sym]uint64
381 typIndex map[*types.Type]uint64
382 }
383
384
385
386 func (p *iexporter) stringOff(s string) uint64 {
387 off, ok := p.stringIndex[s]
388 if !ok {
389 off = uint64(p.strings.Len())
390 p.stringIndex[s] = off
391
392 if *base.Flag.LowerV {
393 fmt.Printf("export: str %v %.40q\n", off, s)
394 }
395
396 p.strings.uint64(uint64(len(s)))
397 p.strings.WriteString(s)
398 }
399 return off
400 }
401
402
403 func (p *iexporter) pushDecl(n *ir.Name) {
404 if n.Sym() == nil || n.Sym().Def != n && n.Op() != ir.OTYPE {
405 base.Fatalf("weird Sym: %v, %v", n, n.Sym())
406 }
407
408
409 if n.Sym().Pkg == types.BuiltinPkg || n.Sym().Pkg == ir.Pkgs.Unsafe {
410 return
411 }
412
413 if _, ok := p.declIndex[n.Sym()]; ok {
414 return
415 }
416
417 p.declIndex[n.Sym()] = ^uint64(0)
418 p.declTodo.PushRight(n)
419 }
420
421
422 type exportWriter struct {
423 p *iexporter
424
425 data intWriter
426 currPkg *types.Pkg
427 prevFile string
428 prevLine int64
429 prevColumn int64
430
431
432
433
434
435 dclIndex map[*ir.Name]int
436 maxDclIndex int
437 maxClosureVarIndex int
438 }
439
440 func (p *iexporter) doDecl(n *ir.Name) {
441 w := p.newWriter()
442 w.setPkg(n.Sym().Pkg, false)
443
444 switch n.Op() {
445 case ir.ONAME:
446 switch n.Class {
447 case ir.PEXTERN:
448
449 w.tag('V')
450 w.pos(n.Pos())
451 w.typ(n.Type())
452 w.varExt(n)
453
454 case ir.PFUNC:
455 if ir.IsMethod(n) {
456 base.Fatalf("unexpected method: %v", n)
457 }
458
459
460 w.tag('F')
461 w.pos(n.Pos())
462 w.signature(n.Type())
463 w.funcExt(n)
464
465 default:
466 base.Fatalf("unexpected class: %v, %v", n, n.Class)
467 }
468
469 case ir.OLITERAL:
470
471 if n.Typecheck() == 0 {
472 base.FatalfAt(n.Pos(), "missed typecheck: %v", n)
473 }
474
475
476 w.tag('C')
477 w.pos(n.Pos())
478 w.value(n.Type(), n.Val())
479 w.constExt(n)
480
481 case ir.OTYPE:
482 if types.IsDotAlias(n.Sym()) {
483
484 w.tag('A')
485 w.pos(n.Pos())
486 w.typ(n.Type())
487 break
488 }
489
490
491 w.tag('T')
492 w.pos(n.Pos())
493
494 underlying := n.Type().Underlying()
495 if underlying == types.ErrorType.Underlying() {
496
497
498
499
500
501
502 underlying = types.ErrorType
503 }
504 w.typ(underlying)
505
506 t := n.Type()
507 if t.IsInterface() {
508 w.typeExt(t)
509 break
510 }
511
512 ms := t.Methods()
513 w.uint64(uint64(ms.Len()))
514 for _, m := range ms.Slice() {
515 w.pos(m.Pos)
516 w.selector(m.Sym)
517 w.param(m.Type.Recv())
518 w.signature(m.Type)
519 }
520
521 w.typeExt(t)
522 for _, m := range ms.Slice() {
523 w.methExt(m)
524 }
525
526 default:
527 base.Fatalf("unexpected node: %v", n)
528 }
529
530 w.finish("dcl", p.declIndex, n.Sym())
531 }
532
533 func (w *exportWriter) tag(tag byte) {
534 w.data.WriteByte(tag)
535 }
536
537 func (w *exportWriter) finish(what string, index map[*types.Sym]uint64, sym *types.Sym) {
538 off := w.flush()
539 if *base.Flag.LowerV {
540 fmt.Printf("export: %v %v %v\n", what, off, sym)
541 }
542 index[sym] = off
543 }
544
545 func (p *iexporter) doInline(f *ir.Name) {
546 w := p.newWriter()
547 w.setPkg(fnpkg(f), false)
548
549 w.dclIndex = make(map[*ir.Name]int, len(f.Func.Inl.Dcl))
550 w.funcBody(f.Func)
551
552 w.finish("inl", p.inlineIndex, f.Sym())
553 }
554
555 func (w *exportWriter) pos(pos src.XPos) {
556 p := base.Ctxt.PosTable.Pos(pos)
557 file := p.Base().AbsFilename()
558 line := int64(p.RelLine())
559 column := int64(p.RelCol())
560
561
562
563
564
565
566
567
568
569
570
571 deltaColumn := (column - w.prevColumn) << 1
572 deltaLine := (line - w.prevLine) << 1
573
574 if file != w.prevFile {
575 deltaLine |= 1
576 }
577 if deltaLine != 0 {
578 deltaColumn |= 1
579 }
580
581 w.int64(deltaColumn)
582 if deltaColumn&1 != 0 {
583 w.int64(deltaLine)
584 if deltaLine&1 != 0 {
585 w.string(file)
586 }
587 }
588
589 w.prevFile = file
590 w.prevLine = line
591 w.prevColumn = column
592 }
593
594 func (w *exportWriter) pkg(pkg *types.Pkg) {
595
596 if pkg == ir.Pkgs.Go {
597 base.Fatalf("export of pseudo-package: %q", pkg.Path)
598 }
599
600
601 w.p.allPkgs[pkg] = true
602
603 w.string(pkg.Path)
604 }
605
606 func (w *exportWriter) qualifiedIdent(n *ir.Name) {
607
608 w.p.pushDecl(n)
609
610 s := n.Sym()
611 w.string(s.Name)
612 w.pkg(s.Pkg)
613 }
614
615 func (w *exportWriter) selector(s *types.Sym) {
616 if w.currPkg == nil {
617 base.Fatalf("missing currPkg")
618 }
619
620
621
622
623
624
625 pkg := w.currPkg
626 if types.IsExported(s.Name) {
627 pkg = types.LocalPkg
628 }
629 if s.Pkg != pkg {
630 base.Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
631 }
632
633 w.string(s.Name)
634 }
635
636 func (w *exportWriter) typ(t *types.Type) {
637 w.data.uint64(w.p.typOff(t))
638 }
639
640
641
642
643
644
645
646
647
648
649 func (w *exportWriter) exoticType(t *types.Type) {
650 switch {
651 case t == nil:
652
653 w.data.uint64(exoticTypeNil)
654 case t.IsStruct() && t.StructType().Funarg != types.FunargNone:
655
656
657
658
659 w.data.uint64(exoticTypeTuple)
660 w.uint64(uint64(t.StructType().Funarg))
661 w.uint64(uint64(t.NumFields()))
662 for _, f := range t.FieldSlice() {
663 w.pos(f.Pos)
664 s := f.Sym
665 if s == nil {
666 w.uint64(0)
667 } else if s.Pkg == nil {
668 w.uint64(exoticTypeSymNoPkg)
669 w.string(s.Name)
670 } else {
671 w.uint64(exoticTypeSymWithPkg)
672 w.pkg(s.Pkg)
673 w.string(s.Name)
674 }
675 w.typ(f.Type)
676 if f.Embedded != 0 || f.Note != "" {
677 panic("extra info in funarg struct field")
678 }
679 }
680 case t.Kind() == types.TFUNC && t.Recv() != nil:
681 w.data.uint64(exoticTypeRecv)
682
683 isFakeRecv := t.Recv().Type == types.FakeRecvType()
684 w.bool(isFakeRecv)
685 if !isFakeRecv {
686 w.exoticParam(t.Recv())
687 }
688 w.exoticSignature(t)
689
690 default:
691
692 w.data.uint64(exoticTypeRegular)
693 w.typ(t)
694 }
695 }
696
697 const (
698 exoticTypeNil = iota
699 exoticTypeTuple
700 exoticTypeRecv
701 exoticTypeRegular
702 )
703 const (
704 exoticTypeSymNil = iota
705 exoticTypeSymNoPkg
706 exoticTypeSymWithPkg
707 )
708
709
710
711
712
713
714 func (w *exportWriter) exoticSelector(s *types.Sym) {
715 pkg := w.currPkg
716 if types.IsExported(s.Name) {
717 pkg = types.LocalPkg
718 }
719
720 w.string(s.Name)
721 if s.Pkg == pkg {
722 w.uint64(0)
723 } else {
724 w.uint64(1)
725 w.pkg(s.Pkg)
726 }
727 }
728
729 func (w *exportWriter) exoticSignature(t *types.Type) {
730 hasPkg := t.Pkg() != nil
731 w.bool(hasPkg)
732 if hasPkg {
733 w.pkg(t.Pkg())
734 }
735 w.exoticParamList(t.Params().FieldSlice())
736 w.exoticParamList(t.Results().FieldSlice())
737 }
738
739 func (w *exportWriter) exoticParamList(fs []*types.Field) {
740 w.uint64(uint64(len(fs)))
741 for _, f := range fs {
742 w.exoticParam(f)
743 }
744
745 }
746 func (w *exportWriter) exoticParam(f *types.Field) {
747 w.pos(f.Pos)
748 w.exoticSym(f.Sym)
749 w.uint64(uint64(f.Offset))
750 w.exoticType(f.Type)
751 w.bool(f.IsDDD())
752 }
753
754 func (w *exportWriter) exoticField(f *types.Field) {
755 w.pos(f.Pos)
756 w.exoticSym(f.Sym)
757 w.uint64(uint64(f.Offset))
758 w.exoticType(f.Type)
759 w.string(f.Note)
760 }
761
762 func (w *exportWriter) exoticSym(s *types.Sym) {
763 if s == nil {
764 w.string("")
765 return
766 }
767 if s.Name == "" {
768 base.Fatalf("empty symbol name")
769 }
770 w.string(s.Name)
771 if !types.IsExported(s.Name) {
772 w.pkg(s.Pkg)
773 }
774 }
775
776 func (p *iexporter) newWriter() *exportWriter {
777 return &exportWriter{p: p}
778 }
779
780 func (w *exportWriter) flush() uint64 {
781 off := uint64(w.p.data0.Len())
782 io.Copy(&w.p.data0, &w.data)
783 return off
784 }
785
786 func (p *iexporter) typOff(t *types.Type) uint64 {
787 off, ok := p.typIndex[t]
788 if !ok {
789 w := p.newWriter()
790 w.doTyp(t)
791 rawOff := w.flush()
792 if *base.Flag.LowerV {
793 fmt.Printf("export: typ %v %v\n", rawOff, t)
794 }
795 off = predeclReserved + rawOff
796 p.typIndex[t] = off
797 }
798 return off
799 }
800
801 func (w *exportWriter) startType(k itag) {
802 w.data.uint64(uint64(k))
803 }
804
805 func (w *exportWriter) doTyp(t *types.Type) {
806 if t.Sym() != nil {
807 if t.Sym().Pkg == types.BuiltinPkg || t.Sym().Pkg == ir.Pkgs.Unsafe {
808 base.Fatalf("builtin type missing from typIndex: %v", t)
809 }
810
811 w.startType(definedType)
812 w.qualifiedIdent(t.Obj().(*ir.Name))
813 return
814 }
815
816 switch t.Kind() {
817 case types.TPTR:
818 w.startType(pointerType)
819 w.typ(t.Elem())
820
821 case types.TSLICE:
822 w.startType(sliceType)
823 w.typ(t.Elem())
824
825 case types.TARRAY:
826 w.startType(arrayType)
827 w.uint64(uint64(t.NumElem()))
828 w.typ(t.Elem())
829
830 case types.TCHAN:
831 w.startType(chanType)
832 w.uint64(uint64(t.ChanDir()))
833 w.typ(t.Elem())
834
835 case types.TMAP:
836 w.startType(mapType)
837 w.typ(t.Key())
838 w.typ(t.Elem())
839
840 case types.TFUNC:
841 w.startType(signatureType)
842 w.setPkg(t.Pkg(), true)
843 w.signature(t)
844
845 case types.TSTRUCT:
846 w.startType(structType)
847 w.setPkg(t.Pkg(), true)
848
849 w.uint64(uint64(t.NumFields()))
850 for _, f := range t.FieldSlice() {
851 w.pos(f.Pos)
852 w.selector(f.Sym)
853 w.typ(f.Type)
854 w.bool(f.Embedded != 0)
855 w.string(f.Note)
856 }
857
858 case types.TINTER:
859 var embeddeds, methods []*types.Field
860 for _, m := range t.Methods().Slice() {
861 if m.Sym != nil {
862 methods = append(methods, m)
863 } else {
864 embeddeds = append(embeddeds, m)
865 }
866 }
867
868 w.startType(interfaceType)
869 w.setPkg(t.Pkg(), true)
870
871 w.uint64(uint64(len(embeddeds)))
872 for _, f := range embeddeds {
873 w.pos(f.Pos)
874 w.typ(f.Type)
875 }
876
877 w.uint64(uint64(len(methods)))
878 for _, f := range methods {
879 w.pos(f.Pos)
880 w.selector(f.Sym)
881 w.signature(f.Type)
882 }
883
884 default:
885 base.Fatalf("unexpected type: %v", t)
886 }
887 }
888
889 func (w *exportWriter) setPkg(pkg *types.Pkg, write bool) {
890 if pkg == types.NoPkg {
891 base.Fatalf("missing pkg")
892 }
893
894 if write {
895 w.pkg(pkg)
896 }
897
898 w.currPkg = pkg
899 }
900
901 func (w *exportWriter) signature(t *types.Type) {
902 w.paramList(t.Params().FieldSlice())
903 w.paramList(t.Results().FieldSlice())
904 if n := t.Params().NumFields(); n > 0 {
905 w.bool(t.Params().Field(n - 1).IsDDD())
906 }
907 }
908
909 func (w *exportWriter) paramList(fs []*types.Field) {
910 w.uint64(uint64(len(fs)))
911 for _, f := range fs {
912 w.param(f)
913 }
914 }
915
916 func (w *exportWriter) param(f *types.Field) {
917 w.pos(f.Pos)
918 w.localIdent(types.OrigSym(f.Sym))
919 w.typ(f.Type)
920 }
921
922 func constTypeOf(typ *types.Type) constant.Kind {
923 switch typ {
924 case types.UntypedInt, types.UntypedRune:
925 return constant.Int
926 case types.UntypedFloat:
927 return constant.Float
928 case types.UntypedComplex:
929 return constant.Complex
930 }
931
932 switch typ.Kind() {
933 case types.TBOOL:
934 return constant.Bool
935 case types.TSTRING:
936 return constant.String
937 case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64,
938 types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINTPTR:
939 return constant.Int
940 case types.TFLOAT32, types.TFLOAT64:
941 return constant.Float
942 case types.TCOMPLEX64, types.TCOMPLEX128:
943 return constant.Complex
944 }
945
946 base.Fatalf("unexpected constant type: %v", typ)
947 return 0
948 }
949
950 func (w *exportWriter) value(typ *types.Type, v constant.Value) {
951 ir.AssertValidTypeForConst(typ, v)
952 w.typ(typ)
953
954
955
956
957
958
959 switch constTypeOf(typ) {
960 case constant.Bool:
961 w.bool(constant.BoolVal(v))
962 case constant.String:
963 w.string(constant.StringVal(v))
964 case constant.Int:
965 w.mpint(v, typ)
966 case constant.Float:
967 w.mpfloat(v, typ)
968 case constant.Complex:
969 w.mpfloat(constant.Real(v), typ)
970 w.mpfloat(constant.Imag(v), typ)
971 }
972 }
973
974 func intSize(typ *types.Type) (signed bool, maxBytes uint) {
975 if typ.IsUntyped() {
976 return true, ir.ConstPrec / 8
977 }
978
979 switch typ.Kind() {
980 case types.TFLOAT32, types.TCOMPLEX64:
981 return true, 3
982 case types.TFLOAT64, types.TCOMPLEX128:
983 return true, 7
984 }
985
986 signed = typ.IsSigned()
987 maxBytes = uint(typ.Size())
988
989
990
991 switch typ.Kind() {
992 case types.TINT, types.TUINT, types.TUINTPTR:
993 maxBytes = 8
994 }
995
996 return
997 }
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 func (w *exportWriter) mpint(x constant.Value, typ *types.Type) {
1018 signed, maxBytes := intSize(typ)
1019
1020 negative := constant.Sign(x) < 0
1021 if !signed && negative {
1022 base.Fatalf("negative unsigned integer; type %v, value %v", typ, x)
1023 }
1024
1025 b := constant.Bytes(x)
1026 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
1027 b[i], b[j] = b[j], b[i]
1028 }
1029
1030 if len(b) > 0 && b[0] == 0 {
1031 base.Fatalf("leading zeros")
1032 }
1033 if uint(len(b)) > maxBytes {
1034 base.Fatalf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)
1035 }
1036
1037 maxSmall := 256 - maxBytes
1038 if signed {
1039 maxSmall = 256 - 2*maxBytes
1040 }
1041 if maxBytes == 1 {
1042 maxSmall = 256
1043 }
1044
1045
1046 if len(b) <= 1 {
1047 var ux uint
1048 if len(b) == 1 {
1049 ux = uint(b[0])
1050 }
1051 if signed {
1052 ux <<= 1
1053 if negative {
1054 ux--
1055 }
1056 }
1057 if ux < maxSmall {
1058 w.data.WriteByte(byte(ux))
1059 return
1060 }
1061 }
1062
1063 n := 256 - uint(len(b))
1064 if signed {
1065 n = 256 - 2*uint(len(b))
1066 if negative {
1067 n |= 1
1068 }
1069 }
1070 if n < maxSmall || n >= 256 {
1071 base.Fatalf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)
1072 }
1073
1074 w.data.WriteByte(byte(n))
1075 w.data.Write(b)
1076 }
1077
1078
1079
1080
1081
1082
1083
1084 func (w *exportWriter) mpfloat(v constant.Value, typ *types.Type) {
1085 f := ir.BigFloat(v)
1086 if f.IsInf() {
1087 base.Fatalf("infinite constant")
1088 }
1089
1090
1091 var mant big.Float
1092 exp := int64(f.MantExp(&mant))
1093
1094
1095 prec := mant.MinPrec()
1096 mant.SetMantExp(&mant, int(prec))
1097 exp -= int64(prec)
1098
1099 manti, acc := mant.Int(nil)
1100 if acc != big.Exact {
1101 base.Fatalf("mantissa scaling failed for %f (%s)", f, acc)
1102 }
1103 w.mpint(constant.Make(manti), typ)
1104 if manti.Sign() != 0 {
1105 w.int64(exp)
1106 }
1107 }
1108
1109 func (w *exportWriter) mprat(v constant.Value) {
1110 r, ok := constant.Val(v).(*big.Rat)
1111 if !w.bool(ok) {
1112 return
1113 }
1114
1115
1116
1117 w.string(r.String())
1118 }
1119
1120 func (w *exportWriter) bool(b bool) bool {
1121 var x uint64
1122 if b {
1123 x = 1
1124 }
1125 w.uint64(x)
1126 return b
1127 }
1128
1129 func (w *exportWriter) int64(x int64) { w.data.int64(x) }
1130 func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
1131 func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
1132
1133
1134
1135 func (w *exportWriter) constExt(n *ir.Name) {
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 switch n.Type() {
1156 case types.UntypedFloat:
1157 w.mprat(n.Val())
1158 case types.UntypedComplex:
1159 v := n.Val()
1160 w.mprat(constant.Real(v))
1161 w.mprat(constant.Imag(v))
1162 }
1163 }
1164
1165 func (w *exportWriter) varExt(n *ir.Name) {
1166 w.linkname(n.Sym())
1167 w.symIdx(n.Sym())
1168 }
1169
1170 func (w *exportWriter) funcExt(n *ir.Name) {
1171 w.linkname(n.Sym())
1172 w.symIdx(n.Sym())
1173
1174
1175
1176
1177 w.uint64(uint64(n.Func.ABI))
1178
1179 w.uint64(uint64(n.Func.Pragma))
1180
1181
1182 for _, fs := range &types.RecvsParams {
1183 for _, f := range fs(n.Type()).FieldSlice() {
1184 w.string(f.Note)
1185 }
1186 }
1187
1188
1189 if n.Func.Inl != nil {
1190 w.uint64(1 + uint64(n.Func.Inl.Cost))
1191 if n.Func.ExportInline() {
1192 w.p.doInline(n)
1193 }
1194
1195
1196 w.pos(n.Func.Endlineno)
1197 } else {
1198 w.uint64(0)
1199 }
1200 }
1201
1202 func (w *exportWriter) methExt(m *types.Field) {
1203 w.bool(m.Nointerface())
1204 w.funcExt(m.Nname.(*ir.Name))
1205 }
1206
1207 func (w *exportWriter) linkname(s *types.Sym) {
1208 w.string(s.Linkname)
1209 }
1210
1211 func (w *exportWriter) symIdx(s *types.Sym) {
1212 lsym := s.Linksym()
1213 if lsym.PkgIdx > goobj.PkgIdxSelf || (lsym.PkgIdx == goobj.PkgIdxInvalid && !lsym.Indexed()) || s.Linkname != "" {
1214
1215
1216
1217 w.int64(-1)
1218 } else {
1219
1220
1221 w.int64(int64(lsym.SymIdx))
1222 }
1223 }
1224
1225 func (w *exportWriter) typeExt(t *types.Type) {
1226
1227 w.bool(t.NotInHeap())
1228
1229 if i, ok := typeSymIdx[t]; ok {
1230 w.int64(i[0])
1231 w.int64(i[1])
1232 return
1233 }
1234 w.symIdx(types.TypeSym(t))
1235 w.symIdx(types.TypeSym(t.PtrTo()))
1236 }
1237
1238
1239
1240 func (w *exportWriter) writeNames(dcl []*ir.Name) {
1241 w.int64(int64(len(dcl)))
1242 for i, n := range dcl {
1243 w.pos(n.Pos())
1244 w.localIdent(n.Sym())
1245 w.typ(n.Type())
1246 w.dclIndex[n] = w.maxDclIndex + i
1247 }
1248 w.maxDclIndex += len(dcl)
1249 }
1250
1251 func (w *exportWriter) funcBody(fn *ir.Func) {
1252
1253 w.writeNames(fn.Inl.Dcl)
1254
1255 w.stmtList(fn.Inl.Body)
1256 }
1257
1258 func (w *exportWriter) stmtList(list []ir.Node) {
1259 for _, n := range list {
1260 w.node(n)
1261 }
1262 w.op(ir.OEND)
1263 }
1264
1265 func (w *exportWriter) node(n ir.Node) {
1266 if ir.OpPrec[n.Op()] < 0 {
1267 w.stmt(n)
1268 } else {
1269 w.expr(n)
1270 }
1271 }
1272
1273
1274
1275 func (w *exportWriter) stmt(n ir.Node) {
1276 if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) {
1277
1278 for _, n := range n.Init() {
1279 w.stmt(n)
1280 }
1281 }
1282
1283 switch n.Op() {
1284 case ir.OBLOCK:
1285
1286
1287
1288
1289
1290
1291 n := n.(*ir.BlockStmt)
1292 for _, n := range n.List {
1293 w.stmt(n)
1294 }
1295
1296 case ir.ODCL:
1297 n := n.(*ir.Decl)
1298 if ir.IsBlank(n.X) {
1299 return
1300 }
1301 w.op(ir.ODCL)
1302 w.localName(n.X)
1303
1304 case ir.OAS:
1305
1306
1307
1308 n := n.(*ir.AssignStmt)
1309 if n.Y != nil {
1310 w.op(ir.OAS)
1311 w.pos(n.Pos())
1312 w.expr(n.X)
1313 w.expr(n.Y)
1314 }
1315
1316 case ir.OASOP:
1317 n := n.(*ir.AssignOpStmt)
1318 w.op(ir.OASOP)
1319 w.pos(n.Pos())
1320 w.op(n.AsOp)
1321 w.expr(n.X)
1322 if w.bool(!n.IncDec) {
1323 w.expr(n.Y)
1324 }
1325
1326 case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
1327 n := n.(*ir.AssignListStmt)
1328 if go117ExportTypes {
1329 w.op(n.Op())
1330 } else {
1331 w.op(ir.OAS2)
1332 }
1333 w.pos(n.Pos())
1334 w.exprList(n.Lhs)
1335 w.exprList(n.Rhs)
1336
1337 case ir.ORETURN:
1338 n := n.(*ir.ReturnStmt)
1339 w.op(ir.ORETURN)
1340 w.pos(n.Pos())
1341 w.exprList(n.Results)
1342
1343
1344
1345
1346 case ir.OGO, ir.ODEFER:
1347 n := n.(*ir.GoDeferStmt)
1348 w.op(n.Op())
1349 w.pos(n.Pos())
1350 w.expr(n.Call)
1351
1352 case ir.OIF:
1353 n := n.(*ir.IfStmt)
1354 w.op(ir.OIF)
1355 w.pos(n.Pos())
1356 w.stmtList(n.Init())
1357 w.expr(n.Cond)
1358 w.stmtList(n.Body)
1359 w.stmtList(n.Else)
1360
1361 case ir.OFOR:
1362 n := n.(*ir.ForStmt)
1363 w.op(ir.OFOR)
1364 w.pos(n.Pos())
1365 w.stmtList(n.Init())
1366 w.exprsOrNil(n.Cond, n.Post)
1367 w.stmtList(n.Body)
1368
1369 case ir.ORANGE:
1370 n := n.(*ir.RangeStmt)
1371 w.op(ir.ORANGE)
1372 w.pos(n.Pos())
1373 w.exprsOrNil(n.Key, n.Value)
1374 w.expr(n.X)
1375 w.stmtList(n.Body)
1376
1377 case ir.OSELECT:
1378 n := n.(*ir.SelectStmt)
1379 w.op(n.Op())
1380 w.pos(n.Pos())
1381 w.stmtList(n.Init())
1382 w.commList(n.Cases)
1383
1384 case ir.OSWITCH:
1385 n := n.(*ir.SwitchStmt)
1386 w.op(n.Op())
1387 w.pos(n.Pos())
1388 w.stmtList(n.Init())
1389 w.exprsOrNil(n.Tag, nil)
1390 w.caseList(n.Cases, isNamedTypeSwitch(n.Tag))
1391
1392
1393
1394
1395 case ir.OFALL:
1396 n := n.(*ir.BranchStmt)
1397 w.op(ir.OFALL)
1398 w.pos(n.Pos())
1399
1400 case ir.OBREAK, ir.OCONTINUE, ir.OGOTO, ir.OLABEL:
1401 w.op(n.Op())
1402 w.pos(n.Pos())
1403 label := ""
1404 if sym := n.Sym(); sym != nil {
1405 label = sym.Name
1406 }
1407 w.string(label)
1408
1409 default:
1410 base.Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op())
1411 }
1412 }
1413
1414 func isNamedTypeSwitch(x ir.Node) bool {
1415 guard, ok := x.(*ir.TypeSwitchGuard)
1416 return ok && guard.Tag != nil
1417 }
1418
1419 func (w *exportWriter) caseList(cases []*ir.CaseClause, namedTypeSwitch bool) {
1420 w.uint64(uint64(len(cases)))
1421 for _, cas := range cases {
1422 w.pos(cas.Pos())
1423 w.stmtList(cas.List)
1424 if namedTypeSwitch {
1425 w.localName(cas.Var)
1426 }
1427 w.stmtList(cas.Body)
1428 }
1429 }
1430
1431 func (w *exportWriter) commList(cases []*ir.CommClause) {
1432 w.uint64(uint64(len(cases)))
1433 for _, cas := range cases {
1434 w.pos(cas.Pos())
1435 w.node(cas.Comm)
1436 w.stmtList(cas.Body)
1437 }
1438 }
1439
1440 func (w *exportWriter) exprList(list ir.Nodes) {
1441 for _, n := range list {
1442 w.expr(n)
1443 }
1444 w.op(ir.OEND)
1445 }
1446
1447 func simplifyForExport(n ir.Node) ir.Node {
1448 switch n.Op() {
1449 case ir.OPAREN:
1450 n := n.(*ir.ParenExpr)
1451 return simplifyForExport(n.X)
1452 }
1453 return n
1454 }
1455
1456 func (w *exportWriter) expr(n ir.Node) {
1457 n = simplifyForExport(n)
1458 switch n.Op() {
1459
1460
1461 case ir.ONIL:
1462 n := n.(*ir.NilExpr)
1463 if !n.Type().HasNil() {
1464 base.Fatalf("unexpected type for nil: %v", n.Type())
1465 }
1466 w.op(ir.ONIL)
1467 w.pos(n.Pos())
1468 w.typ(n.Type())
1469
1470 case ir.OLITERAL:
1471 w.op(ir.OLITERAL)
1472 w.pos(n.Pos())
1473 w.value(n.Type(), n.Val())
1474
1475 case ir.ONAME:
1476
1477 n := n.(*ir.Name)
1478 if (n.Class == ir.PEXTERN || n.Class == ir.PFUNC) && !ir.IsBlank(n) {
1479 w.op(ir.ONONAME)
1480 w.qualifiedIdent(n)
1481 if go117ExportTypes {
1482 w.typ(n.Type())
1483 }
1484 break
1485 }
1486
1487
1488
1489
1490 w.op(ir.ONAME)
1491 w.localName(n)
1492
1493
1494
1495
1496 case ir.OTYPE:
1497 w.op(ir.OTYPE)
1498 w.typ(n.Type())
1499
1500 case ir.OTYPESW:
1501 n := n.(*ir.TypeSwitchGuard)
1502 w.op(ir.OTYPESW)
1503 w.pos(n.Pos())
1504 var s *types.Sym
1505 if n.Tag != nil {
1506 if n.Tag.Op() != ir.ONONAME {
1507 base.Fatalf("expected ONONAME, got %v", n.Tag)
1508 }
1509 s = n.Tag.Sym()
1510 }
1511 w.localIdent(s)
1512 w.expr(n.X)
1513
1514
1515
1516
1517 case ir.OCLOSURE:
1518 n := n.(*ir.ClosureExpr)
1519 w.op(ir.OCLOSURE)
1520 w.pos(n.Pos())
1521 w.signature(n.Type())
1522
1523
1524
1525
1526 w.int64(int64(len(n.Func.ClosureVars)))
1527 for i, cv := range n.Func.ClosureVars {
1528 w.pos(cv.Pos())
1529 w.localName(cv.Outer)
1530
1531
1532
1533
1534 w.dclIndex[cv] = -(i + 2) - w.maxClosureVarIndex
1535 }
1536 w.maxClosureVarIndex += len(n.Func.ClosureVars)
1537
1538
1539 w.writeNames(n.Func.Dcl)
1540 w.stmtList(n.Func.Body)
1541
1542
1543
1544
1545 case ir.OPTRLIT:
1546 n := n.(*ir.AddrExpr)
1547 if go117ExportTypes {
1548 w.op(ir.OPTRLIT)
1549 } else {
1550 w.op(ir.OADDR)
1551 }
1552 w.pos(n.Pos())
1553 w.expr(n.X)
1554 if go117ExportTypes {
1555 w.typ(n.Type())
1556 }
1557
1558 case ir.OSTRUCTLIT:
1559 n := n.(*ir.CompLitExpr)
1560 w.op(ir.OSTRUCTLIT)
1561 w.pos(n.Pos())
1562 w.typ(n.Type())
1563 w.fieldList(n.List)
1564
1565 case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
1566 n := n.(*ir.CompLitExpr)
1567 if go117ExportTypes {
1568 w.op(n.Op())
1569 } else {
1570 w.op(ir.OCOMPLIT)
1571 }
1572 w.pos(n.Pos())
1573 w.typ(n.Type())
1574 w.exprList(n.List)
1575 if go117ExportTypes && n.Op() == ir.OSLICELIT {
1576 w.uint64(uint64(n.Len))
1577 }
1578 case ir.OKEY:
1579 n := n.(*ir.KeyExpr)
1580 w.op(ir.OKEY)
1581 w.pos(n.Pos())
1582 w.expr(n.Key)
1583 w.expr(n.Value)
1584
1585
1586
1587
1588 case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
1589 n := n.(*ir.SelectorExpr)
1590 if go117ExportTypes {
1591 if n.Op() == ir.OXDOT {
1592 base.Fatalf("shouldn't encounter XDOT in new exporter")
1593 }
1594 w.op(n.Op())
1595 } else {
1596 w.op(ir.OXDOT)
1597 }
1598 w.pos(n.Pos())
1599 w.expr(n.X)
1600 w.exoticSelector(n.Sel)
1601 if go117ExportTypes {
1602 w.exoticType(n.Type())
1603 if n.Op() == ir.ODOT || n.Op() == ir.ODOTPTR || n.Op() == ir.ODOTINTER {
1604 w.exoticField(n.Selection)
1605 }
1606
1607
1608 }
1609
1610 case ir.ODOTTYPE, ir.ODOTTYPE2:
1611 n := n.(*ir.TypeAssertExpr)
1612 if go117ExportTypes {
1613 w.op(n.Op())
1614 } else {
1615 w.op(ir.ODOTTYPE)
1616 }
1617 w.pos(n.Pos())
1618 w.expr(n.X)
1619 w.typ(n.Type())
1620
1621 case ir.OINDEX, ir.OINDEXMAP:
1622 n := n.(*ir.IndexExpr)
1623 if go117ExportTypes {
1624 w.op(n.Op())
1625 } else {
1626 w.op(ir.OINDEX)
1627 }
1628 w.pos(n.Pos())
1629 w.expr(n.X)
1630 w.expr(n.Index)
1631 if go117ExportTypes {
1632 w.typ(n.Type())
1633 if n.Op() == ir.OINDEXMAP {
1634 w.bool(n.Assigned)
1635 }
1636 }
1637
1638 case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR:
1639 n := n.(*ir.SliceExpr)
1640 if go117ExportTypes {
1641 w.op(n.Op())
1642 } else {
1643 w.op(ir.OSLICE)
1644 }
1645 w.pos(n.Pos())
1646 w.expr(n.X)
1647 w.exprsOrNil(n.Low, n.High)
1648 if go117ExportTypes {
1649 w.typ(n.Type())
1650 }
1651
1652 case ir.OSLICE3, ir.OSLICE3ARR:
1653 n := n.(*ir.SliceExpr)
1654 if go117ExportTypes {
1655 w.op(n.Op())
1656 } else {
1657 w.op(ir.OSLICE3)
1658 }
1659 w.pos(n.Pos())
1660 w.expr(n.X)
1661 w.exprsOrNil(n.Low, n.High)
1662 w.expr(n.Max)
1663 if go117ExportTypes {
1664 w.typ(n.Type())
1665 }
1666
1667 case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
1668
1669 n := n.(*ir.BinaryExpr)
1670 w.op(n.Op())
1671 w.pos(n.Pos())
1672 w.expr(n.X)
1673 w.expr(n.Y)
1674 if go117ExportTypes {
1675 w.typ(n.Type())
1676 } else {
1677 w.op(ir.OEND)
1678 }
1679
1680 case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
1681 n := n.(*ir.ConvExpr)
1682 if go117ExportTypes {
1683 w.op(n.Op())
1684 } else {
1685 w.op(ir.OCONV)
1686 }
1687 w.pos(n.Pos())
1688 w.typ(n.Type())
1689 w.expr(n.X)
1690
1691 case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
1692 n := n.(*ir.UnaryExpr)
1693 w.op(n.Op())
1694 w.pos(n.Pos())
1695 w.expr(n.X)
1696 if go117ExportTypes {
1697 if n.Op() != ir.OPANIC {
1698 w.typ(n.Type())
1699 }
1700 } else {
1701 w.op(ir.OEND)
1702 }
1703
1704 case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
1705 n := n.(*ir.CallExpr)
1706 w.op(n.Op())
1707 w.pos(n.Pos())
1708 w.exprList(n.Args)
1709
1710 if n.Op() == ir.OAPPEND {
1711 w.bool(n.IsDDD)
1712 } else if n.IsDDD {
1713 base.Fatalf("exporter: unexpected '...' with %v call", n.Op())
1714 }
1715 if go117ExportTypes {
1716 if n.Op() != ir.ODELETE && n.Op() != ir.OPRINT && n.Op() != ir.OPRINTN {
1717 w.typ(n.Type())
1718 }
1719 }
1720
1721 case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
1722 n := n.(*ir.CallExpr)
1723 if go117ExportTypes {
1724 w.op(n.Op())
1725 } else {
1726 w.op(ir.OCALL)
1727 }
1728 w.pos(n.Pos())
1729 w.stmtList(n.Init())
1730 w.expr(n.X)
1731 w.exprList(n.Args)
1732 w.bool(n.IsDDD)
1733 if go117ExportTypes {
1734 w.exoticType(n.Type())
1735 w.uint64(uint64(n.Use))
1736 }
1737
1738 case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
1739 n := n.(*ir.MakeExpr)
1740 w.op(n.Op())
1741 w.pos(n.Pos())
1742 w.typ(n.Type())
1743 switch {
1744 default:
1745
1746 w.op(ir.OEND)
1747 case n.Cap != nil:
1748 w.expr(n.Len)
1749 w.expr(n.Cap)
1750 w.op(ir.OEND)
1751 case n.Len != nil && (n.Op() == ir.OMAKESLICE || !n.Len.Type().IsUntyped()):
1752
1753
1754
1755 w.expr(n.Len)
1756 w.op(ir.OEND)
1757 case n.Len != nil && go117ExportTypes:
1758 w.expr(n.Len)
1759 w.op(ir.OEND)
1760 }
1761
1762
1763 case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
1764 n := n.(*ir.UnaryExpr)
1765 w.op(n.Op())
1766 w.pos(n.Pos())
1767 w.expr(n.X)
1768 if go117ExportTypes {
1769 w.typ(n.Type())
1770 }
1771
1772 case ir.OADDR:
1773 n := n.(*ir.AddrExpr)
1774 w.op(n.Op())
1775 w.pos(n.Pos())
1776 w.expr(n.X)
1777 if go117ExportTypes {
1778 w.typ(n.Type())
1779 }
1780
1781 case ir.ODEREF:
1782 n := n.(*ir.StarExpr)
1783 w.op(n.Op())
1784 w.pos(n.Pos())
1785 w.expr(n.X)
1786 if go117ExportTypes {
1787 w.typ(n.Type())
1788 }
1789
1790 case ir.OSEND:
1791 n := n.(*ir.SendStmt)
1792 w.op(n.Op())
1793 w.pos(n.Pos())
1794 w.expr(n.Chan)
1795 w.expr(n.Value)
1796
1797
1798 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
1799 ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
1800 n := n.(*ir.BinaryExpr)
1801 w.op(n.Op())
1802 w.pos(n.Pos())
1803 w.expr(n.X)
1804 w.expr(n.Y)
1805 if go117ExportTypes {
1806 w.typ(n.Type())
1807 }
1808
1809 case ir.OANDAND, ir.OOROR:
1810 n := n.(*ir.LogicalExpr)
1811 w.op(n.Op())
1812 w.pos(n.Pos())
1813 w.expr(n.X)
1814 w.expr(n.Y)
1815 if go117ExportTypes {
1816 w.typ(n.Type())
1817 }
1818
1819 case ir.OADDSTR:
1820 n := n.(*ir.AddStringExpr)
1821 w.op(ir.OADDSTR)
1822 w.pos(n.Pos())
1823 w.exprList(n.List)
1824 if go117ExportTypes {
1825 w.typ(n.Type())
1826 }
1827
1828 case ir.ODCLCONST:
1829
1830
1831
1832 default:
1833 base.Fatalf("cannot export %v (%d) node\n"+
1834 "\t==> please file an issue and assign to gri@", n.Op(), int(n.Op()))
1835 }
1836 }
1837
1838 func (w *exportWriter) op(op ir.Op) {
1839 if debug {
1840 w.uint64(magic)
1841 }
1842 w.uint64(uint64(op))
1843 }
1844
1845 func (w *exportWriter) exprsOrNil(a, b ir.Node) {
1846 ab := 0
1847 if a != nil {
1848 ab |= 1
1849 }
1850 if b != nil {
1851 ab |= 2
1852 }
1853 w.uint64(uint64(ab))
1854 if ab&1 != 0 {
1855 w.expr(a)
1856 }
1857 if ab&2 != 0 {
1858 w.node(b)
1859 }
1860 }
1861
1862 func (w *exportWriter) fieldList(list ir.Nodes) {
1863 w.uint64(uint64(len(list)))
1864 for _, n := range list {
1865 n := n.(*ir.StructKeyExpr)
1866 w.pos(n.Pos())
1867 w.selector(n.Field)
1868 w.expr(n.Value)
1869 if go117ExportTypes {
1870 w.uint64(uint64(n.Offset))
1871 }
1872 }
1873 }
1874
1875 func (w *exportWriter) localName(n *ir.Name) {
1876 if ir.IsBlank(n) {
1877 w.int64(-1)
1878 return
1879 }
1880
1881 i, ok := w.dclIndex[n]
1882 if !ok {
1883 base.FatalfAt(n.Pos(), "missing from dclIndex: %+v", n)
1884 }
1885 w.int64(int64(i))
1886 }
1887
1888 func (w *exportWriter) localIdent(s *types.Sym) {
1889 if w.currPkg == nil {
1890 base.Fatalf("missing currPkg")
1891 }
1892
1893
1894 if s == nil {
1895 w.string("")
1896 return
1897 }
1898
1899 name := s.Name
1900 if name == "_" {
1901 w.string("_")
1902 return
1903 }
1904
1905
1906 if i := strings.LastIndex(name, "."); i >= 0 && !strings.HasPrefix(name, ".autotmp_") {
1907 base.Fatalf("unexpected dot in identifier: %v", name)
1908 }
1909
1910 if s.Pkg != w.currPkg {
1911 base.Fatalf("weird package in name: %v => %v from %q, not %q", s, name, s.Pkg.Path, w.currPkg.Path)
1912 }
1913
1914 w.string(name)
1915 }
1916
1917 type intWriter struct {
1918 bytes.Buffer
1919 }
1920
1921 func (w *intWriter) int64(x int64) {
1922 var buf [binary.MaxVarintLen64]byte
1923 n := binary.PutVarint(buf[:], x)
1924 w.Write(buf[:n])
1925 }
1926
1927 func (w *intWriter) uint64(x uint64) {
1928 var buf [binary.MaxVarintLen64]byte
1929 n := binary.PutUvarint(buf[:], x)
1930 w.Write(buf[:n])
1931 }
1932
1933
1934
1935
1936
1937
1938
1939
1940 const go117ExportTypes = true
1941 const Go117ExportTypes = go117ExportTypes
1942
View as plain text