mirror of
https://github.com/golang/go.git
synced 2025-05-22 16:09:37 +00:00
[dev.link] all: merge branch 'master' into dev.link
Fixed a couple of minor conflicts in lib.go and deadcode.go relating to debug logging. Change-Id: I58335fc42ab1f1f3409fd8354da4f26419e8fb22
This commit is contained in:
commit
c0555a2a7a
@ -90,7 +90,7 @@ func getTitle(w http.ResponseWriter, r *http.Request) (string, error) {
|
||||
m := validPath.FindStringSubmatch(r.URL.Path)
|
||||
if m == nil {
|
||||
http.NotFound(w, r)
|
||||
return "", errors.New("Invalid Page Title")
|
||||
return "", errors.New("invalid Page Title")
|
||||
}
|
||||
return m[2], nil // The title is the second subexpression.
|
||||
}
|
||||
|
@ -54,6 +54,15 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.13.3">Go
|
||||
1.13.3 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.13.4 (released 2019/10/31) includes fixes to the <code>net/http</code> and
|
||||
<code>syscall</code> packages. It also fixes an issue on macOS 10.15 Catalina
|
||||
where the non-notarized installer and binaries were being
|
||||
<a href="https://golang.org/issue/34986">rejected by Gatekeeper</a>.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.13.4">Go
|
||||
1.13.4 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.12">go1.12 (released 2019/02/25)</h2>
|
||||
|
||||
<p>
|
||||
@ -150,6 +159,13 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.12">Go
|
||||
1.12.12 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.13 (released 2019/10/31) fixes an issue on macOS 10.15 Catalina
|
||||
where the non-notarized installer and binaries were being
|
||||
<a href="https://golang.org/issue/34986">rejected by Gatekeeper</a>.
|
||||
Only macOS users who hit this issue need to update.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.11">go1.11 (released 2018/08/24)</h2>
|
||||
|
||||
<p>
|
||||
|
@ -56,6 +56,14 @@ TODO
|
||||
Go 1.14 is the last Go release to support 32-bit binaries on
|
||||
macOS (the <code>darwin/386</code> port). They are no longer
|
||||
supported by macOS, starting with macOS 10.15 (Catalina).
|
||||
Go continues to support the 64-bit <code>darwin/amd64</code> port.
|
||||
</p>
|
||||
|
||||
<p><!-- golang.org/issue/34751 -->
|
||||
Go 1.14 will likely be the last Go release to support 32-bit
|
||||
binaries on iOS, iPadOS, watchOS, and tvOS
|
||||
(the <code>darwin/arm</code> port). Go continues to support the
|
||||
64-bit <code>darwin/arm64</code> port.
|
||||
</p>
|
||||
|
||||
<h3 id="nacl">Native Client (NaCl)</h3>
|
||||
@ -133,6 +141,10 @@ TODO
|
||||
trimming the ".mod" extension and appending ".sum".
|
||||
</p>
|
||||
|
||||
<p><!-- golang.org/issue/26092 -->
|
||||
The <code>go</code> command now supports Subversion repositories in module mode.
|
||||
</p>
|
||||
|
||||
<h2 id="runtime">Runtime</h2>
|
||||
|
||||
<p>
|
||||
|
@ -706,9 +706,14 @@ func (b *Writer) WriteString(s string) (int, error) {
|
||||
// supports the ReadFrom method, and b has no buffered data yet,
|
||||
// this calls the underlying ReadFrom without buffering.
|
||||
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
if b.err != nil {
|
||||
return 0, b.err
|
||||
}
|
||||
if b.Buffered() == 0 {
|
||||
if w, ok := b.wr.(io.ReaderFrom); ok {
|
||||
return w.ReadFrom(r)
|
||||
n, err = w.ReadFrom(r)
|
||||
b.err = err
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
var m int
|
||||
|
@ -1535,6 +1535,52 @@ func TestPartialReadEOF(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type writerWithReadFromError struct{}
|
||||
|
||||
func (w writerWithReadFromError) ReadFrom(r io.Reader) (int64, error) {
|
||||
return 0, errors.New("writerWithReadFromError error")
|
||||
}
|
||||
|
||||
func (w writerWithReadFromError) Write(b []byte) (n int, err error) {
|
||||
return 10, nil
|
||||
}
|
||||
|
||||
func TestWriterReadFromMustSetUnderlyingError(t *testing.T) {
|
||||
var wr = NewWriter(writerWithReadFromError{})
|
||||
if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil {
|
||||
t.Fatal("expected ReadFrom returns error, got nil")
|
||||
}
|
||||
if _, err := wr.Write([]byte("123")); err == nil {
|
||||
t.Fatal("expected Write returns error, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
type writeErrorOnlyWriter struct{}
|
||||
|
||||
func (w writeErrorOnlyWriter) Write(p []byte) (n int, err error) {
|
||||
return 0, errors.New("writeErrorOnlyWriter error")
|
||||
}
|
||||
|
||||
// Ensure that previous Write errors are immediately returned
|
||||
// on any ReadFrom. See golang.org/issue/35194.
|
||||
func TestWriterReadFromMustReturnUnderlyingError(t *testing.T) {
|
||||
var wr = NewWriter(writeErrorOnlyWriter{})
|
||||
s := "test1"
|
||||
wantBuffered := len(s)
|
||||
if _, err := wr.WriteString(s); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if err := wr.Flush(); err == nil {
|
||||
t.Error("expected flush error, got nil")
|
||||
}
|
||||
if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil {
|
||||
t.Fatal("expected error, got nil")
|
||||
}
|
||||
if buffered := wr.Buffered(); buffered != wantBuffered {
|
||||
t.Fatalf("Buffered = %v; want %v", buffered, wantBuffered)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReaderCopyOptimal(b *testing.B) {
|
||||
// Optimal case is where the underlying reader implements io.WriterTo
|
||||
srcBuf := bytes.NewBuffer(make([]byte, 8192))
|
||||
|
13
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
13
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
@ -130,27 +130,27 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVW FCR0, R1
|
||||
MOVW FCR31, R1 // 4441f800
|
||||
|
||||
// LMOVW freg ',' fpscr
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVW R1, FCR0
|
||||
MOVW R1, FCR31 // 44c1f800
|
||||
|
||||
// LMOVW rreg ',' mreg
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVW R1, M1
|
||||
MOVV R1, M1
|
||||
MOVW R1, M1 // 40810800
|
||||
MOVV R1, M1 // 40a10800
|
||||
|
||||
// LMOVW mreg ',' rreg
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVW M1, R1
|
||||
MOVV M1, R1
|
||||
MOVW M1, R1 // 40010800
|
||||
MOVV M1, R1 // 40210800
|
||||
|
||||
|
||||
//
|
||||
@ -406,6 +406,7 @@ label4:
|
||||
|
||||
NEGW R1, R2 // 00011023
|
||||
NEGV R1, R2 // 0001102f
|
||||
RET
|
||||
|
||||
// END
|
||||
//
|
||||
|
@ -171,37 +171,37 @@ var knownFormats = map[string]string{
|
||||
"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
|
||||
"map[*cmd/compile/internal/gc.Node][]*cmd/compile/internal/gc.Node %v": "",
|
||||
"map[cmd/compile/internal/ssa.ID]uint32 %v": "",
|
||||
"map[int64]uint32 %v": "",
|
||||
"math/big.Accuracy %s": "",
|
||||
"reflect.Type %s": "",
|
||||
"rune %#U": "",
|
||||
"rune %c": "",
|
||||
"rune %q": "",
|
||||
"string %-*s": "",
|
||||
"string %-16s": "",
|
||||
"string %-6s": "",
|
||||
"string %q": "",
|
||||
"string %s": "",
|
||||
"string %v": "",
|
||||
"time.Duration %d": "",
|
||||
"time.Duration %v": "",
|
||||
"uint %04x": "",
|
||||
"uint %5d": "",
|
||||
"uint %d": "",
|
||||
"uint %x": "",
|
||||
"uint16 %d": "",
|
||||
"uint16 %x": "",
|
||||
"uint32 %#U": "",
|
||||
"uint32 %#x": "",
|
||||
"uint32 %d": "",
|
||||
"uint32 %v": "",
|
||||
"uint32 %x": "",
|
||||
"uint64 %08x": "",
|
||||
"uint64 %b": "",
|
||||
"uint64 %d": "",
|
||||
"uint64 %x": "",
|
||||
"uint8 %d": "",
|
||||
"uint8 %v": "",
|
||||
"uint8 %x": "",
|
||||
"uintptr %d": "",
|
||||
"map[int64]uint32 %v": "",
|
||||
"math/big.Accuracy %s": "",
|
||||
"reflect.Type %s": "",
|
||||
"rune %#U": "",
|
||||
"rune %c": "",
|
||||
"rune %q": "",
|
||||
"string %-*s": "",
|
||||
"string %-16s": "",
|
||||
"string %-6s": "",
|
||||
"string %q": "",
|
||||
"string %s": "",
|
||||
"string %v": "",
|
||||
"time.Duration %d": "",
|
||||
"time.Duration %v": "",
|
||||
"uint %04x": "",
|
||||
"uint %5d": "",
|
||||
"uint %d": "",
|
||||
"uint %x": "",
|
||||
"uint16 %d": "",
|
||||
"uint16 %x": "",
|
||||
"uint32 %#U": "",
|
||||
"uint32 %#x": "",
|
||||
"uint32 %d": "",
|
||||
"uint32 %v": "",
|
||||
"uint32 %x": "",
|
||||
"uint64 %08x": "",
|
||||
"uint64 %b": "",
|
||||
"uint64 %d": "",
|
||||
"uint64 %x": "",
|
||||
"uint8 %d": "",
|
||||
"uint8 %v": "",
|
||||
"uint8 %x": "",
|
||||
"uintptr %d": "",
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ func Init(arch *gc.Arch) {
|
||||
arch.MAXWIDTH = 1 << 50
|
||||
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
|
@ -121,26 +121,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Pr
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
// Note: this code must not clobber any registers.
|
||||
op := x86.AMOVQ
|
||||
if gc.Widthptr == 4 {
|
||||
op = x86.AMOVL
|
||||
}
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
for i := int64(0); i < size; i += int64(gc.Widthptr) {
|
||||
p := pp.Prog(op)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = 0
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_AUTO
|
||||
p.To.Reg = x86.REG_SP
|
||||
p.To.Offset = n.Xoffset + i
|
||||
p.To.Sym = sym
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
// This is a hardware nop (1-byte 0x90) instruction,
|
||||
// even though we describe it as an explicit XCHGL here.
|
||||
|
@ -1091,7 +1091,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
gc.AddAux(&p.From, v)
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = v.Reg0()
|
||||
case ssa.OpAMD64XCHGL, ssa.OpAMD64XCHGQ:
|
||||
case ssa.OpAMD64XCHGB, ssa.OpAMD64XCHGL, ssa.OpAMD64XCHGQ:
|
||||
r := v.Reg0()
|
||||
if r != v.Args[0].Reg() {
|
||||
v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
|
||||
|
@ -17,7 +17,6 @@ func Init(arch *gc.Arch) {
|
||||
arch.MAXWIDTH = (1 << 32) - 1
|
||||
arch.SoftFloat = objabi.GOARM == 5
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
|
@ -47,27 +47,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, r0 *uint32) *obj.Prog
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
// Note: this code must not clobber any registers.
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
p := pp.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = 0
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REGTMP
|
||||
for i := int64(0); i < size; i += 4 {
|
||||
p := pp.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = arm.REGTMP
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_AUTO
|
||||
p.To.Reg = arm.REGSP
|
||||
p.To.Offset = n.Xoffset + i
|
||||
p.To.Sym = sym
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
p := pp.Prog(arm.AAND)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
|
@ -17,7 +17,6 @@ func Init(arch *gc.Arch) {
|
||||
|
||||
arch.PadFrame = padframe
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
|
@ -63,22 +63,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
// Note: this code must not clobber any registers.
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
for i := int64(0); i < size; i += 8 {
|
||||
p := pp.Prog(arm64.AMOVD)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = arm64.REGZERO
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_AUTO
|
||||
p.To.Reg = arm64.REGSP
|
||||
p.To.Offset = n.Xoffset + i
|
||||
p.To.Sym = sym
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
p := pp.Prog(arm64.AHINT)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
|
@ -452,6 +452,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
ssa.OpARM64MOVDstore,
|
||||
ssa.OpARM64FMOVSstore,
|
||||
ssa.OpARM64FMOVDstore,
|
||||
ssa.OpARM64STLRB,
|
||||
ssa.OpARM64STLR,
|
||||
ssa.OpARM64STLRW:
|
||||
p := s.Prog(v.Op.Asm())
|
||||
|
@ -270,11 +270,6 @@ type Arch struct {
|
||||
// SSAGenBlock emits end-of-block Progs. SSAGenValue should be called
|
||||
// for all values in the block before SSAGenBlock.
|
||||
SSAGenBlock func(s *SSAGenState, b, next *ssa.Block)
|
||||
|
||||
// ZeroAuto emits code to zero the given auto stack variable.
|
||||
// ZeroAuto must not use any non-temporary registers.
|
||||
// ZeroAuto will only be called for variables which contain a pointer.
|
||||
ZeroAuto func(*Progs, *Node)
|
||||
}
|
||||
|
||||
var thearch Arch
|
||||
|
@ -179,11 +179,6 @@ func (a *Mpflt) Neg() {
|
||||
}
|
||||
|
||||
func (a *Mpflt) SetString(as string) {
|
||||
// TODO(gri) why is this needed?
|
||||
for len(as) > 0 && (as[0] == ' ' || as[0] == '\t') {
|
||||
as = as[1:]
|
||||
}
|
||||
|
||||
f, _, err := a.Val.Parse(as, 0)
|
||||
if err != nil {
|
||||
yyerror("malformed constant: %s (%v)", as, err)
|
||||
|
@ -3337,7 +3337,7 @@ func init() {
|
||||
s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
|
||||
return s.newValue1(ssa.OpSelect0, types.Types[TUINT8], v)
|
||||
},
|
||||
sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS64, sys.PPC64)
|
||||
sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
|
||||
addF("runtime/internal/atomic", "Load64",
|
||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||
v := s.newValue2(ssa.OpAtomicLoad64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], s.mem())
|
||||
@ -3366,6 +3366,12 @@ func init() {
|
||||
return nil
|
||||
},
|
||||
sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
|
||||
addF("runtime/internal/atomic", "Store8",
|
||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||
s.vars[&memVar] = s.newValue3(ssa.OpAtomicStore8, types.TypeMem, args[0], args[1], s.mem())
|
||||
return nil
|
||||
},
|
||||
sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
|
||||
addF("runtime/internal/atomic", "Store64",
|
||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||
s.vars[&memVar] = s.newValue3(ssa.OpAtomicStore64, types.TypeMem, args[0], args[1], s.mem())
|
||||
@ -4099,7 +4105,7 @@ func (s *state) openDeferRecord(n *Node) {
|
||||
// runtime panic code to use. But in the defer exit code, we will
|
||||
// call the function directly if it is a static function.
|
||||
closureVal := s.expr(fn)
|
||||
closure := s.openDeferSave(fn, fn.Type, closureVal)
|
||||
closure := s.openDeferSave(nil, fn.Type, closureVal)
|
||||
opendefer.closureNode = closure.Aux.(*Node)
|
||||
if !(fn.Op == ONAME && fn.Class() == PFUNC) {
|
||||
opendefer.closure = closure
|
||||
@ -4112,14 +4118,14 @@ func (s *state) openDeferRecord(n *Node) {
|
||||
// We must always store the function value in a stack slot for the
|
||||
// runtime panic code to use. But in the defer exit code, we will
|
||||
// call the method directly.
|
||||
closure := s.openDeferSave(fn, fn.Type, closureVal)
|
||||
closure := s.openDeferSave(nil, fn.Type, closureVal)
|
||||
opendefer.closureNode = closure.Aux.(*Node)
|
||||
} else {
|
||||
if fn.Op != ODOTINTER {
|
||||
Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op)
|
||||
}
|
||||
closure, rcvr := s.getClosureAndRcvr(fn)
|
||||
opendefer.closure = s.openDeferSave(fn, closure.Type, closure)
|
||||
opendefer.closure = s.openDeferSave(nil, closure.Type, closure)
|
||||
// Important to get the receiver type correct, so it is recognized
|
||||
// as a pointer for GC purposes.
|
||||
opendefer.rcvr = s.openDeferSave(nil, fn.Type.Recv().Type, rcvr)
|
||||
@ -4127,7 +4133,12 @@ func (s *state) openDeferRecord(n *Node) {
|
||||
opendefer.rcvrNode = opendefer.rcvr.Aux.(*Node)
|
||||
}
|
||||
for _, argn := range n.Rlist.Slice() {
|
||||
v := s.openDeferSave(argn, argn.Type, s.expr(argn))
|
||||
var v *ssa.Value
|
||||
if canSSAType(argn.Type) {
|
||||
v = s.openDeferSave(nil, argn.Type, s.expr(argn))
|
||||
} else {
|
||||
v = s.openDeferSave(argn, argn.Type, nil)
|
||||
}
|
||||
args = append(args, v)
|
||||
argNodes = append(argNodes, v.Aux.(*Node))
|
||||
}
|
||||
@ -4144,13 +4155,22 @@ func (s *state) openDeferRecord(n *Node) {
|
||||
s.store(types.Types[TUINT8], s.deferBitsAddr, newDeferBits)
|
||||
}
|
||||
|
||||
// openDeferSave generates SSA nodes to store a value val (with type t) for an
|
||||
// open-coded defer on the stack at an explicit autotmp location, so it can be
|
||||
// reloaded and used for the appropriate call on exit. n is the associated node,
|
||||
// which is only needed if the associated type is non-SSAable. It returns an SSA
|
||||
// value representing a pointer to the stack location.
|
||||
// openDeferSave generates SSA nodes to store a value (with type t) for an
|
||||
// open-coded defer at an explicit autotmp location on the stack, so it can be
|
||||
// reloaded and used for the appropriate call on exit. If type t is SSAable, then
|
||||
// val must be non-nil (and n should be nil) and val is the value to be stored. If
|
||||
// type t is non-SSAable, then n must be non-nil (and val should be nil) and n is
|
||||
// evaluated (via s.addr() below) to get the value that is to be stored. The
|
||||
// function returns an SSA value representing a pointer to the autotmp location.
|
||||
func (s *state) openDeferSave(n *Node, t *types.Type, val *ssa.Value) *ssa.Value {
|
||||
argTemp := tempAt(val.Pos.WithNotStmt(), s.curfn, t)
|
||||
canSSA := canSSAType(t)
|
||||
var pos src.XPos
|
||||
if canSSA {
|
||||
pos = val.Pos
|
||||
} else {
|
||||
pos = n.Pos
|
||||
}
|
||||
argTemp := tempAt(pos.WithNotStmt(), s.curfn, t)
|
||||
argTemp.Name.SetOpenDeferSlot(true)
|
||||
var addrArgTemp *ssa.Value
|
||||
// Use OpVarLive to make sure stack slots for the args, etc. are not
|
||||
@ -4179,10 +4199,7 @@ func (s *state) openDeferSave(n *Node, t *types.Type, val *ssa.Value) *ssa.Value
|
||||
// uninitialized pointer value.
|
||||
argTemp.Name.SetNeedzero(true)
|
||||
}
|
||||
if !canSSAType(t) {
|
||||
if n.Op != ONAME {
|
||||
panic(fmt.Sprintf("Non-SSAable value should be a named location: %v", n))
|
||||
}
|
||||
if !canSSA {
|
||||
a := s.addr(n, false)
|
||||
s.move(t, addrArgTemp, a)
|
||||
return addrArgTemp
|
||||
|
@ -32,7 +32,7 @@ func typecheckTypeSwitch(n *Node) {
|
||||
// declaration itself. So if there are no cases, we won't
|
||||
// notice that it went unused.
|
||||
if v := n.Left.Left; v != nil && !v.isBlank() && n.List.Len() == 0 {
|
||||
yyerrorl(v.Pos, "%v declared and not used", v.Sym)
|
||||
yyerrorl(v.Pos, "%v declared but not used", v.Sym)
|
||||
}
|
||||
|
||||
var defCase, nilCase *Node
|
||||
|
@ -2782,7 +2782,7 @@ func typecheckcomplit(n *Node) (res *Node) {
|
||||
}
|
||||
elemType := n.Right.Right.Type
|
||||
|
||||
length := typecheckarraylit(elemType, -1, n.List.Slice())
|
||||
length := typecheckarraylit(elemType, -1, n.List.Slice(), "array literal")
|
||||
|
||||
n.Op = OARRAYLIT
|
||||
n.Type = types.NewArray(elemType, length)
|
||||
@ -2804,12 +2804,12 @@ func typecheckcomplit(n *Node) (res *Node) {
|
||||
n.Type = nil
|
||||
|
||||
case TARRAY:
|
||||
typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice())
|
||||
typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice(), "array literal")
|
||||
n.Op = OARRAYLIT
|
||||
n.Right = nil
|
||||
|
||||
case TSLICE:
|
||||
length := typecheckarraylit(t.Elem(), -1, n.List.Slice())
|
||||
length := typecheckarraylit(t.Elem(), -2, n.List.Slice(), "slice literal")
|
||||
n.Op = OSLICELIT
|
||||
n.Right = nodintconst(length)
|
||||
|
||||
@ -2960,7 +2960,8 @@ func typecheckcomplit(n *Node) (res *Node) {
|
||||
return n
|
||||
}
|
||||
|
||||
func typecheckarraylit(elemType *types.Type, bound int64, elts []*Node) int64 {
|
||||
// typecheckarraylit type-checks a sequence of slice/array literal elements.
|
||||
func typecheckarraylit(elemType *types.Type, bound int64, elts []*Node, ctx string) int64 {
|
||||
// If there are key/value pairs, create a map to keep seen
|
||||
// keys so we can check for duplicate indices.
|
||||
var indices map[int64]bool
|
||||
@ -2995,12 +2996,12 @@ func typecheckarraylit(elemType *types.Type, bound int64, elts []*Node) int64 {
|
||||
r := *vp
|
||||
r = pushtype(r, elemType)
|
||||
r = typecheck(r, ctxExpr)
|
||||
*vp = assignconv(r, elemType, "array or slice literal")
|
||||
*vp = assignconv(r, elemType, ctx)
|
||||
|
||||
if key >= 0 {
|
||||
if indices != nil {
|
||||
if indices[key] {
|
||||
yyerror("duplicate index in array literal: %d", key)
|
||||
yyerror("duplicate index in %s: %d", ctx, key)
|
||||
} else {
|
||||
indices[key] = true
|
||||
}
|
||||
|
@ -50,10 +50,10 @@ func walk(fn *Node) {
|
||||
if defn.Left.Name.Used() {
|
||||
continue
|
||||
}
|
||||
yyerrorl(defn.Left.Pos, "%v declared and not used", ln.Sym)
|
||||
yyerrorl(defn.Left.Pos, "%v declared but not used", ln.Sym)
|
||||
defn.Left.Name.SetUsed(true) // suppress repeats
|
||||
} else {
|
||||
yyerrorl(ln.Pos, "%v declared and not used", ln.Sym)
|
||||
yyerrorl(ln.Pos, "%v declared but not used", ln.Sym)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3965,8 +3965,12 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
|
||||
// Calling cheapexpr(n, init) below leads to a recursive call
|
||||
// to walkexpr, which leads us back here again. Use n.Opt to
|
||||
// prevent infinite loops.
|
||||
if n.Opt() == &walkCheckPtrArithmeticMarker {
|
||||
if opt := n.Opt(); opt == &walkCheckPtrArithmeticMarker {
|
||||
return n
|
||||
} else if opt != nil {
|
||||
// We use n.Opt() here because today it's not used for OCONVNOP. If that changes,
|
||||
// there's no guarantee that temporarily replacing it is safe, so just hard fail here.
|
||||
Fatalf("unexpected Opt: %v", opt)
|
||||
}
|
||||
n.SetOpt(&walkCheckPtrArithmeticMarker)
|
||||
defer n.SetOpt(nil)
|
||||
|
@ -20,7 +20,6 @@ func Init(arch *gc.Arch) {
|
||||
arch.MAXWIDTH = (1 << 31) - 1
|
||||
arch.SoftFloat = (objabi.GOMIPS == "softfloat")
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
|
||||
|
@ -43,22 +43,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
// Note: this code must not clobber any registers.
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
for i := int64(0); i < size; i += 4 {
|
||||
p := pp.Prog(mips.AMOVW)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = mips.REGZERO
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_AUTO
|
||||
p.To.Reg = mips.REGSP
|
||||
p.To.Offset = n.Xoffset + i
|
||||
p.To.Sym = sym
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
p := pp.Prog(mips.ANOR)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
|
@ -497,20 +497,36 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
|
||||
s.UseArgs(12) // space used in callee args area by assembly stubs
|
||||
case ssa.OpMIPSLoweredAtomicLoad:
|
||||
case ssa.OpMIPSLoweredAtomicLoad8,
|
||||
ssa.OpMIPSLoweredAtomicLoad32:
|
||||
s.Prog(mips.ASYNC)
|
||||
|
||||
p := s.Prog(mips.AMOVW)
|
||||
var op obj.As
|
||||
switch v.Op {
|
||||
case ssa.OpMIPSLoweredAtomicLoad8:
|
||||
op = mips.AMOVB
|
||||
case ssa.OpMIPSLoweredAtomicLoad32:
|
||||
op = mips.AMOVW
|
||||
}
|
||||
p := s.Prog(op)
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = v.Args[0].Reg()
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = v.Reg0()
|
||||
|
||||
s.Prog(mips.ASYNC)
|
||||
case ssa.OpMIPSLoweredAtomicStore:
|
||||
case ssa.OpMIPSLoweredAtomicStore8,
|
||||
ssa.OpMIPSLoweredAtomicStore32:
|
||||
s.Prog(mips.ASYNC)
|
||||
|
||||
p := s.Prog(mips.AMOVW)
|
||||
var op obj.As
|
||||
switch v.Op {
|
||||
case ssa.OpMIPSLoweredAtomicStore8:
|
||||
op = mips.AMOVB
|
||||
case ssa.OpMIPSLoweredAtomicStore32:
|
||||
op = mips.AMOVW
|
||||
}
|
||||
p := s.Prog(op)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = v.Args[1].Reg()
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
|
@ -20,7 +20,6 @@ func Init(arch *gc.Arch) {
|
||||
arch.MAXWIDTH = 1 << 50
|
||||
arch.SoftFloat = objabi.GOMIPS64 == "softfloat"
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
|
@ -47,22 +47,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
// Note: this code must not clobber any registers.
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
for i := int64(0); i < size; i += 8 {
|
||||
p := pp.Prog(mips.AMOVV)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = mips.REGZERO
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_AUTO
|
||||
p.To.Reg = mips.REGSP
|
||||
p.To.Offset = n.Xoffset + i
|
||||
p.To.Sym = sym
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
p := pp.Prog(mips.ANOR)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
|
@ -516,9 +516,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = v.Reg0()
|
||||
s.Prog(mips.ASYNC)
|
||||
case ssa.OpMIPS64LoweredAtomicStore32, ssa.OpMIPS64LoweredAtomicStore64:
|
||||
case ssa.OpMIPS64LoweredAtomicStore8, ssa.OpMIPS64LoweredAtomicStore32, ssa.OpMIPS64LoweredAtomicStore64:
|
||||
as := mips.AMOVV
|
||||
if v.Op == ssa.OpMIPS64LoweredAtomicStore32 {
|
||||
switch v.Op {
|
||||
case ssa.OpMIPS64LoweredAtomicStore8:
|
||||
as = mips.AMOVB
|
||||
case ssa.OpMIPS64LoweredAtomicStore32:
|
||||
as = mips.AMOVW
|
||||
}
|
||||
s.Prog(mips.ASYNC)
|
||||
|
@ -19,7 +19,6 @@ func Init(arch *gc.Arch) {
|
||||
arch.MAXWIDTH = 1 << 60
|
||||
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnopdefer
|
||||
|
||||
|
@ -42,22 +42,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
// Note: this code must not clobber any registers.
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
for i := int64(0); i < size; i += 8 {
|
||||
p := pp.Prog(ppc64.AMOVD)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = ppc64.REGZERO
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_AUTO
|
||||
p.To.Reg = ppc64.REGSP
|
||||
p.To.Offset = n.Xoffset + i
|
||||
p.To.Sym = sym
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
p := pp.Prog(ppc64.AOR)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
|
@ -335,12 +335,16 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
pisync.To.Type = obj.TYPE_NONE
|
||||
gc.Patch(p2, pisync)
|
||||
|
||||
case ssa.OpPPC64LoweredAtomicStore32,
|
||||
case ssa.OpPPC64LoweredAtomicStore8,
|
||||
ssa.OpPPC64LoweredAtomicStore32,
|
||||
ssa.OpPPC64LoweredAtomicStore64:
|
||||
// SYNC or LWSYNC
|
||||
// MOVD/MOVW arg1,(arg0)
|
||||
// MOVB/MOVW/MOVD arg1,(arg0)
|
||||
st := ppc64.AMOVD
|
||||
if v.Op == ssa.OpPPC64LoweredAtomicStore32 {
|
||||
switch v.Op {
|
||||
case ssa.OpPPC64LoweredAtomicStore8:
|
||||
st = ppc64.AMOVB
|
||||
case ssa.OpPPC64LoweredAtomicStore32:
|
||||
st = ppc64.AMOVW
|
||||
}
|
||||
arg0 := v.Args[0].Reg()
|
||||
|
@ -15,7 +15,6 @@ func Init(arch *gc.Arch) {
|
||||
arch.MAXWIDTH = 1 << 50
|
||||
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
|
@ -83,23 +83,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
// Note: this code must not clobber any registers or the
|
||||
// condition code.
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
for i := int64(0); i < size; i += int64(gc.Widthptr) {
|
||||
p := pp.Prog(s390x.AMOVD)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = 0
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_AUTO
|
||||
p.To.Reg = s390x.REGSP
|
||||
p.To.Offset = n.Xoffset + i
|
||||
p.To.Sym = sym
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
return pp.Prog(s390x.ANOPH)
|
||||
}
|
||||
|
@ -725,7 +725,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
gc.AddAux(&p.From, v)
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = v.Reg0()
|
||||
case ssa.OpS390XMOVWatomicstore, ssa.OpS390XMOVDatomicstore:
|
||||
case ssa.OpS390XMOVBatomicstore, ssa.OpS390XMOVWatomicstore, ssa.OpS390XMOVDatomicstore:
|
||||
p := s.Prog(v.Op.Asm())
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = v.Args[1].Reg()
|
||||
|
@ -220,7 +220,7 @@ func elimIf(f *Func, loadAddr *sparseSet, dom *Block) bool {
|
||||
// that has the same line number as the Pos for b itself, and
|
||||
// puts a statement mark on it, and returns whether it succeeded
|
||||
// in this operation.
|
||||
setBlockPos := func (b *Block) bool {
|
||||
setBlockPos := func(b *Block) bool {
|
||||
pos := b.Pos
|
||||
for _, v := range b.Values {
|
||||
if pos.SameFileAndLine(v.Pos) && !isPoorStatementOp(v.Op) {
|
||||
|
@ -4,13 +4,11 @@
|
||||
|
||||
// Lowering arithmetic
|
||||
(Add(64|32|16|8) x y) -> (ADD(Q|L|L|L) x y)
|
||||
(AddPtr x y) && config.PtrSize == 8 -> (ADDQ x y)
|
||||
(AddPtr x y) && config.PtrSize == 4 -> (ADDL x y)
|
||||
(AddPtr x y) -> (ADDQ x y)
|
||||
(Add(32|64)F x y) -> (ADDS(S|D) x y)
|
||||
|
||||
(Sub(64|32|16|8) x y) -> (SUB(Q|L|L|L) x y)
|
||||
(SubPtr x y) && config.PtrSize == 8 -> (SUBQ x y)
|
||||
(SubPtr x y) && config.PtrSize == 4 -> (SUBL x y)
|
||||
(SubPtr x y) -> (SUBQ x y)
|
||||
(Sub(32|64)F x y) -> (SUBS(S|D) x y)
|
||||
|
||||
(Mul(64|32|16|8) x y) -> (MUL(Q|L|L|L) x y)
|
||||
@ -76,9 +74,8 @@
|
||||
(Not x) -> (XORLconst [1] x)
|
||||
|
||||
// Lowering pointer arithmetic
|
||||
(OffPtr [off] ptr) && config.PtrSize == 8 && is32Bit(off) -> (ADDQconst [off] ptr)
|
||||
(OffPtr [off] ptr) && config.PtrSize == 8 -> (ADDQ (MOVQconst [off]) ptr)
|
||||
(OffPtr [off] ptr) && config.PtrSize == 4 -> (ADDLconst [off] ptr)
|
||||
(OffPtr [off] ptr) && is32Bit(off) -> (ADDQconst [off] ptr)
|
||||
(OffPtr [off] ptr) -> (ADDQ (MOVQconst [off]) ptr)
|
||||
|
||||
// Lowering other arithmetic
|
||||
(Ctz64 <t> x) -> (CMOVQEQ (Select0 <t> (BSFQ x)) (MOVQconst <t> [64]) (Select1 <types.TypeFlags> (BSFQ x)))
|
||||
@ -217,18 +214,16 @@
|
||||
(Geq(32|64)F x y) -> (SETGEF (UCOMIS(S|D) x y))
|
||||
|
||||
(Eq(64|32|16|8|B) x y) -> (SETEQ (CMP(Q|L|W|B|B) x y))
|
||||
(EqPtr x y) && config.PtrSize == 8 -> (SETEQ (CMPQ x y))
|
||||
(EqPtr x y) && config.PtrSize == 4 -> (SETEQ (CMPL x y))
|
||||
(EqPtr x y) -> (SETEQ (CMPQ x y))
|
||||
(Eq(32|64)F x y) -> (SETEQF (UCOMIS(S|D) x y))
|
||||
|
||||
(Neq(64|32|16|8|B) x y) -> (SETNE (CMP(Q|L|W|B|B) x y))
|
||||
(NeqPtr x y) && config.PtrSize == 8 -> (SETNE (CMPQ x y))
|
||||
(NeqPtr x y) && config.PtrSize == 4 -> (SETNE (CMPL x y))
|
||||
(NeqPtr x y) -> (SETNE (CMPQ x y))
|
||||
(Neq(32|64)F x y) -> (SETNEF (UCOMIS(S|D) x y))
|
||||
|
||||
// Lowering loads
|
||||
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t) && config.PtrSize == 8) -> (MOVQload ptr mem)
|
||||
(Load <t> ptr mem) && (is32BitInt(t) || isPtr(t) && config.PtrSize == 4) -> (MOVLload ptr mem)
|
||||
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) -> (MOVQload ptr mem)
|
||||
(Load <t> ptr mem) && is32BitInt(t) -> (MOVLload ptr mem)
|
||||
(Load <t> ptr mem) && is16BitInt(t) -> (MOVWload ptr mem)
|
||||
(Load <t> ptr mem) && (t.IsBoolean() || is8BitInt(t)) -> (MOVBload ptr mem)
|
||||
(Load <t> ptr mem) && is32BitFloat(t) -> (MOVSSload ptr mem)
|
||||
@ -420,8 +415,7 @@
|
||||
(Const64 [val]) -> (MOVQconst [val])
|
||||
(Const32F [val]) -> (MOVSSconst [val])
|
||||
(Const64F [val]) -> (MOVSDconst [val])
|
||||
(ConstNil) && config.PtrSize == 8 -> (MOVQconst [0])
|
||||
(ConstNil) && config.PtrSize == 4 -> (MOVLconst [0])
|
||||
(ConstNil) -> (MOVQconst [0])
|
||||
(ConstBool [b]) -> (MOVLconst [b])
|
||||
|
||||
// Lowering calls
|
||||
@ -476,21 +470,16 @@
|
||||
(CMOV(QEQ|QGT|QGE|QCS|QLS|LEQ|LGT|LGE|LCS|LLS|WEQ|WGT|WGE|WCS|WLS) y _ (FlagLT_UGT)) -> y
|
||||
|
||||
// Miscellaneous
|
||||
(IsNonNil p) && config.PtrSize == 8 -> (SETNE (TESTQ p p))
|
||||
(IsNonNil p) && config.PtrSize == 4 -> (SETNE (TESTL p p))
|
||||
(IsInBounds idx len) && config.PtrSize == 8 -> (SETB (CMPQ idx len))
|
||||
(IsInBounds idx len) && config.PtrSize == 4 -> (SETB (CMPL idx len))
|
||||
(IsSliceInBounds idx len) && config.PtrSize == 8 -> (SETBE (CMPQ idx len))
|
||||
(IsSliceInBounds idx len) && config.PtrSize == 4 -> (SETBE (CMPL idx len))
|
||||
(IsNonNil p) -> (SETNE (TESTQ p p))
|
||||
(IsInBounds idx len) -> (SETB (CMPQ idx len))
|
||||
(IsSliceInBounds idx len) -> (SETBE (CMPQ idx len))
|
||||
(NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
|
||||
(GetG mem) -> (LoweredGetG mem)
|
||||
(GetClosurePtr) -> (LoweredGetClosurePtr)
|
||||
(GetCallerPC) -> (LoweredGetCallerPC)
|
||||
(GetCallerSP) -> (LoweredGetCallerSP)
|
||||
(Addr {sym} base) && config.PtrSize == 8 -> (LEAQ {sym} base)
|
||||
(Addr {sym} base) && config.PtrSize == 4 -> (LEAL {sym} base)
|
||||
(LocalAddr {sym} base _) && config.PtrSize == 8 -> (LEAQ {sym} base)
|
||||
(LocalAddr {sym} base _) && config.PtrSize == 4 -> (LEAL {sym} base)
|
||||
(Addr {sym} base) -> (LEAQ {sym} base)
|
||||
(LocalAddr {sym} base _) -> (LEAQ {sym} base)
|
||||
|
||||
(MOVBstore [off] {sym} ptr y:(SETL x) mem) && y.Uses == 1 -> (SETLstore [off] {sym} ptr x mem)
|
||||
(MOVBstore [off] {sym} ptr y:(SETLE x) mem) && y.Uses == 1 -> (SETLEstore [off] {sym} ptr x mem)
|
||||
@ -528,15 +517,14 @@
|
||||
(AtomicLoad8 ptr mem) -> (MOVBatomicload ptr mem)
|
||||
(AtomicLoad32 ptr mem) -> (MOVLatomicload ptr mem)
|
||||
(AtomicLoad64 ptr mem) -> (MOVQatomicload ptr mem)
|
||||
(AtomicLoadPtr ptr mem) && config.PtrSize == 8 -> (MOVQatomicload ptr mem)
|
||||
(AtomicLoadPtr ptr mem) && config.PtrSize == 4 -> (MOVLatomicload ptr mem)
|
||||
(AtomicLoadPtr ptr mem) -> (MOVQatomicload ptr mem)
|
||||
|
||||
// Atomic stores. We use XCHG to prevent the hardware reordering a subsequent load.
|
||||
// TODO: most runtime uses of atomic stores don't need that property. Use normal stores for those?
|
||||
(AtomicStore8 ptr val mem) -> (Select1 (XCHGB <types.NewTuple(typ.UInt8,types.TypeMem)> val ptr mem))
|
||||
(AtomicStore32 ptr val mem) -> (Select1 (XCHGL <types.NewTuple(typ.UInt32,types.TypeMem)> val ptr mem))
|
||||
(AtomicStore64 ptr val mem) -> (Select1 (XCHGQ <types.NewTuple(typ.UInt64,types.TypeMem)> val ptr mem))
|
||||
(AtomicStorePtrNoWB ptr val mem) && config.PtrSize == 8 -> (Select1 (XCHGQ <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
|
||||
(AtomicStorePtrNoWB ptr val mem) && config.PtrSize == 4 -> (Select1 (XCHGL <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
|
||||
(AtomicStorePtrNoWB ptr val mem) -> (Select1 (XCHGQ <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
|
||||
|
||||
// Atomic exchanges.
|
||||
(AtomicExchange32 ptr val mem) -> (XCHGL val ptr mem)
|
||||
|
@ -746,6 +746,7 @@ func init() {
|
||||
// store arg0 to arg1+auxint+aux, arg2=mem.
|
||||
// These ops return a tuple of <old contents of *(arg1+auxint+aux), memory>.
|
||||
// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
|
||||
{name: "XCHGB", argLength: 3, reg: gpstorexchg, asm: "XCHGB", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
|
||||
{name: "XCHGL", argLength: 3, reg: gpstorexchg, asm: "XCHGL", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
|
||||
{name: "XCHGQ", argLength: 3, reg: gpstorexchg, asm: "XCHGQ", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
|
||||
|
||||
|
@ -589,6 +589,7 @@
|
||||
(AtomicLoad64 ptr mem) -> (LDAR ptr mem)
|
||||
(AtomicLoadPtr ptr mem) -> (LDAR ptr mem)
|
||||
|
||||
(AtomicStore8 ptr val mem) -> (STLRB ptr val mem)
|
||||
(AtomicStore32 ptr val mem) -> (STLRW ptr val mem)
|
||||
(AtomicStore64 ptr val mem) -> (STLR ptr val mem)
|
||||
(AtomicStorePtrNoWB ptr val mem) -> (STLR ptr val mem)
|
||||
|
@ -611,6 +611,7 @@ func init() {
|
||||
|
||||
// atomic stores.
|
||||
// store arg1 to arg0. arg2=mem. returns memory. auxint must be zero.
|
||||
{name: "STLRB", argLength: 3, reg: gpstore, asm: "STLRB", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "STLR", argLength: 3, reg: gpstore, asm: "STLR", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "STLRW", argLength: 3, reg: gpstore, asm: "STLRW", faultOnNilArg0: true, hasSideEffects: true},
|
||||
|
||||
|
@ -351,11 +351,11 @@
|
||||
(InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem)
|
||||
|
||||
// atomic intrinsics
|
||||
(AtomicLoad32 ptr mem) -> (LoweredAtomicLoad ptr mem)
|
||||
(AtomicLoadPtr ptr mem) -> (LoweredAtomicLoad ptr mem)
|
||||
(AtomicLoad(8|32) ptr mem) -> (LoweredAtomicLoad(8|32) ptr mem)
|
||||
(AtomicLoadPtr ptr mem) -> (LoweredAtomicLoad32 ptr mem)
|
||||
|
||||
(AtomicStore32 ptr val mem) -> (LoweredAtomicStore ptr val mem)
|
||||
(AtomicStorePtrNoWB ptr val mem) -> (LoweredAtomicStore ptr val mem)
|
||||
(AtomicStore(8|32) ptr val mem) -> (LoweredAtomicStore(8|32) ptr val mem)
|
||||
(AtomicStorePtrNoWB ptr val mem) -> (LoweredAtomicStore32 ptr val mem)
|
||||
|
||||
(AtomicExchange32 ptr val mem) -> (LoweredAtomicExchange ptr val mem)
|
||||
(AtomicAdd32 ptr val mem) -> (LoweredAtomicAdd ptr val mem)
|
||||
@ -708,6 +708,6 @@
|
||||
(CMOVZ a (MOVWconst [0]) c) -> (CMOVZzero a c)
|
||||
|
||||
// atomic
|
||||
(LoweredAtomicStore ptr (MOVWconst [0]) mem) -> (LoweredAtomicStorezero ptr mem)
|
||||
(LoweredAtomicStore32 ptr (MOVWconst [0]) mem) -> (LoweredAtomicStorezero ptr mem)
|
||||
(LoweredAtomicAdd ptr (MOVWconst [c]) mem) && is16Bit(c) -> (LoweredAtomicAddconst [c] ptr mem)
|
||||
|
||||
|
@ -403,6 +403,7 @@
|
||||
(AtomicLoad64 ptr mem) -> (LoweredAtomicLoad64 ptr mem)
|
||||
(AtomicLoadPtr ptr mem) -> (LoweredAtomicLoad64 ptr mem)
|
||||
|
||||
(AtomicStore8 ptr val mem) -> (LoweredAtomicStore8 ptr val mem)
|
||||
(AtomicStore32 ptr val mem) -> (LoweredAtomicStore32 ptr val mem)
|
||||
(AtomicStore64 ptr val mem) -> (LoweredAtomicStore64 ptr val mem)
|
||||
(AtomicStorePtrNoWB ptr val mem) -> (LoweredAtomicStore64 ptr val mem)
|
||||
|
@ -367,6 +367,7 @@ func init() {
|
||||
|
||||
// atomic stores.
|
||||
// store arg1 to arg0. arg2=mem. returns memory.
|
||||
{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
|
||||
// store zero to arg0. arg1=mem. returns memory.
|
||||
|
@ -262,15 +262,17 @@ func init() {
|
||||
// load from arg0. arg1=mem.
|
||||
// returns <value,memory> so they can be properly ordered with other loads.
|
||||
// SYNC
|
||||
// MOVW (Rarg0), Rout
|
||||
// MOV(B|W) (Rarg0), Rout
|
||||
// SYNC
|
||||
{name: "LoweredAtomicLoad", argLength: 2, reg: gpload, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
|
||||
|
||||
// store arg1 to arg0. arg2=mem. returns memory.
|
||||
// SYNC
|
||||
// MOVW Rarg1, (Rarg0)
|
||||
// MOV(B|W) Rarg1, (Rarg0)
|
||||
// SYNC
|
||||
{name: "LoweredAtomicStore", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStorezero", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
|
||||
|
||||
// atomic exchange.
|
||||
|
@ -931,7 +931,7 @@
|
||||
(AtomicLoad(8|32|64|Ptr) ptr mem) -> (LoweredAtomicLoad(8|32|64|Ptr) [1] ptr mem)
|
||||
(AtomicLoadAcq32 ptr mem) -> (LoweredAtomicLoad32 [0] ptr mem)
|
||||
|
||||
(AtomicStore(32|64) ptr val mem) -> (LoweredAtomicStore(32|64) [1] ptr val mem)
|
||||
(AtomicStore(8|32|64) ptr val mem) -> (LoweredAtomicStore(8|32|64) [1] ptr val mem)
|
||||
(AtomicStoreRel32 ptr val mem) -> (LoweredAtomicStore32 [0] ptr val mem)
|
||||
//(AtomicStorePtrNoWB ptr val mem) -> (STLR ptr val mem)
|
||||
|
||||
|
@ -495,6 +495,7 @@ func init() {
|
||||
faultOnNilArg1: true,
|
||||
},
|
||||
|
||||
{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
|
||||
|
||||
|
@ -146,7 +146,7 @@
|
||||
// reordering. Other sequences of memory operations (load-load,
|
||||
// store-store and load-store) are already guaranteed not to be reordered.
|
||||
(AtomicLoad(8|32|Acq32|64|Ptr) ptr mem) -> (MOV(BZ|WZ|WZ|D|D)atomicload ptr mem)
|
||||
(AtomicStore(32|64|PtrNoWB) ptr val mem) -> (SYNC (MOV(W|D|D)atomicstore ptr val mem))
|
||||
(AtomicStore(8|32|64|PtrNoWB) ptr val mem) -> (SYNC (MOV(B|W|D|D)atomicstore ptr val mem))
|
||||
|
||||
// Store-release doesn't require store-load ordering.
|
||||
(AtomicStoreRel32 ptr val mem) -> (MOVWatomicstore ptr val mem)
|
||||
|
@ -495,6 +495,7 @@ func init() {
|
||||
|
||||
// Atomic stores. These are just normal stores.
|
||||
// store arg1 to arg0+auxint+aux. arg2=mem.
|
||||
{name: "MOVBatomicstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
|
||||
{name: "MOVWatomicstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
|
||||
{name: "MOVDatomicstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
|
||||
|
||||
|
@ -803,7 +803,7 @@
|
||||
|
||||
// Putting struct{*byte} and similar into direct interfaces.
|
||||
(IMake typ (StructMake1 val)) -> (IMake typ val)
|
||||
(StructSelect [0] x:(IData _)) -> x
|
||||
(StructSelect [0] (IData x)) -> (IData x)
|
||||
|
||||
// un-SSAable values use mem->mem copies
|
||||
(Store {t} dst (Load src mem) mem) && !fe.CanSSA(t.(*types.Type)) ->
|
||||
@ -823,9 +823,9 @@
|
||||
(Store _ (ArrayMake0) mem) -> mem
|
||||
(Store dst (ArrayMake1 e) mem) -> (Store {e.Type} dst e mem)
|
||||
|
||||
// Putting [1]{*byte} and similar into direct interfaces.
|
||||
// Putting [1]*byte and similar into direct interfaces.
|
||||
(IMake typ (ArrayMake1 val)) -> (IMake typ val)
|
||||
(ArraySelect [0] x:(IData _)) -> x
|
||||
(ArraySelect [0] (IData x)) -> (IData x)
|
||||
|
||||
// string ops
|
||||
// Decomposing StringMake and lowering of StringPtr and StringLen
|
||||
|
@ -316,8 +316,7 @@ var genericOps = []opData{
|
||||
// See section 7.2 in ieee754.
|
||||
{name: "Fma", argLength: 3}, // compute (a*b)+c without intermediate rounding
|
||||
|
||||
// Data movement, max argument length for Phi is indefinite so just pick
|
||||
// a really large number
|
||||
// Data movement. Max argument length for Phi is indefinite.
|
||||
{name: "Phi", argLength: -1, zeroWidth: true}, // select an argument based on which predecessor block we came from
|
||||
{name: "Copy", argLength: 1}, // output = arg0
|
||||
// Convert converts between pointers and integers.
|
||||
@ -546,6 +545,7 @@ var genericOps = []opData{
|
||||
{name: "AtomicLoad64", argLength: 2, typ: "(UInt64,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory.
|
||||
{name: "AtomicLoadPtr", argLength: 2, typ: "(BytePtr,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory.
|
||||
{name: "AtomicLoadAcq32", argLength: 2, typ: "(UInt32,Mem)"}, // Load from arg0. arg1=memory. Lock acquisition, returns loaded value and new memory.
|
||||
{name: "AtomicStore8", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicStore32", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicStore64", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicStorePtrNoWB", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
|
@ -877,6 +877,7 @@ const (
|
||||
OpAMD64MOVBatomicload
|
||||
OpAMD64MOVLatomicload
|
||||
OpAMD64MOVQatomicload
|
||||
OpAMD64XCHGB
|
||||
OpAMD64XCHGL
|
||||
OpAMD64XCHGQ
|
||||
OpAMD64XADDLlock
|
||||
@ -1434,6 +1435,7 @@ const (
|
||||
OpARM64LDAR
|
||||
OpARM64LDARB
|
||||
OpARM64LDARW
|
||||
OpARM64STLRB
|
||||
OpARM64STLR
|
||||
OpARM64STLRW
|
||||
OpARM64LoweredAtomicExchange64
|
||||
@ -1535,8 +1537,10 @@ const (
|
||||
OpMIPSCALLstatic
|
||||
OpMIPSCALLclosure
|
||||
OpMIPSCALLinter
|
||||
OpMIPSLoweredAtomicLoad
|
||||
OpMIPSLoweredAtomicStore
|
||||
OpMIPSLoweredAtomicLoad8
|
||||
OpMIPSLoweredAtomicLoad32
|
||||
OpMIPSLoweredAtomicStore8
|
||||
OpMIPSLoweredAtomicStore32
|
||||
OpMIPSLoweredAtomicStorezero
|
||||
OpMIPSLoweredAtomicExchange
|
||||
OpMIPSLoweredAtomicAdd
|
||||
@ -1655,6 +1659,7 @@ const (
|
||||
OpMIPS64LoweredAtomicLoad8
|
||||
OpMIPS64LoweredAtomicLoad32
|
||||
OpMIPS64LoweredAtomicLoad64
|
||||
OpMIPS64LoweredAtomicStore8
|
||||
OpMIPS64LoweredAtomicStore32
|
||||
OpMIPS64LoweredAtomicStore64
|
||||
OpMIPS64LoweredAtomicStorezero32
|
||||
@ -1848,6 +1853,7 @@ const (
|
||||
OpPPC64CALLinter
|
||||
OpPPC64LoweredZero
|
||||
OpPPC64LoweredMove
|
||||
OpPPC64LoweredAtomicStore8
|
||||
OpPPC64LoweredAtomicStore32
|
||||
OpPPC64LoweredAtomicStore64
|
||||
OpPPC64LoweredAtomicLoad8
|
||||
@ -2068,6 +2074,7 @@ const (
|
||||
OpS390XMOVBZatomicload
|
||||
OpS390XMOVWZatomicload
|
||||
OpS390XMOVDatomicload
|
||||
OpS390XMOVBatomicstore
|
||||
OpS390XMOVWatomicstore
|
||||
OpS390XMOVDatomicstore
|
||||
OpS390XLAA
|
||||
@ -2553,6 +2560,7 @@ const (
|
||||
OpAtomicLoad64
|
||||
OpAtomicLoadPtr
|
||||
OpAtomicLoadAcq32
|
||||
OpAtomicStore8
|
||||
OpAtomicStore32
|
||||
OpAtomicStore64
|
||||
OpAtomicStorePtrNoWB
|
||||
@ -11406,6 +11414,25 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "XCHGB",
|
||||
auxType: auxSymOff,
|
||||
argLen: 3,
|
||||
resultInArg0: true,
|
||||
faultOnNilArg1: true,
|
||||
hasSideEffects: true,
|
||||
symEffect: SymRdWr,
|
||||
asm: x86.AXCHGB,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
|
||||
{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "XCHGL",
|
||||
auxType: auxSymOff,
|
||||
@ -18876,6 +18903,19 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "STLRB",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: arm64.ASTLRB,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||
{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "STLR",
|
||||
argLen: 3,
|
||||
@ -20278,7 +20318,7 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredAtomicLoad",
|
||||
name: "LoweredAtomicLoad8",
|
||||
argLen: 2,
|
||||
faultOnNilArg0: true,
|
||||
reg: regInfo{
|
||||
@ -20291,7 +20331,32 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredAtomicStore",
|
||||
name: "LoweredAtomicLoad32",
|
||||
argLen: 2,
|
||||
faultOnNilArg0: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 140738025226238}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 SP g R31 SB
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 335544318}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredAtomicStore8",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
|
||||
{0, 140738025226238}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 SP g R31 SB
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredAtomicStore32",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
@ -21882,6 +21947,18 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredAtomicStore8",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
|
||||
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredAtomicStore32",
|
||||
argLen: 3,
|
||||
@ -24489,6 +24566,19 @@ var opcodeTable = [...]opInfo{
|
||||
clobbers: 16408, // R3 R4 R14
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredAtomicStore8",
|
||||
auxType: auxInt64,
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
|
||||
{1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredAtomicStore32",
|
||||
auxType: auxInt64,
|
||||
@ -27632,6 +27722,22 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MOVBatomicstore",
|
||||
auxType: auxSymOff,
|
||||
argLen: 3,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
symEffect: SymWrite,
|
||||
asm: s390x.AMOVB,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4295023614}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 SP SB
|
||||
{1, 56319}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 SP
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MOVWatomicstore",
|
||||
auxType: auxSymOff,
|
||||
@ -31347,6 +31453,12 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 2,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicStore8",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicStore32",
|
||||
argLen: 3,
|
||||
|
@ -407,56 +407,82 @@ func (po *poset) newconst(n *Value) {
|
||||
po.upushconst(i, 0)
|
||||
}
|
||||
|
||||
// aliasnode records that n2 is an alias of n1
|
||||
func (po *poset) aliasnode(n1, n2 *Value) {
|
||||
// aliasnewnode records that a single node n2 (not in the poset yet) is an alias
|
||||
// of the master node n1.
|
||||
func (po *poset) aliasnewnode(n1, n2 *Value) {
|
||||
i1, i2 := po.values[n1.ID], po.values[n2.ID]
|
||||
if i1 == 0 || i2 != 0 {
|
||||
panic("aliasnewnode invalid arguments")
|
||||
}
|
||||
|
||||
po.values[n2.ID] = i1
|
||||
po.upushalias(n2.ID, 0)
|
||||
}
|
||||
|
||||
// aliasnodes records that all the nodes i2s are aliases of a single master node n1.
|
||||
// aliasnodes takes care of rearranging the DAG, changing references of parent/children
|
||||
// of nodes in i2s, so that they point to n1 instead.
|
||||
// Complexity is O(n) (with n being the total number of nodes in the poset, not just
|
||||
// the number of nodes being aliased).
|
||||
func (po *poset) aliasnodes(n1 *Value, i2s bitset) {
|
||||
i1 := po.values[n1.ID]
|
||||
if i1 == 0 {
|
||||
panic("aliasnode for non-existing node")
|
||||
}
|
||||
if i2s.Test(i1) {
|
||||
panic("aliasnode i2s contains n1 node")
|
||||
}
|
||||
|
||||
i2 := po.values[n2.ID]
|
||||
if i2 != 0 {
|
||||
// Rename all references to i2 into i1
|
||||
// (do not touch i1 itself, otherwise we can create useless self-loops)
|
||||
for idx, n := range po.nodes {
|
||||
if uint32(idx) != i1 {
|
||||
l, r := n.l, n.r
|
||||
if l.Target() == i2 {
|
||||
po.setchl(uint32(idx), newedge(i1, l.Strict()))
|
||||
po.upush(undoSetChl, uint32(idx), l)
|
||||
}
|
||||
if r.Target() == i2 {
|
||||
po.setchr(uint32(idx), newedge(i1, r.Strict()))
|
||||
po.upush(undoSetChr, uint32(idx), r)
|
||||
}
|
||||
}
|
||||
// Go through all the nodes to adjust parent/chidlren of nodes in i2s
|
||||
for idx, n := range po.nodes {
|
||||
// Do not touch i1 itself, otherwise we can create useless self-loops
|
||||
if uint32(idx) == i1 {
|
||||
continue
|
||||
}
|
||||
l, r := n.l, n.r
|
||||
|
||||
// Rename all references to i2s into i1
|
||||
if i2s.Test(l.Target()) {
|
||||
po.setchl(uint32(idx), newedge(i1, l.Strict()))
|
||||
po.upush(undoSetChl, uint32(idx), l)
|
||||
}
|
||||
if i2s.Test(r.Target()) {
|
||||
po.setchr(uint32(idx), newedge(i1, r.Strict()))
|
||||
po.upush(undoSetChr, uint32(idx), r)
|
||||
}
|
||||
|
||||
// Reassign all existing IDs that point to i2 to i1.
|
||||
// This includes n2.ID.
|
||||
for k, v := range po.values {
|
||||
if v == i2 {
|
||||
po.values[k] = i1
|
||||
po.upushalias(k, i2)
|
||||
// Connect all chidren of i2s to i1 (unless those children
|
||||
// are in i2s as well, in which case it would be useless)
|
||||
if i2s.Test(uint32(idx)) {
|
||||
if l != 0 && !i2s.Test(l.Target()) {
|
||||
po.addchild(i1, l.Target(), l.Strict())
|
||||
}
|
||||
if r != 0 && !i2s.Test(r.Target()) {
|
||||
po.addchild(i1, r.Target(), r.Strict())
|
||||
}
|
||||
po.setchl(uint32(idx), 0)
|
||||
po.setchr(uint32(idx), 0)
|
||||
po.upush(undoSetChl, uint32(idx), l)
|
||||
po.upush(undoSetChr, uint32(idx), r)
|
||||
}
|
||||
}
|
||||
|
||||
if n2.isGenericIntConst() {
|
||||
val := n2.AuxInt
|
||||
if po.flags&posetFlagUnsigned != 0 {
|
||||
val = int64(n2.AuxUnsigned())
|
||||
}
|
||||
if po.constants[val] != i2 {
|
||||
panic("aliasing constant which is not registered")
|
||||
}
|
||||
// Reassign all existing IDs that point to i2 to i1.
|
||||
// This includes n2.ID.
|
||||
for k, v := range po.values {
|
||||
if i2s.Test(v) {
|
||||
po.values[k] = i1
|
||||
po.upushalias(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// If one of the aliased nodes is a constant, then make sure
|
||||
// po.constants is updated to point to the master node.
|
||||
for val, idx := range po.constants {
|
||||
if i2s.Test(idx) {
|
||||
po.constants[val] = i1
|
||||
po.upushconst(i1, i2)
|
||||
po.upushconst(i1, idx)
|
||||
}
|
||||
|
||||
} else {
|
||||
// n2.ID wasn't seen before, so record it as alias to i1
|
||||
po.values[n2.ID] = i1
|
||||
po.upushalias(n2.ID, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -603,25 +629,56 @@ func (po *poset) mergeroot(r1, r2 uint32) uint32 {
|
||||
return r
|
||||
}
|
||||
|
||||
// collapsepath marks i1 and i2 as equal and collapses as equal all
|
||||
// nodes across all paths between i1 and i2. If a strict edge is
|
||||
// collapsepath marks n1 and n2 as equal and collapses as equal all
|
||||
// nodes across all paths between n1 and n2. If a strict edge is
|
||||
// found, the function does not modify the DAG and returns false.
|
||||
// Complexity is O(n).
|
||||
func (po *poset) collapsepath(n1, n2 *Value) bool {
|
||||
i1, i2 := po.values[n1.ID], po.values[n2.ID]
|
||||
if po.reaches(i1, i2, true) {
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: for now, only handle the simple case of i2 being child of i1
|
||||
l, r := po.children(i1)
|
||||
if l.Target() == i2 || r.Target() == i2 {
|
||||
po.aliasnode(n1, n2)
|
||||
po.addchild(i1, i2, false)
|
||||
return true
|
||||
}
|
||||
// Find all the paths from i1 to i2
|
||||
paths := po.findpaths(i1, i2)
|
||||
// Mark all nodes in all the paths as aliases of n1
|
||||
// (excluding n1 itself)
|
||||
paths.Clear(i1)
|
||||
po.aliasnodes(n1, paths)
|
||||
return true
|
||||
}
|
||||
|
||||
// findpaths is a recursive function that calculates all paths from cur to dst
|
||||
// and return them as a bitset (the index of a node is set in the bitset if
|
||||
// that node is on at least one path from cur to dst).
|
||||
// We do a DFS from cur (stopping going deep any time we reach dst, if ever),
|
||||
// and mark as part of the paths any node that has a children which is already
|
||||
// part of the path (or is dst itself).
|
||||
func (po *poset) findpaths(cur, dst uint32) bitset {
|
||||
seen := newBitset(int(po.lastidx + 1))
|
||||
path := newBitset(int(po.lastidx + 1))
|
||||
path.Set(dst)
|
||||
po.findpaths1(cur, dst, seen, path)
|
||||
return path
|
||||
}
|
||||
|
||||
func (po *poset) findpaths1(cur, dst uint32, seen bitset, path bitset) {
|
||||
if cur == dst {
|
||||
return
|
||||
}
|
||||
seen.Set(cur)
|
||||
l, r := po.chl(cur), po.chr(cur)
|
||||
if !seen.Test(l) {
|
||||
po.findpaths1(l, dst, seen, path)
|
||||
}
|
||||
if !seen.Test(r) {
|
||||
po.findpaths1(r, dst, seen, path)
|
||||
}
|
||||
if path.Test(l) || path.Test(r) {
|
||||
path.Set(cur)
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether it is recorded that i1!=i2
|
||||
func (po *poset) isnoneq(i1, i2 uint32) bool {
|
||||
if i1 == i2 {
|
||||
@ -1093,11 +1150,11 @@ func (po *poset) SetEqual(n1, n2 *Value) bool {
|
||||
i1 = po.newnode(n1)
|
||||
po.roots = append(po.roots, i1)
|
||||
po.upush(undoNewRoot, i1, 0)
|
||||
po.aliasnode(n1, n2)
|
||||
po.aliasnewnode(n1, n2)
|
||||
case f1 && !f2:
|
||||
po.aliasnode(n1, n2)
|
||||
po.aliasnewnode(n1, n2)
|
||||
case !f1 && f2:
|
||||
po.aliasnode(n2, n1)
|
||||
po.aliasnewnode(n2, n1)
|
||||
case f1 && f2:
|
||||
if i1 == i2 {
|
||||
// Already aliased, ignore
|
||||
@ -1127,11 +1184,9 @@ func (po *poset) SetEqual(n1, n2 *Value) bool {
|
||||
|
||||
// Set n2 as alias of n1. This will also update all the references
|
||||
// to n2 to become references to n1
|
||||
po.aliasnode(n1, n2)
|
||||
|
||||
// Connect i2 (now dummy) as child of i1. This allows to keep the correct
|
||||
// order with its children.
|
||||
po.addchild(i1, i2, false)
|
||||
i2s := newBitset(int(po.lastidx) + 1)
|
||||
i2s.Set(i2)
|
||||
po.aliasnodes(n1, i2s)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -438,7 +438,127 @@ func TestPosetStrict(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetEqual(t *testing.T) {
|
||||
func TestPosetCollapse(t *testing.T) {
|
||||
testPosetOps(t, false, []posetTestOp{
|
||||
{Checkpoint, 0, 0},
|
||||
// Create a complex graph of <= relations among nodes between 10 and 25.
|
||||
{SetOrderOrEqual, 10, 15},
|
||||
{SetOrderOrEqual, 15, 20},
|
||||
{SetOrderOrEqual, 20, vconst(20)},
|
||||
{SetOrderOrEqual, vconst(20), 25},
|
||||
{SetOrderOrEqual, 10, 12},
|
||||
{SetOrderOrEqual, 12, 16},
|
||||
{SetOrderOrEqual, 16, vconst(20)},
|
||||
{SetOrderOrEqual, 10, 17},
|
||||
{SetOrderOrEqual, 17, 25},
|
||||
{SetOrderOrEqual, 15, 18},
|
||||
{SetOrderOrEqual, 18, vconst(20)},
|
||||
{SetOrderOrEqual, 15, 19},
|
||||
{SetOrderOrEqual, 19, 25},
|
||||
|
||||
// These are other paths not part of the main collapsing path
|
||||
{SetOrderOrEqual, 10, 11},
|
||||
{SetOrderOrEqual, 11, 26},
|
||||
{SetOrderOrEqual, 13, 25},
|
||||
{SetOrderOrEqual, 100, 25},
|
||||
{SetOrderOrEqual, 101, 15},
|
||||
{SetOrderOrEqual, 102, 10},
|
||||
{SetOrderOrEqual, 25, 103},
|
||||
{SetOrderOrEqual, 20, 104},
|
||||
|
||||
{Checkpoint, 0, 0},
|
||||
// Collapse everything by setting 10 >= 25: this should make everything equal
|
||||
{SetOrderOrEqual, 25, 10},
|
||||
|
||||
// Check that all nodes are pairwise equal now
|
||||
{Equal, 10, 12},
|
||||
{Equal, 10, 15},
|
||||
{Equal, 10, 16},
|
||||
{Equal, 10, 17},
|
||||
{Equal, 10, 18},
|
||||
{Equal, 10, 19},
|
||||
{Equal, 10, vconst(20)},
|
||||
{Equal, 10, vconst2(20)},
|
||||
{Equal, 10, 25},
|
||||
|
||||
{Equal, 12, 15},
|
||||
{Equal, 12, 16},
|
||||
{Equal, 12, 17},
|
||||
{Equal, 12, 18},
|
||||
{Equal, 12, 19},
|
||||
{Equal, 12, vconst(20)},
|
||||
{Equal, 12, vconst2(20)},
|
||||
{Equal, 12, 25},
|
||||
|
||||
{Equal, 15, 16},
|
||||
{Equal, 15, 17},
|
||||
{Equal, 15, 18},
|
||||
{Equal, 15, 19},
|
||||
{Equal, 15, vconst(20)},
|
||||
{Equal, 15, vconst2(20)},
|
||||
{Equal, 15, 25},
|
||||
|
||||
{Equal, 16, 17},
|
||||
{Equal, 16, 18},
|
||||
{Equal, 16, 19},
|
||||
{Equal, 16, vconst(20)},
|
||||
{Equal, 16, vconst2(20)},
|
||||
{Equal, 16, 25},
|
||||
|
||||
{Equal, 17, 18},
|
||||
{Equal, 17, 19},
|
||||
{Equal, 17, vconst(20)},
|
||||
{Equal, 17, vconst2(20)},
|
||||
{Equal, 17, 25},
|
||||
|
||||
{Equal, 18, 19},
|
||||
{Equal, 18, vconst(20)},
|
||||
{Equal, 18, vconst2(20)},
|
||||
{Equal, 18, 25},
|
||||
|
||||
{Equal, 19, vconst(20)},
|
||||
{Equal, 19, vconst2(20)},
|
||||
{Equal, 19, 25},
|
||||
|
||||
{Equal, vconst(20), vconst2(20)},
|
||||
{Equal, vconst(20), 25},
|
||||
|
||||
{Equal, vconst2(20), 25},
|
||||
|
||||
// ... but not 11/26/100/101/102, which were on a different path
|
||||
{Equal_Fail, 10, 11},
|
||||
{Equal_Fail, 10, 26},
|
||||
{Equal_Fail, 10, 100},
|
||||
{Equal_Fail, 10, 101},
|
||||
{Equal_Fail, 10, 102},
|
||||
{OrderedOrEqual, 10, 26},
|
||||
{OrderedOrEqual, 25, 26},
|
||||
{OrderedOrEqual, 13, 25},
|
||||
{OrderedOrEqual, 13, 10},
|
||||
|
||||
{Undo, 0, 0},
|
||||
{OrderedOrEqual, 10, 25},
|
||||
{Equal_Fail, 10, 12},
|
||||
{Equal_Fail, 10, 15},
|
||||
{Equal_Fail, 10, 25},
|
||||
|
||||
{Undo, 0, 0},
|
||||
})
|
||||
|
||||
testPosetOps(t, false, []posetTestOp{
|
||||
{Checkpoint, 0, 0},
|
||||
{SetOrderOrEqual, 10, 15},
|
||||
{SetOrderOrEqual, 15, 20},
|
||||
{SetOrderOrEqual, 20, 25},
|
||||
{SetOrder, 10, 16},
|
||||
{SetOrderOrEqual, 16, 20},
|
||||
// Check that we cannot collapse here because of the strict relation 10<16
|
||||
{SetOrderOrEqual_Fail, 20, 10},
|
||||
{Undo, 0, 0},
|
||||
})
|
||||
}
|
||||
|
||||
func TestPosetSetEqual(t *testing.T) {
|
||||
testPosetOps(t, false, []posetTestOp{
|
||||
// 10<=20<=30<40, 20<=100<110
|
||||
{Checkpoint, 0, 0},
|
||||
|
@ -646,6 +646,8 @@ func rewriteValueAMD64(v *Value) bool {
|
||||
return rewriteValueAMD64_OpAtomicStore32_0(v)
|
||||
case OpAtomicStore64:
|
||||
return rewriteValueAMD64_OpAtomicStore64_0(v)
|
||||
case OpAtomicStore8:
|
||||
return rewriteValueAMD64_OpAtomicStore8_0(v)
|
||||
case OpAtomicStorePtrNoWB:
|
||||
return rewriteValueAMD64_OpAtomicStorePtrNoWB_0(v)
|
||||
case OpAvg64u:
|
||||
@ -50035,70 +50037,28 @@ func rewriteValueAMD64_OpAdd8_0(v *Value) bool {
|
||||
}
|
||||
}
|
||||
func rewriteValueAMD64_OpAddPtr_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (AddPtr x y)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (ADDQ x y)
|
||||
for {
|
||||
y := v.Args[1]
|
||||
x := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64ADDQ)
|
||||
v.AddArg(x)
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
// match: (AddPtr x y)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (ADDL x y)
|
||||
for {
|
||||
y := v.Args[1]
|
||||
x := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64ADDL)
|
||||
v.AddArg(x)
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpAddr_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (Addr {sym} base)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (LEAQ {sym} base)
|
||||
for {
|
||||
sym := v.Aux
|
||||
base := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64LEAQ)
|
||||
v.Aux = sym
|
||||
v.AddArg(base)
|
||||
return true
|
||||
}
|
||||
// match: (Addr {sym} base)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (LEAL {sym} base)
|
||||
for {
|
||||
sym := v.Aux
|
||||
base := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64LEAL)
|
||||
v.Aux = sym
|
||||
v.AddArg(base)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpAnd16_0(v *Value) bool {
|
||||
// match: (And16 x y)
|
||||
@ -50309,37 +50269,16 @@ func rewriteValueAMD64_OpAtomicLoad8_0(v *Value) bool {
|
||||
}
|
||||
}
|
||||
func rewriteValueAMD64_OpAtomicLoadPtr_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (AtomicLoadPtr ptr mem)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (MOVQatomicload ptr mem)
|
||||
for {
|
||||
mem := v.Args[1]
|
||||
ptr := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64MOVQatomicload)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (AtomicLoadPtr ptr mem)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (MOVLatomicload ptr mem)
|
||||
for {
|
||||
mem := v.Args[1]
|
||||
ptr := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64MOVLatomicload)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpAtomicOr8_0(v *Value) bool {
|
||||
// match: (AtomicOr8 ptr val mem)
|
||||
@ -50391,20 +50330,33 @@ func rewriteValueAMD64_OpAtomicStore64_0(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueAMD64_OpAtomicStore8_0(v *Value) bool {
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (AtomicStore8 ptr val mem)
|
||||
// result: (Select1 (XCHGB <types.NewTuple(typ.UInt8,types.TypeMem)> val ptr mem))
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64XCHGB, types.NewTuple(typ.UInt8, types.TypeMem))
|
||||
v0.AddArg(val)
|
||||
v0.AddArg(ptr)
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueAMD64_OpAtomicStorePtrNoWB_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (AtomicStorePtrNoWB ptr val mem)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (Select1 (XCHGQ <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64XCHGQ, types.NewTuple(typ.BytePtr, types.TypeMem))
|
||||
v0.AddArg(val)
|
||||
@ -50413,25 +50365,6 @@ func rewriteValueAMD64_OpAtomicStorePtrNoWB_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (AtomicStorePtrNoWB ptr val mem)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (Select1 (XCHGL <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64XCHGL, types.NewTuple(typ.BytePtr, types.TypeMem))
|
||||
v0.AddArg(val)
|
||||
v0.AddArg(ptr)
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpAvg64u_0(v *Value) bool {
|
||||
// match: (Avg64u x y)
|
||||
@ -51754,31 +51687,13 @@ func rewriteValueAMD64_OpConstBool_0(v *Value) bool {
|
||||
}
|
||||
}
|
||||
func rewriteValueAMD64_OpConstNil_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (ConstNil)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (MOVQconst [0])
|
||||
for {
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64MOVQconst)
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
// match: (ConstNil)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (MOVLconst [0])
|
||||
for {
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64MOVLconst)
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpCtz16_0(v *Value) bool {
|
||||
b := v.Block
|
||||
@ -52283,16 +52198,11 @@ func rewriteValueAMD64_OpEqB_0(v *Value) bool {
|
||||
}
|
||||
func rewriteValueAMD64_OpEqPtr_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (EqPtr x y)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (SETEQ (CMPQ x y))
|
||||
for {
|
||||
y := v.Args[1]
|
||||
x := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETEQ)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64CMPQ, types.TypeFlags)
|
||||
v0.AddArg(x)
|
||||
@ -52300,23 +52210,6 @@ func rewriteValueAMD64_OpEqPtr_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr x y)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (SETEQ (CMPL x y))
|
||||
for {
|
||||
y := v.Args[1]
|
||||
x := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETEQ)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64CMPL, types.TypeFlags)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpFloor_0(v *Value) bool {
|
||||
// match: (Floor x)
|
||||
@ -52741,16 +52634,11 @@ func rewriteValueAMD64_OpInterCall_0(v *Value) bool {
|
||||
}
|
||||
func rewriteValueAMD64_OpIsInBounds_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (IsInBounds idx len)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (SETB (CMPQ idx len))
|
||||
for {
|
||||
len := v.Args[1]
|
||||
idx := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETB)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64CMPQ, types.TypeFlags)
|
||||
v0.AddArg(idx)
|
||||
@ -52758,35 +52646,13 @@ func rewriteValueAMD64_OpIsInBounds_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (IsInBounds idx len)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (SETB (CMPL idx len))
|
||||
for {
|
||||
len := v.Args[1]
|
||||
idx := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETB)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64CMPL, types.TypeFlags)
|
||||
v0.AddArg(idx)
|
||||
v0.AddArg(len)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpIsNonNil_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (IsNonNil p)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (SETNE (TESTQ p p))
|
||||
for {
|
||||
p := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETNE)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64TESTQ, types.TypeFlags)
|
||||
v0.AddArg(p)
|
||||
@ -52794,35 +52660,14 @@ func rewriteValueAMD64_OpIsNonNil_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (IsNonNil p)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (SETNE (TESTL p p))
|
||||
for {
|
||||
p := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETNE)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64TESTL, types.TypeFlags)
|
||||
v0.AddArg(p)
|
||||
v0.AddArg(p)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpIsSliceInBounds_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (IsSliceInBounds idx len)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (SETBE (CMPQ idx len))
|
||||
for {
|
||||
len := v.Args[1]
|
||||
idx := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETBE)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64CMPQ, types.TypeFlags)
|
||||
v0.AddArg(idx)
|
||||
@ -52830,23 +52675,6 @@ func rewriteValueAMD64_OpIsSliceInBounds_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (IsSliceInBounds idx len)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (SETBE (CMPL idx len))
|
||||
for {
|
||||
len := v.Args[1]
|
||||
idx := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETBE)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64CMPL, types.TypeFlags)
|
||||
v0.AddArg(idx)
|
||||
v0.AddArg(len)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpLeq16_0(v *Value) bool {
|
||||
b := v.Block
|
||||
@ -53149,16 +52977,14 @@ func rewriteValueAMD64_OpLess8U_0(v *Value) bool {
|
||||
}
|
||||
}
|
||||
func rewriteValueAMD64_OpLoad_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: (is64BitInt(t) || isPtr(t) && config.PtrSize == 8)
|
||||
// cond: (is64BitInt(t) || isPtr(t))
|
||||
// result: (MOVQload ptr mem)
|
||||
for {
|
||||
t := v.Type
|
||||
mem := v.Args[1]
|
||||
ptr := v.Args[0]
|
||||
if !(is64BitInt(t) || isPtr(t) && config.PtrSize == 8) {
|
||||
if !(is64BitInt(t) || isPtr(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64MOVQload)
|
||||
@ -53167,13 +52993,13 @@ func rewriteValueAMD64_OpLoad_0(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: (is32BitInt(t) || isPtr(t) && config.PtrSize == 4)
|
||||
// cond: is32BitInt(t)
|
||||
// result: (MOVLload ptr mem)
|
||||
for {
|
||||
t := v.Type
|
||||
mem := v.Args[1]
|
||||
ptr := v.Args[0]
|
||||
if !(is32BitInt(t) || isPtr(t) && config.PtrSize == 4) {
|
||||
if !(is32BitInt(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64MOVLload)
|
||||
@ -53244,39 +53070,17 @@ func rewriteValueAMD64_OpLoad_0(v *Value) bool {
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpLocalAddr_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (LocalAddr {sym} base _)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (LEAQ {sym} base)
|
||||
for {
|
||||
sym := v.Aux
|
||||
_ = v.Args[1]
|
||||
base := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64LEAQ)
|
||||
v.Aux = sym
|
||||
v.AddArg(base)
|
||||
return true
|
||||
}
|
||||
// match: (LocalAddr {sym} base _)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (LEAL {sym} base)
|
||||
for {
|
||||
sym := v.Aux
|
||||
_ = v.Args[1]
|
||||
base := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64LEAL)
|
||||
v.Aux = sym
|
||||
v.AddArg(base)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpLsh16x16_0(v *Value) bool {
|
||||
b := v.Block
|
||||
@ -54939,16 +54743,11 @@ func rewriteValueAMD64_OpNeqB_0(v *Value) bool {
|
||||
}
|
||||
func rewriteValueAMD64_OpNeqPtr_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (NeqPtr x y)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (SETNE (CMPQ x y))
|
||||
for {
|
||||
y := v.Args[1]
|
||||
x := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETNE)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64CMPQ, types.TypeFlags)
|
||||
v0.AddArg(x)
|
||||
@ -54956,23 +54755,6 @@ func rewriteValueAMD64_OpNeqPtr_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr x y)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (SETNE (CMPL x y))
|
||||
for {
|
||||
y := v.Args[1]
|
||||
x := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SETNE)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64CMPL, types.TypeFlags)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpNilCheck_0(v *Value) bool {
|
||||
// match: (NilCheck ptr mem)
|
||||
@ -54999,15 +54781,14 @@ func rewriteValueAMD64_OpNot_0(v *Value) bool {
|
||||
}
|
||||
func rewriteValueAMD64_OpOffPtr_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (OffPtr [off] ptr)
|
||||
// cond: config.PtrSize == 8 && is32Bit(off)
|
||||
// cond: is32Bit(off)
|
||||
// result: (ADDQconst [off] ptr)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
ptr := v.Args[0]
|
||||
if !(config.PtrSize == 8 && is32Bit(off)) {
|
||||
if !(is32Bit(off)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64ADDQconst)
|
||||
@ -55016,14 +54797,10 @@ func rewriteValueAMD64_OpOffPtr_0(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
// match: (OffPtr [off] ptr)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (ADDQ (MOVQconst [off]) ptr)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
ptr := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64ADDQ)
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64MOVQconst, typ.UInt64)
|
||||
v0.AuxInt = off
|
||||
@ -55031,21 +54808,6 @@ func rewriteValueAMD64_OpOffPtr_0(v *Value) bool {
|
||||
v.AddArg(ptr)
|
||||
return true
|
||||
}
|
||||
// match: (OffPtr [off] ptr)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (ADDLconst [off] ptr)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
ptr := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64ADDLconst)
|
||||
v.AuxInt = off
|
||||
v.AddArg(ptr)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpOr16_0(v *Value) bool {
|
||||
// match: (Or16 x y)
|
||||
@ -57203,37 +56965,16 @@ func rewriteValueAMD64_OpSub8_0(v *Value) bool {
|
||||
}
|
||||
}
|
||||
func rewriteValueAMD64_OpSubPtr_0(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
// match: (SubPtr x y)
|
||||
// cond: config.PtrSize == 8
|
||||
// result: (SUBQ x y)
|
||||
for {
|
||||
y := v.Args[1]
|
||||
x := v.Args[0]
|
||||
if !(config.PtrSize == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SUBQ)
|
||||
v.AddArg(x)
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
// match: (SubPtr x y)
|
||||
// cond: config.PtrSize == 4
|
||||
// result: (SUBL x y)
|
||||
for {
|
||||
y := v.Args[1]
|
||||
x := v.Args[0]
|
||||
if !(config.PtrSize == 4) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SUBL)
|
||||
v.AddArg(x)
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueAMD64_OpTrunc_0(v *Value) bool {
|
||||
// match: (Trunc x)
|
||||
|
@ -431,6 +431,8 @@ func rewriteValueARM64(v *Value) bool {
|
||||
return rewriteValueARM64_OpAtomicStore32_0(v)
|
||||
case OpAtomicStore64:
|
||||
return rewriteValueARM64_OpAtomicStore64_0(v)
|
||||
case OpAtomicStore8:
|
||||
return rewriteValueARM64_OpAtomicStore8_0(v)
|
||||
case OpAtomicStorePtrNoWB:
|
||||
return rewriteValueARM64_OpAtomicStorePtrNoWB_0(v)
|
||||
case OpAvg64u:
|
||||
@ -27669,6 +27671,20 @@ func rewriteValueARM64_OpAtomicStore64_0(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueARM64_OpAtomicStore8_0(v *Value) bool {
|
||||
// match: (AtomicStore8 ptr val mem)
|
||||
// result: (STLRB ptr val mem)
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
v.reset(OpARM64STLRB)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueARM64_OpAtomicStorePtrNoWB_0(v *Value) bool {
|
||||
// match: (AtomicStorePtrNoWB ptr val mem)
|
||||
// result: (STLR ptr val mem)
|
||||
|
@ -41,12 +41,16 @@ func rewriteValueMIPS(v *Value) bool {
|
||||
return rewriteValueMIPS_OpAtomicExchange32_0(v)
|
||||
case OpAtomicLoad32:
|
||||
return rewriteValueMIPS_OpAtomicLoad32_0(v)
|
||||
case OpAtomicLoad8:
|
||||
return rewriteValueMIPS_OpAtomicLoad8_0(v)
|
||||
case OpAtomicLoadPtr:
|
||||
return rewriteValueMIPS_OpAtomicLoadPtr_0(v)
|
||||
case OpAtomicOr8:
|
||||
return rewriteValueMIPS_OpAtomicOr8_0(v)
|
||||
case OpAtomicStore32:
|
||||
return rewriteValueMIPS_OpAtomicStore32_0(v)
|
||||
case OpAtomicStore8:
|
||||
return rewriteValueMIPS_OpAtomicStore8_0(v)
|
||||
case OpAtomicStorePtrNoWB:
|
||||
return rewriteValueMIPS_OpAtomicStorePtrNoWB_0(v)
|
||||
case OpAvg32u:
|
||||
@ -245,8 +249,8 @@ func rewriteValueMIPS(v *Value) bool {
|
||||
return rewriteValueMIPS_OpMIPSCMOVZzero_0(v)
|
||||
case OpMIPSLoweredAtomicAdd:
|
||||
return rewriteValueMIPS_OpMIPSLoweredAtomicAdd_0(v)
|
||||
case OpMIPSLoweredAtomicStore:
|
||||
return rewriteValueMIPS_OpMIPSLoweredAtomicStore_0(v)
|
||||
case OpMIPSLoweredAtomicStore32:
|
||||
return rewriteValueMIPS_OpMIPSLoweredAtomicStore32_0(v)
|
||||
case OpMIPSMOVBUload:
|
||||
return rewriteValueMIPS_OpMIPSMOVBUload_0(v)
|
||||
case OpMIPSMOVBUreg:
|
||||
@ -826,11 +830,23 @@ func rewriteValueMIPS_OpAtomicExchange32_0(v *Value) bool {
|
||||
}
|
||||
func rewriteValueMIPS_OpAtomicLoad32_0(v *Value) bool {
|
||||
// match: (AtomicLoad32 ptr mem)
|
||||
// result: (LoweredAtomicLoad ptr mem)
|
||||
// result: (LoweredAtomicLoad32 ptr mem)
|
||||
for {
|
||||
mem := v.Args[1]
|
||||
ptr := v.Args[0]
|
||||
v.reset(OpMIPSLoweredAtomicLoad)
|
||||
v.reset(OpMIPSLoweredAtomicLoad32)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueMIPS_OpAtomicLoad8_0(v *Value) bool {
|
||||
// match: (AtomicLoad8 ptr mem)
|
||||
// result: (LoweredAtomicLoad8 ptr mem)
|
||||
for {
|
||||
mem := v.Args[1]
|
||||
ptr := v.Args[0]
|
||||
v.reset(OpMIPSLoweredAtomicLoad8)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
@ -838,11 +854,11 @@ func rewriteValueMIPS_OpAtomicLoad32_0(v *Value) bool {
|
||||
}
|
||||
func rewriteValueMIPS_OpAtomicLoadPtr_0(v *Value) bool {
|
||||
// match: (AtomicLoadPtr ptr mem)
|
||||
// result: (LoweredAtomicLoad ptr mem)
|
||||
// result: (LoweredAtomicLoad32 ptr mem)
|
||||
for {
|
||||
mem := v.Args[1]
|
||||
ptr := v.Args[0]
|
||||
v.reset(OpMIPSLoweredAtomicLoad)
|
||||
v.reset(OpMIPSLoweredAtomicLoad32)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
@ -923,12 +939,26 @@ func rewriteValueMIPS_OpAtomicOr8_0(v *Value) bool {
|
||||
}
|
||||
func rewriteValueMIPS_OpAtomicStore32_0(v *Value) bool {
|
||||
// match: (AtomicStore32 ptr val mem)
|
||||
// result: (LoweredAtomicStore ptr val mem)
|
||||
// result: (LoweredAtomicStore32 ptr val mem)
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
v.reset(OpMIPSLoweredAtomicStore)
|
||||
v.reset(OpMIPSLoweredAtomicStore32)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueMIPS_OpAtomicStore8_0(v *Value) bool {
|
||||
// match: (AtomicStore8 ptr val mem)
|
||||
// result: (LoweredAtomicStore8 ptr val mem)
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
v.reset(OpMIPSLoweredAtomicStore8)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
@ -937,12 +967,12 @@ func rewriteValueMIPS_OpAtomicStore32_0(v *Value) bool {
|
||||
}
|
||||
func rewriteValueMIPS_OpAtomicStorePtrNoWB_0(v *Value) bool {
|
||||
// match: (AtomicStorePtrNoWB ptr val mem)
|
||||
// result: (LoweredAtomicStore ptr val mem)
|
||||
// result: (LoweredAtomicStore32 ptr val mem)
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
v.reset(OpMIPSLoweredAtomicStore)
|
||||
v.reset(OpMIPSLoweredAtomicStore32)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
@ -3000,8 +3030,8 @@ func rewriteValueMIPS_OpMIPSLoweredAtomicAdd_0(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueMIPS_OpMIPSLoweredAtomicStore_0(v *Value) bool {
|
||||
// match: (LoweredAtomicStore ptr (MOVWconst [0]) mem)
|
||||
func rewriteValueMIPS_OpMIPSLoweredAtomicStore32_0(v *Value) bool {
|
||||
// match: (LoweredAtomicStore32 ptr (MOVWconst [0]) mem)
|
||||
// result: (LoweredAtomicStorezero ptr mem)
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
|
@ -57,6 +57,8 @@ func rewriteValueMIPS64(v *Value) bool {
|
||||
return rewriteValueMIPS64_OpAtomicStore32_0(v)
|
||||
case OpAtomicStore64:
|
||||
return rewriteValueMIPS64_OpAtomicStore64_0(v)
|
||||
case OpAtomicStore8:
|
||||
return rewriteValueMIPS64_OpAtomicStore8_0(v)
|
||||
case OpAtomicStorePtrNoWB:
|
||||
return rewriteValueMIPS64_OpAtomicStorePtrNoWB_0(v)
|
||||
case OpAvg64u:
|
||||
@ -938,6 +940,20 @@ func rewriteValueMIPS64_OpAtomicStore64_0(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueMIPS64_OpAtomicStore8_0(v *Value) bool {
|
||||
// match: (AtomicStore8 ptr val mem)
|
||||
// result: (LoweredAtomicStore8 ptr val mem)
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
v.reset(OpMIPS64LoweredAtomicStore8)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueMIPS64_OpAtomicStorePtrNoWB_0(v *Value) bool {
|
||||
// match: (AtomicStorePtrNoWB ptr val mem)
|
||||
// result: (LoweredAtomicStore64 ptr val mem)
|
||||
|
@ -71,6 +71,8 @@ func rewriteValuePPC64(v *Value) bool {
|
||||
return rewriteValuePPC64_OpAtomicStore32_0(v)
|
||||
case OpAtomicStore64:
|
||||
return rewriteValuePPC64_OpAtomicStore64_0(v)
|
||||
case OpAtomicStore8:
|
||||
return rewriteValuePPC64_OpAtomicStore8_0(v)
|
||||
case OpAtomicStoreRel32:
|
||||
return rewriteValuePPC64_OpAtomicStoreRel32_0(v)
|
||||
case OpAvg64u:
|
||||
@ -1132,6 +1134,21 @@ func rewriteValuePPC64_OpAtomicStore64_0(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValuePPC64_OpAtomicStore8_0(v *Value) bool {
|
||||
// match: (AtomicStore8 ptr val mem)
|
||||
// result: (LoweredAtomicStore8 [1] ptr val mem)
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
v.reset(OpPPC64LoweredAtomicStore8)
|
||||
v.AuxInt = 1
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValuePPC64_OpAtomicStoreRel32_0(v *Value) bool {
|
||||
// match: (AtomicStoreRel32 ptr val mem)
|
||||
// result: (LoweredAtomicStore32 [0] ptr val mem)
|
||||
|
@ -60,6 +60,8 @@ func rewriteValueS390X(v *Value) bool {
|
||||
return rewriteValueS390X_OpAtomicStore32_0(v)
|
||||
case OpAtomicStore64:
|
||||
return rewriteValueS390X_OpAtomicStore64_0(v)
|
||||
case OpAtomicStore8:
|
||||
return rewriteValueS390X_OpAtomicStore8_0(v)
|
||||
case OpAtomicStorePtrNoWB:
|
||||
return rewriteValueS390X_OpAtomicStorePtrNoWB_0(v)
|
||||
case OpAtomicStoreRel32:
|
||||
@ -1153,6 +1155,23 @@ func rewriteValueS390X_OpAtomicStore64_0(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueS390X_OpAtomicStore8_0(v *Value) bool {
|
||||
b := v.Block
|
||||
// match: (AtomicStore8 ptr val mem)
|
||||
// result: (SYNC (MOVBatomicstore ptr val mem))
|
||||
for {
|
||||
mem := v.Args[2]
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
v.reset(OpS390XSYNC)
|
||||
v0 := b.NewValue0(v.Pos, OpS390XMOVBatomicstore, types.TypeMem)
|
||||
v0.AddArg(ptr)
|
||||
v0.AddArg(val)
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueS390X_OpAtomicStorePtrNoWB_0(v *Value) bool {
|
||||
b := v.Block
|
||||
// match: (AtomicStorePtrNoWB ptr val mem)
|
||||
|
@ -6142,18 +6142,18 @@ func rewriteValuegeneric_OpArraySelect_0(v *Value) bool {
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ArraySelect [0] x:(IData _))
|
||||
// result: x
|
||||
// match: (ArraySelect [0] (IData x))
|
||||
// result: (IData x)
|
||||
for {
|
||||
if v.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
if x.Op != OpIData {
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpIData {
|
||||
break
|
||||
}
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpIData)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@ -43502,18 +43502,18 @@ func rewriteValuegeneric_OpStructSelect_10(v *Value) bool {
|
||||
v0.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (StructSelect [0] x:(IData _))
|
||||
// result: x
|
||||
// match: (StructSelect [0] (IData x))
|
||||
// result: (IData x)
|
||||
for {
|
||||
if v.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
x := v.Args[0]
|
||||
if x.Op != OpIData {
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpIData {
|
||||
break
|
||||
}
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpIData)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func walkDirs(t *testing.T, dir string, action func(string)) {
|
||||
}
|
||||
} else if fi.IsDir() && fi.Name() != "testdata" {
|
||||
path := filepath.Join(dir, fi.Name())
|
||||
if !strings.HasSuffix(path, "/test") {
|
||||
if !strings.HasSuffix(path, string(filepath.Separator)+"test") {
|
||||
dirs = append(dirs, path)
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ func Init(arch *gc.Arch) {
|
||||
arch.MAXWIDTH = 1 << 50
|
||||
|
||||
arch.ZeroRange = zeroRange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
@ -45,21 +44,6 @@ func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Pr
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
for i := int64(0); i < size; i += 8 {
|
||||
p := pp.Prog(wasm.AGet)
|
||||
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: wasm.REG_SP}
|
||||
|
||||
p = pp.Prog(wasm.AI64Const)
|
||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0}
|
||||
|
||||
p = pp.Prog(wasm.AI64Store)
|
||||
p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_AUTO, Offset: n.Xoffset + i, Sym: sym}
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
return pp.Prog(wasm.ANop)
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ func Init(arch *gc.Arch) {
|
||||
arch.MAXWIDTH = (1 << 32) - 1
|
||||
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
|
@ -37,22 +37,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, ax *uint32) *obj.Prog
|
||||
return p
|
||||
}
|
||||
|
||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
||||
// Note: this code must not clobber any registers.
|
||||
sym := n.Sym.Linksym()
|
||||
size := n.Type.Size()
|
||||
for i := int64(0); i < size; i += 4 {
|
||||
p := pp.Prog(x86.AMOVL)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = 0
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_AUTO
|
||||
p.To.Reg = x86.REG_SP
|
||||
p.To.Offset = n.Xoffset + i
|
||||
p.To.Sym = sym
|
||||
}
|
||||
}
|
||||
|
||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||
// See comment in ../amd64/ggen.go.
|
||||
p := pp.Prog(x86.AXCHGL)
|
||||
|
106
src/cmd/dist/build.go
vendored
106
src/cmd/dist/build.go
vendored
@ -605,26 +605,26 @@ func startInstall(dir string) chan struct{} {
|
||||
|
||||
// runInstall installs the library, package, or binary associated with dir,
|
||||
// which is relative to $GOROOT/src.
|
||||
func runInstall(dir string, ch chan struct{}) {
|
||||
if dir == "net" || dir == "os/user" || dir == "crypto/x509" {
|
||||
fatalf("go_bootstrap cannot depend on cgo package %s", dir)
|
||||
func runInstall(pkg string, ch chan struct{}) {
|
||||
if pkg == "net" || pkg == "os/user" || pkg == "crypto/x509" {
|
||||
fatalf("go_bootstrap cannot depend on cgo package %s", pkg)
|
||||
}
|
||||
|
||||
defer close(ch)
|
||||
|
||||
if dir == "unsafe" {
|
||||
if pkg == "unsafe" {
|
||||
return
|
||||
}
|
||||
|
||||
if vflag > 0 {
|
||||
if goos != gohostos || goarch != gohostarch {
|
||||
errprintf("%s (%s/%s)\n", dir, goos, goarch)
|
||||
errprintf("%s (%s/%s)\n", pkg, goos, goarch)
|
||||
} else {
|
||||
errprintf("%s\n", dir)
|
||||
errprintf("%s\n", pkg)
|
||||
}
|
||||
}
|
||||
|
||||
workdir := pathf("%s/%s", workdir, dir)
|
||||
workdir := pathf("%s/%s", workdir, pkg)
|
||||
xmkdirall(workdir)
|
||||
|
||||
var clean []string
|
||||
@ -634,11 +634,14 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
}
|
||||
}()
|
||||
|
||||
// path = full path to dir.
|
||||
path := pathf("%s/src/%s", goroot, dir)
|
||||
// dir = full path to pkg.
|
||||
dir := pathf("%s/src/%s", goroot, pkg)
|
||||
name := filepath.Base(dir)
|
||||
|
||||
ispkg := !strings.HasPrefix(dir, "cmd/") || strings.Contains(dir, "/internal/")
|
||||
// ispkg predicts whether the package should be linked as a binary, based
|
||||
// on the name. There should be no "main" packages in vendor, since
|
||||
// 'go mod vendor' will only copy imported packages there.
|
||||
ispkg := !strings.HasPrefix(pkg, "cmd/") || strings.Contains(pkg, "/internal/") || strings.Contains(pkg, "/vendor/")
|
||||
|
||||
// Start final link command line.
|
||||
// Note: code below knows that link.p[targ] is the target.
|
||||
@ -650,7 +653,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
if ispkg {
|
||||
// Go library (package).
|
||||
ispackcmd = true
|
||||
link = []string{"pack", pathf("%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir)}
|
||||
link = []string{"pack", packagefile(pkg)}
|
||||
targ = len(link) - 1
|
||||
xmkdirall(filepath.Dir(link[targ]))
|
||||
} else {
|
||||
@ -675,7 +678,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
// Gather files that are sources for this target.
|
||||
// Everything in that directory, and any target-specific
|
||||
// additions.
|
||||
files := xreaddir(path)
|
||||
files := xreaddir(dir)
|
||||
|
||||
// Remove files beginning with . or _,
|
||||
// which are likely to be editor temporary files.
|
||||
@ -687,7 +690,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
})
|
||||
|
||||
for _, dt := range deptab {
|
||||
if dir == dt.prefix || strings.HasSuffix(dt.prefix, "/") && strings.HasPrefix(dir, dt.prefix) {
|
||||
if pkg == dt.prefix || strings.HasSuffix(dt.prefix, "/") && strings.HasPrefix(pkg, dt.prefix) {
|
||||
for _, p := range dt.dep {
|
||||
p = os.ExpandEnv(p)
|
||||
files = append(files, p)
|
||||
@ -699,7 +702,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
// Convert to absolute paths.
|
||||
for i, p := range files {
|
||||
if !filepath.IsAbs(p) {
|
||||
files[i] = pathf("%s/%s", path, p)
|
||||
files[i] = pathf("%s/%s", dir, p)
|
||||
}
|
||||
}
|
||||
|
||||
@ -715,7 +718,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
return false
|
||||
ok:
|
||||
t := mtime(p)
|
||||
if !t.IsZero() && !strings.HasSuffix(p, ".a") && !shouldbuild(p, dir) {
|
||||
if !t.IsZero() && !strings.HasSuffix(p, ".a") && !shouldbuild(p, pkg) {
|
||||
return false
|
||||
}
|
||||
if strings.HasSuffix(p, ".go") {
|
||||
@ -742,7 +745,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
}
|
||||
|
||||
// For package runtime, copy some files into the work space.
|
||||
if dir == "runtime" {
|
||||
if pkg == "runtime" {
|
||||
xmkdirall(pathf("%s/pkg/include", goroot))
|
||||
// For use by assembly and C files.
|
||||
copyfile(pathf("%s/pkg/include/textflag.h", goroot),
|
||||
@ -764,7 +767,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
if vflag > 1 {
|
||||
errprintf("generate %s\n", p)
|
||||
}
|
||||
gt.gen(path, p)
|
||||
gt.gen(dir, p)
|
||||
// Do not add generated file to clean list.
|
||||
// In runtime, we want to be able to
|
||||
// build the package with the go tool,
|
||||
@ -782,22 +785,31 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
built:
|
||||
}
|
||||
|
||||
// Make sure dependencies are installed.
|
||||
var deps []string
|
||||
// Resolve imported packages to actual package paths.
|
||||
// Make sure they're installed.
|
||||
importMap := make(map[string]string)
|
||||
for _, p := range gofiles {
|
||||
deps = append(deps, readimports(p)...)
|
||||
for _, imp := range readimports(p) {
|
||||
importMap[imp] = resolveVendor(imp, dir)
|
||||
}
|
||||
}
|
||||
for _, dir1 := range deps {
|
||||
startInstall(dir1)
|
||||
sortedImports := make([]string, 0, len(importMap))
|
||||
for imp := range importMap {
|
||||
sortedImports = append(sortedImports, imp)
|
||||
}
|
||||
for _, dir1 := range deps {
|
||||
install(dir1)
|
||||
sort.Strings(sortedImports)
|
||||
|
||||
for _, dep := range importMap {
|
||||
startInstall(dep)
|
||||
}
|
||||
for _, dep := range importMap {
|
||||
install(dep)
|
||||
}
|
||||
|
||||
if goos != gohostos || goarch != gohostarch {
|
||||
// We've generated the right files; the go command can do the build.
|
||||
if vflag > 1 {
|
||||
errprintf("skip build for cross-compile %s\n", dir)
|
||||
errprintf("skip build for cross-compile %s\n", pkg)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -830,18 +842,35 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
if err := ioutil.WriteFile(goasmh, nil, 0666); err != nil {
|
||||
fatalf("cannot write empty go_asm.h: %s", err)
|
||||
}
|
||||
bgrun(&wg, path, asmabis...)
|
||||
bgrun(&wg, dir, asmabis...)
|
||||
bgwait(&wg)
|
||||
}
|
||||
|
||||
// Build an importcfg file for the compiler.
|
||||
buf := &bytes.Buffer{}
|
||||
for _, imp := range sortedImports {
|
||||
if imp == "unsafe" {
|
||||
continue
|
||||
}
|
||||
dep := importMap[imp]
|
||||
if imp != dep {
|
||||
fmt.Fprintf(buf, "importmap %s=%s\n", imp, dep)
|
||||
}
|
||||
fmt.Fprintf(buf, "packagefile %s=%s\n", dep, packagefile(dep))
|
||||
}
|
||||
importcfg := pathf("%s/importcfg", workdir)
|
||||
if err := ioutil.WriteFile(importcfg, buf.Bytes(), 0666); err != nil {
|
||||
fatalf("cannot write importcfg file: %v", err)
|
||||
}
|
||||
|
||||
var archive string
|
||||
// The next loop will compile individual non-Go files.
|
||||
// Hand the Go files to the compiler en masse.
|
||||
// For packages containing assembly, this writes go_asm.h, which
|
||||
// the assembly files will need.
|
||||
pkg := dir
|
||||
if strings.HasPrefix(dir, "cmd/") && strings.Count(dir, "/") == 1 {
|
||||
pkg = "main"
|
||||
pkgName := pkg
|
||||
if strings.HasPrefix(pkg, "cmd/") && strings.Count(pkg, "/") == 1 {
|
||||
pkgName = "main"
|
||||
}
|
||||
b := pathf("%s/_go_.a", workdir)
|
||||
clean = append(clean, b)
|
||||
@ -852,11 +881,11 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
}
|
||||
|
||||
// Compile Go code.
|
||||
compile := []string{pathf("%s/compile", tooldir), "-std", "-pack", "-o", b, "-p", pkg}
|
||||
compile := []string{pathf("%s/compile", tooldir), "-std", "-pack", "-o", b, "-p", pkgName, "-importcfg", importcfg}
|
||||
if gogcflags != "" {
|
||||
compile = append(compile, strings.Fields(gogcflags)...)
|
||||
}
|
||||
if dir == "runtime" {
|
||||
if pkg == "runtime" {
|
||||
compile = append(compile, "-+")
|
||||
}
|
||||
if len(sfiles) > 0 {
|
||||
@ -874,7 +903,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
// We use bgrun and immediately wait for it instead of calling run() synchronously.
|
||||
// This executes all jobs through the bgwork channel and allows the process
|
||||
// to exit cleanly in case an error occurs.
|
||||
bgrun(&wg, path, compile...)
|
||||
bgrun(&wg, dir, compile...)
|
||||
bgwait(&wg)
|
||||
|
||||
// Compile the files.
|
||||
@ -888,7 +917,7 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
// Change the last character of the output file (which was c or s).
|
||||
b = b[:len(b)-1] + "o"
|
||||
compile = append(compile, "-o", b, p)
|
||||
bgrun(&wg, path, compile...)
|
||||
bgrun(&wg, dir, compile...)
|
||||
|
||||
link = append(link, b)
|
||||
if doclean {
|
||||
@ -909,6 +938,12 @@ func runInstall(dir string, ch chan struct{}) {
|
||||
bgwait(&wg)
|
||||
}
|
||||
|
||||
// packagefile returns the path to a compiled .a file for the given package
|
||||
// path. Paths may need to be resolved with resolveVendor first.
|
||||
func packagefile(pkg string) string {
|
||||
return pathf("%s/pkg/%s_%s/%s.a", goroot, goos, goarch, pkg)
|
||||
}
|
||||
|
||||
// matchfield reports whether the field (x,y,z) matches this build.
|
||||
// all the elements in the field must be satisfied.
|
||||
func matchfield(f string) bool {
|
||||
@ -940,7 +975,7 @@ func matchtag(tag string) bool {
|
||||
// of GOOS and GOARCH.
|
||||
// We also allow the special tag cmd_go_bootstrap.
|
||||
// See ../go/bootstrap.go and package go/build.
|
||||
func shouldbuild(file, dir string) bool {
|
||||
func shouldbuild(file, pkg string) bool {
|
||||
// Check file name for GOOS or GOARCH.
|
||||
name := filepath.Base(file)
|
||||
excluded := func(list []string, ok string) bool {
|
||||
@ -982,7 +1017,7 @@ func shouldbuild(file, dir string) bool {
|
||||
if code == "package documentation" {
|
||||
return false
|
||||
}
|
||||
if code == "package main" && dir != "cmd/go" && dir != "cmd/cgo" {
|
||||
if code == "package main" && pkg != "cmd/go" && pkg != "cmd/cgo" {
|
||||
return false
|
||||
}
|
||||
if !strings.HasPrefix(p, "//") {
|
||||
@ -1485,6 +1520,7 @@ var cgoEnabled = map[string]bool{
|
||||
"freebsd/386": true,
|
||||
"freebsd/amd64": true,
|
||||
"freebsd/arm": true,
|
||||
"freebsd/arm64": true,
|
||||
"illumos/amd64": true,
|
||||
"linux/386": true,
|
||||
"linux/amd64": true,
|
||||
|
31
src/cmd/dist/imports.go
vendored
31
src/cmd/dist/imports.go
vendored
@ -11,7 +11,10 @@ package main
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
@ -243,3 +246,31 @@ func readimports(file string) []string {
|
||||
|
||||
return imports
|
||||
}
|
||||
|
||||
// resolveVendor returns a unique package path imported with the given import
|
||||
// path from srcDir.
|
||||
//
|
||||
// resolveVendor assumes that a package is vendored if and only if its first
|
||||
// path component contains a dot. If a package is vendored, its import path
|
||||
// is returned with a "vendor" or "cmd/vendor" prefix, depending on srcDir.
|
||||
// Otherwise, the import path is returned verbatim.
|
||||
func resolveVendor(imp, srcDir string) string {
|
||||
var first string
|
||||
if i := strings.Index(imp, "/"); i < 0 {
|
||||
first = imp
|
||||
} else {
|
||||
first = imp[:i]
|
||||
}
|
||||
isStandard := !strings.Contains(first, ".")
|
||||
if isStandard {
|
||||
return imp
|
||||
}
|
||||
|
||||
if strings.HasPrefix(srcDir, filepath.Join(goroot, "src", "cmd")) {
|
||||
return path.Join("cmd", "vendor", imp)
|
||||
} else if strings.HasPrefix(srcDir, filepath.Join(goroot, "src")) {
|
||||
return path.Join("vendor", imp)
|
||||
} else {
|
||||
panic(fmt.Sprintf("srcDir %q not in GOOROT/src", srcDir))
|
||||
}
|
||||
}
|
||||
|
13
src/cmd/dist/test.go
vendored
13
src/cmd/dist/test.go
vendored
@ -418,7 +418,7 @@ func (t *tester) registerTests() {
|
||||
cmd.Args = append(cmd.Args, "-tags=race")
|
||||
}
|
||||
cmd.Args = append(cmd.Args, "std")
|
||||
if !t.race {
|
||||
if t.shouldTestCmd() {
|
||||
cmd.Args = append(cmd.Args, "cmd")
|
||||
}
|
||||
cmd.Stderr = new(bytes.Buffer)
|
||||
@ -1455,6 +1455,17 @@ func (t *tester) shouldUsePrecompiledStdTest() bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (t *tester) shouldTestCmd() bool {
|
||||
if t.race {
|
||||
return false
|
||||
}
|
||||
if goos == "js" && goarch == "wasm" {
|
||||
// Issues 25911, 35220
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// prebuiltGoPackageTestBinary returns the path where we'd expect
|
||||
// the pre-built go test binary to be on disk when dist test is run with
|
||||
// a single argument.
|
||||
|
@ -15,11 +15,11 @@ import (
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"cmd/internal/diff"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -186,7 +186,7 @@ func processFile(filename string, useStdin bool) error {
|
||||
}
|
||||
|
||||
if *doDiff {
|
||||
data, err := diff(src, newSrc)
|
||||
data, err := diff.Diff("go-fix", src, newSrc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("computing diff: %s", err)
|
||||
}
|
||||
@ -237,46 +237,3 @@ func isGoFile(f os.FileInfo) bool {
|
||||
name := f.Name()
|
||||
return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
||||
}
|
||||
|
||||
func writeTempFile(dir, prefix string, data []byte) (string, error) {
|
||||
file, err := ioutil.TempFile(dir, prefix)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = file.Write(data)
|
||||
if err1 := file.Close(); err == nil {
|
||||
err = err1
|
||||
}
|
||||
if err != nil {
|
||||
os.Remove(file.Name())
|
||||
return "", err
|
||||
}
|
||||
return file.Name(), nil
|
||||
}
|
||||
|
||||
func diff(b1, b2 []byte) (data []byte, err error) {
|
||||
f1, err := writeTempFile("", "go-fix", b1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer os.Remove(f1)
|
||||
|
||||
f2, err := writeTempFile("", "go-fix", b2)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer os.Remove(f2)
|
||||
|
||||
cmd := "diff"
|
||||
if runtime.GOOS == "plan9" {
|
||||
cmd = "/bin/ape/diff"
|
||||
}
|
||||
|
||||
data, err = exec.Command(cmd, "-u", f1, f2).CombinedOutput()
|
||||
if len(data) > 0 {
|
||||
// diff exits with a non-zero status when the files don't match.
|
||||
// Ignore that failure as long as we get output.
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"go/parser"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"cmd/internal/diff"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
@ -123,7 +125,7 @@ func TestRewrite(t *testing.T) {
|
||||
}
|
||||
|
||||
func tdiff(t *testing.T, a, b string) {
|
||||
data, err := diff([]byte(a), []byte(b))
|
||||
data, err := diff.Diff("go-fix-test", []byte(a), []byte(b))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
|
@ -6,7 +6,8 @@ require (
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20180524225900-fc6590592b44 // indirect
|
||||
golang.org/x/arch v0.0.0-20190815191158-8a70ba74b3a1
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||
golang.org/x/mod v0.1.1-0.20191029194233-18c3998b6452
|
||||
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 // indirect
|
||||
golang.org/x/tools v0.0.0-20191018203202-04252eccb9d5
|
||||
)
|
||||
|
@ -5,11 +5,15 @@ github.com/ianlancetaylor/demangle v0.0.0-20180524225900-fc6590592b44/go.mod h1:
|
||||
golang.org/x/arch v0.0.0-20190815191158-8a70ba74b3a1 h1:A71BZbKSu+DtCNry/x5JKn20C+64DirDHmePEA8k0FY=
|
||||
golang.org/x/arch v0.0.0-20190815191158-8a70ba74b3a1/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.1.1-0.20191029194233-18c3998b6452 h1:ES2W0A+AqNBCkgWga22gheu9IUDjq3TDmeCdY1A7jhk=
|
||||
golang.org/x/mod v0.1.1-0.20191029194233-18c3998b6452/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 h1:vsphBvatvfbhlb4PO1BYSr9dzugGxJ/SQHoNufZJq1w=
|
||||
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
@ -17,4 +21,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20191018203202-04252eccb9d5 h1:TFUhCYbgGMOGnRxJv+j0iAcxCjk8oGjXXWNejQBhUUs=
|
||||
golang.org/x/tools v0.0.0-20191018203202-04252eccb9d5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
@ -1,135 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dirhash
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func h(s string) string {
|
||||
return fmt.Sprintf("%x", sha256.Sum256([]byte(s)))
|
||||
}
|
||||
|
||||
func htop(k string, s string) string {
|
||||
sum := sha256.Sum256([]byte(s))
|
||||
return k + ":" + base64.StdEncoding.EncodeToString(sum[:])
|
||||
}
|
||||
|
||||
func TestHash1(t *testing.T) {
|
||||
files := []string{"xyz", "abc"}
|
||||
open := func(name string) (io.ReadCloser, error) {
|
||||
return ioutil.NopCloser(strings.NewReader("data for " + name)), nil
|
||||
}
|
||||
want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "abc", h("data for xyz"), "xyz"))
|
||||
out, err := Hash1(files, open)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if out != want {
|
||||
t.Errorf("Hash1(...) = %s, want %s", out, want)
|
||||
}
|
||||
|
||||
_, err = Hash1([]string{"xyz", "a\nbc"}, open)
|
||||
if err == nil {
|
||||
t.Error("Hash1: expected error on newline in filenames")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashDir(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "dirhash-test-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "prefix/abc", h("data for xyz"), "prefix/xyz"))
|
||||
out, err := HashDir(dir, "prefix", Hash1)
|
||||
if err != nil {
|
||||
t.Fatalf("HashDir: %v", err)
|
||||
}
|
||||
if out != want {
|
||||
t.Errorf("HashDir(...) = %s, want %s", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashZip(t *testing.T) {
|
||||
f, err := ioutil.TempFile("", "dirhash-test-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
defer f.Close()
|
||||
|
||||
z := zip.NewWriter(f)
|
||||
w, err := z.Create("prefix/xyz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w.Write([]byte("data for xyz"))
|
||||
w, err = z.Create("prefix/abc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w.Write([]byte("data for abc"))
|
||||
if err := z.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "prefix/abc", h("data for xyz"), "prefix/xyz"))
|
||||
out, err := HashZip(f.Name(), Hash1)
|
||||
if err != nil {
|
||||
t.Fatalf("HashDir: %v", err)
|
||||
}
|
||||
if out != want {
|
||||
t.Errorf("HashDir(...) = %s, want %s", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDirFiles(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "dirfiles-test-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Mkdir(filepath.Join(dir, "subdir"), 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "subdir", "xyz"), []byte("data for subdir xyz"), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
prefix := "foo/bar@v2.3.4"
|
||||
out, err := DirFiles(dir, prefix)
|
||||
if err != nil {
|
||||
t.Fatalf("DirFiles: %v", err)
|
||||
}
|
||||
for _, file := range out {
|
||||
if !strings.HasPrefix(file, prefix) {
|
||||
t.Errorf("Dir file = %s, want prefix %s", file, prefix)
|
||||
}
|
||||
}
|
||||
}
|
@ -237,7 +237,7 @@ func runEnv(cmd *base.Command, args []string) {
|
||||
base.Fatalf("go env -w: arguments must be KEY=VALUE: invalid argument: %s", arg)
|
||||
}
|
||||
key, val := arg[:i], arg[i+1:]
|
||||
if err := checkEnvWrite(key, val, env); err != nil {
|
||||
if err := checkEnvWrite(key, val); err != nil {
|
||||
base.Fatalf("go env -w: %v", err)
|
||||
}
|
||||
if _, ok := add[key]; ok {
|
||||
@ -259,7 +259,7 @@ func runEnv(cmd *base.Command, args []string) {
|
||||
}
|
||||
del := make(map[string]bool)
|
||||
for _, arg := range args {
|
||||
if err := checkEnvWrite(arg, "", env); err != nil {
|
||||
if err := checkEnvWrite(arg, ""); err != nil {
|
||||
base.Fatalf("go env -u: %v", err)
|
||||
}
|
||||
del[arg] = true
|
||||
@ -330,7 +330,7 @@ func printEnvAsJSON(env []cfg.EnvVar) {
|
||||
}
|
||||
}
|
||||
|
||||
func checkEnvWrite(key, val string, env []cfg.EnvVar) error {
|
||||
func checkEnvWrite(key, val string) error {
|
||||
switch key {
|
||||
case "GOEXE", "GOGCCFLAGS", "GOHOSTARCH", "GOHOSTOS", "GOMOD", "GOTOOLDIR":
|
||||
return fmt.Errorf("%s cannot be modified", key)
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// The following functions are copied verbatim from cmd/go/internal/module/module.go,
|
||||
// The following functions are copied verbatim from golang.org/x/mod/module/module.go,
|
||||
// with a change to additionally reject Windows short-names,
|
||||
// and one to accept arbitrary letters (golang.org/issue/29101).
|
||||
//
|
||||
|
@ -593,7 +593,7 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS
|
||||
return setErrorPos(perr, importPos)
|
||||
}
|
||||
if mode&ResolveImport != 0 {
|
||||
if perr := disallowVendor(srcDir, parent, parentPath, path, p, stk); perr != p {
|
||||
if perr := disallowVendor(srcDir, path, p, stk); perr != p {
|
||||
return setErrorPos(perr, importPos)
|
||||
}
|
||||
}
|
||||
@ -1321,11 +1321,10 @@ func findInternal(path string) (index int, ok bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// disallowVendor checks that srcDir (containing package importerPath, if non-empty)
|
||||
// is allowed to import p as path.
|
||||
// disallowVendor checks that srcDir is allowed to import p as path.
|
||||
// If the import is allowed, disallowVendor returns the original package p.
|
||||
// If not, it returns a new package containing just an appropriate error.
|
||||
func disallowVendor(srcDir string, importer *Package, importerPath, path string, p *Package, stk *ImportStack) *Package {
|
||||
func disallowVendor(srcDir string, path string, p *Package, stk *ImportStack) *Package {
|
||||
// The stack includes p.ImportPath.
|
||||
// If that's the only thing on the stack, we started
|
||||
// with a name given on the command line, not an
|
||||
|
@ -5,16 +5,17 @@
|
||||
package modcmd
|
||||
|
||||
import (
|
||||
"cmd/go/internal/cfg"
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/modfetch"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/par"
|
||||
"cmd/go/internal/work"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
var cmdDownload = &base.Command{
|
||||
|
@ -16,10 +16,11 @@ import (
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/modfetch"
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/work"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
var cmdEdit = &base.Command{
|
||||
|
@ -8,15 +8,16 @@ package modcmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"cmd/go/internal/cfg"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/par"
|
||||
"cmd/go/internal/work"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
var cmdGraph = &base.Command{
|
||||
|
@ -14,8 +14,9 @@ import (
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/modfetch"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/work"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
var cmdTidy = &base.Command{
|
||||
|
@ -18,9 +18,10 @@ import (
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/imports"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/semver"
|
||||
"cmd/go/internal/work"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
var cmdVendor = &base.Command{
|
||||
|
@ -6,17 +6,18 @@ package modcmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/go/internal/cfg"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/dirhash"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/modfetch"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/work"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/sumdb/dirhash"
|
||||
)
|
||||
|
||||
var cmdVerify = &base.Command{
|
||||
|
@ -5,12 +5,14 @@
|
||||
package modcmd
|
||||
|
||||
import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/work"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/work"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
var cmdWhy = &base.Command{
|
||||
|
@ -13,10 +13,11 @@ import (
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/modfetch"
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/par"
|
||||
"cmd/go/internal/semver"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
// ConvertLegacyConfig converts legacy config to modfile.
|
||||
|
@ -19,8 +19,9 @@ import (
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/modfetch"
|
||||
"cmd/go/internal/modfetch/codehost"
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
@ -12,9 +12,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/semver"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
func ParseGopkgLock(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -7,8 +7,8 @@ package modconv
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func ParseGlideLock(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -7,8 +7,8 @@ package modconv
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func ParseGLOCKFILE(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -7,8 +7,8 @@ package modconv
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func ParseGodepsJSON(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
package modconv
|
||||
|
||||
import "cmd/go/internal/modfile"
|
||||
import "golang.org/x/mod/modfile"
|
||||
|
||||
var Converters = map[string]func(string, []byte) (*modfile.File, error){
|
||||
"GLOCKFILE": ParseGLOCKFILE,
|
||||
|
@ -7,8 +7,8 @@ package modconv
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func ParseDependenciesTSV(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -7,8 +7,8 @@ package modconv
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func ParseVendorConf(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -7,8 +7,8 @@ package modconv
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func ParseVendorJSON(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -7,8 +7,8 @@ package modconv
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func ParseVendorManifest(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -7,8 +7,8 @@ package modconv
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
|
||||
func ParseVendorYML(file string, data []byte) (*modfile.File, error) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
package modfetch
|
||||
|
||||
import "cmd/go/internal/module"
|
||||
import "golang.org/x/mod/module"
|
||||
|
||||
func useSumDB(mod module.Version) bool {
|
||||
return false
|
||||
|
@ -18,10 +18,11 @@ import (
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/lockedfile"
|
||||
"cmd/go/internal/modfetch/codehost"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/par"
|
||||
"cmd/go/internal/renameio"
|
||||
"cmd/go/internal/semver"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
var QuietLookup bool // do not print about lookups
|
||||
|
@ -22,8 +22,9 @@ import (
|
||||
|
||||
"cmd/go/internal/lockedfile"
|
||||
"cmd/go/internal/par"
|
||||
"cmd/go/internal/semver"
|
||||
"cmd/go/internal/web"
|
||||
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
// GitRepo returns the code repository at the given Git remote reference.
|
||||
|
154
src/cmd/go/internal/modfetch/codehost/svn.go
Normal file
154
src/cmd/go/internal/modfetch/codehost/svn.go
Normal file
@ -0,0 +1,154 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package codehost
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
func svnParseStat(rev, out string) (*RevInfo, error) {
|
||||
var log struct {
|
||||
Logentry struct {
|
||||
Revision int64 `xml:"revision,attr"`
|
||||
Date string `xml:"date"`
|
||||
} `xml:"logentry"`
|
||||
}
|
||||
if err := xml.Unmarshal([]byte(out), &log); err != nil {
|
||||
return nil, vcsErrorf("unexpected response from svn log --xml: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339, log.Logentry.Date)
|
||||
if err != nil {
|
||||
return nil, vcsErrorf("unexpected response from svn log --xml: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
info := &RevInfo{
|
||||
Name: fmt.Sprintf("%d", log.Logentry.Revision),
|
||||
Short: fmt.Sprintf("%012d", log.Logentry.Revision),
|
||||
Time: t.UTC(),
|
||||
Version: rev,
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func svnReadZip(dst io.Writer, workDir, rev, subdir, remote string) (err error) {
|
||||
// The subversion CLI doesn't provide a command to write the repository
|
||||
// directly to an archive, so we need to export it to the local filesystem
|
||||
// instead. Unfortunately, the local filesystem might apply arbitrary
|
||||
// normalization to the filenames, so we need to obtain those directly.
|
||||
//
|
||||
// 'svn export' prints the filenames as they are written, but from reading the
|
||||
// svn source code (as of revision 1868933), those filenames are encoded using
|
||||
// the system locale rather than preserved byte-for-byte from the origin. For
|
||||
// our purposes, that won't do, but we don't want to go mucking around with
|
||||
// the user's locale settings either — that could impact error messages, and
|
||||
// we don't know what locales the user has available or what LC_* variables
|
||||
// their platform supports.
|
||||
//
|
||||
// Instead, we'll do a two-pass export: first we'll run 'svn list' to get the
|
||||
// canonical filenames, then we'll 'svn export' and look for those filenames
|
||||
// in the local filesystem. (If there is an encoding problem at that point, we
|
||||
// would probably reject the resulting module anyway.)
|
||||
|
||||
remotePath := remote
|
||||
if subdir != "" {
|
||||
remotePath += "/" + subdir
|
||||
}
|
||||
|
||||
out, err := Run(workDir, []string{
|
||||
"svn", "list",
|
||||
"--non-interactive",
|
||||
"--xml",
|
||||
"--incremental",
|
||||
"--recursive",
|
||||
"--revision", rev,
|
||||
"--", remotePath,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type listEntry struct {
|
||||
Kind string `xml:"kind,attr"`
|
||||
Name string `xml:"name"`
|
||||
Size int64 `xml:"size"`
|
||||
}
|
||||
var list struct {
|
||||
Entries []listEntry `xml:"entry"`
|
||||
}
|
||||
if err := xml.Unmarshal(out, &list); err != nil {
|
||||
return vcsErrorf("unexpected response from svn list --xml: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
exportDir := filepath.Join(workDir, "export")
|
||||
// Remove any existing contents from a previous (failed) run.
|
||||
if err := os.RemoveAll(exportDir); err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(exportDir) // best-effort
|
||||
|
||||
_, err = Run(workDir, []string{
|
||||
"svn", "export",
|
||||
"--non-interactive",
|
||||
"--quiet",
|
||||
|
||||
// Suppress any platform- or host-dependent transformations.
|
||||
"--native-eol", "LF",
|
||||
"--ignore-externals",
|
||||
"--ignore-keywords",
|
||||
|
||||
"--revision", rev,
|
||||
"--", remotePath,
|
||||
exportDir,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Scrape the exported files out of the filesystem and encode them in the zipfile.
|
||||
|
||||
// “All files in the zip file are expected to be
|
||||
// nested in a single top-level directory, whose name is not specified.”
|
||||
// We'll (arbitrarily) choose the base of the remote path.
|
||||
basePath := path.Join(path.Base(remote), subdir)
|
||||
|
||||
zw := zip.NewWriter(dst)
|
||||
for _, e := range list.Entries {
|
||||
if e.Kind != "file" {
|
||||
continue
|
||||
}
|
||||
|
||||
zf, err := zw.Create(path.Join(basePath, e.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Open(filepath.Join(exportDir, e.Name))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return vcsErrorf("file reported by 'svn list', but not written by 'svn export': %s", e.Name)
|
||||
}
|
||||
return fmt.Errorf("error opening file created by 'svn export': %v", err)
|
||||
}
|
||||
|
||||
n, err := io.Copy(zf, f)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != e.Size {
|
||||
return vcsErrorf("file size differs between 'svn list' and 'svn export': file %s listed as %v bytes, but exported as %v bytes", e.Name, e.Size, n)
|
||||
}
|
||||
}
|
||||
|
||||
return zw.Close()
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
package codehost
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"internal/lazyregexp"
|
||||
"io"
|
||||
@ -122,19 +122,20 @@ func newVCSRepo(vcs, remote string) (Repo, error) {
|
||||
const vcsWorkDirType = "vcs1."
|
||||
|
||||
type vcsCmd struct {
|
||||
vcs string // vcs name "hg"
|
||||
init func(remote string) []string // cmd to init repo to track remote
|
||||
tags func(remote string) []string // cmd to list local tags
|
||||
tagRE *lazyregexp.Regexp // regexp to extract tag names from output of tags cmd
|
||||
branches func(remote string) []string // cmd to list local branches
|
||||
branchRE *lazyregexp.Regexp // regexp to extract branch names from output of tags cmd
|
||||
badLocalRevRE *lazyregexp.Regexp // regexp of names that must not be served out of local cache without doing fetch first
|
||||
statLocal func(rev, remote string) []string // cmd to stat local rev
|
||||
parseStat func(rev, out string) (*RevInfo, error) // cmd to parse output of statLocal
|
||||
fetch []string // cmd to fetch everything from remote
|
||||
latest string // name of latest commit on remote (tip, HEAD, etc)
|
||||
readFile func(rev, file, remote string) []string // cmd to read rev's file
|
||||
readZip func(rev, subdir, remote, target string) []string // cmd to read rev's subdir as zip file
|
||||
vcs string // vcs name "hg"
|
||||
init func(remote string) []string // cmd to init repo to track remote
|
||||
tags func(remote string) []string // cmd to list local tags
|
||||
tagRE *lazyregexp.Regexp // regexp to extract tag names from output of tags cmd
|
||||
branches func(remote string) []string // cmd to list local branches
|
||||
branchRE *lazyregexp.Regexp // regexp to extract branch names from output of tags cmd
|
||||
badLocalRevRE *lazyregexp.Regexp // regexp of names that must not be served out of local cache without doing fetch first
|
||||
statLocal func(rev, remote string) []string // cmd to stat local rev
|
||||
parseStat func(rev, out string) (*RevInfo, error) // cmd to parse output of statLocal
|
||||
fetch []string // cmd to fetch everything from remote
|
||||
latest string // name of latest commit on remote (tip, HEAD, etc)
|
||||
readFile func(rev, file, remote string) []string // cmd to read rev's file
|
||||
readZip func(rev, subdir, remote, target string) []string // cmd to read rev's subdir as zip file
|
||||
doReadZip func(dst io.Writer, workDir, rev, subdir, remote string) error // arbitrary function to read rev's subdir as zip file
|
||||
}
|
||||
|
||||
var re = lazyregexp.New
|
||||
@ -191,7 +192,7 @@ var vcsCmds = map[string]*vcsCmd{
|
||||
readFile: func(rev, file, remote string) []string {
|
||||
return []string{"svn", "cat", "--", remote + "/" + file + "@" + rev}
|
||||
},
|
||||
// TODO: zip
|
||||
doReadZip: svnReadZip,
|
||||
},
|
||||
|
||||
"bzr": {
|
||||
@ -418,7 +419,7 @@ func (r *vcsRepo) DescendsFrom(rev, tag string) (bool, error) {
|
||||
}
|
||||
|
||||
func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, err error) {
|
||||
if r.cmd.readZip == nil {
|
||||
if r.cmd.readZip == nil && r.cmd.doReadZip == nil {
|
||||
return nil, vcsErrorf("ReadZip not implemented for %s", r.cmd.vcs)
|
||||
}
|
||||
|
||||
@ -435,7 +436,17 @@ func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if r.cmd.vcs == "fossil" {
|
||||
if r.cmd.doReadZip != nil {
|
||||
lw := &limitedWriter{
|
||||
W: f,
|
||||
N: maxSize,
|
||||
ErrLimitReached: errors.New("ReadZip: encoded file exceeds allowed size"),
|
||||
}
|
||||
err = r.cmd.doReadZip(lw, r.dir, rev, subdir, r.remote)
|
||||
if err == nil {
|
||||
_, err = f.Seek(0, io.SeekStart)
|
||||
}
|
||||
} else if r.cmd.vcs == "fossil" {
|
||||
// If you run
|
||||
// fossil zip -R .fossil --name prefix trunk /tmp/x.zip
|
||||
// fossil fails with "unable to create directory /tmp" [sic].
|
||||
@ -502,31 +513,6 @@ func hgParseStat(rev, out string) (*RevInfo, error) {
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func svnParseStat(rev, out string) (*RevInfo, error) {
|
||||
var log struct {
|
||||
Logentry struct {
|
||||
Revision int64 `xml:"revision,attr"`
|
||||
Date string `xml:"date"`
|
||||
} `xml:"logentry"`
|
||||
}
|
||||
if err := xml.Unmarshal([]byte(out), &log); err != nil {
|
||||
return nil, vcsErrorf("unexpected response from svn log --xml: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339, log.Logentry.Date)
|
||||
if err != nil {
|
||||
return nil, vcsErrorf("unexpected response from svn log --xml: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
info := &RevInfo{
|
||||
Name: fmt.Sprintf("%d", log.Logentry.Revision),
|
||||
Short: fmt.Sprintf("%012d", log.Logentry.Revision),
|
||||
Time: t.UTC(),
|
||||
Version: rev,
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func bzrParseStat(rev, out string) (*RevInfo, error) {
|
||||
var revno int64
|
||||
var tm time.Time
|
||||
@ -606,3 +592,25 @@ func fossilParseStat(rev, out string) (*RevInfo, error) {
|
||||
}
|
||||
return nil, vcsErrorf("unexpected response from fossil info: %q", out)
|
||||
}
|
||||
|
||||
type limitedWriter struct {
|
||||
W io.Writer
|
||||
N int64
|
||||
ErrLimitReached error
|
||||
}
|
||||
|
||||
func (l *limitedWriter) Write(p []byte) (n int, err error) {
|
||||
if l.N > 0 {
|
||||
max := len(p)
|
||||
if l.N < int64(max) {
|
||||
max = int(l.N)
|
||||
}
|
||||
n, err = l.W.Write(p[:max])
|
||||
l.N -= int64(n)
|
||||
if err != nil || n >= len(p) {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
return n, l.ErrLimitReached
|
||||
}
|
||||
|
@ -16,9 +16,10 @@ import (
|
||||
"time"
|
||||
|
||||
"cmd/go/internal/modfetch/codehost"
|
||||
"cmd/go/internal/modfile"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/semver"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
// A codeRepo implements modfetch.Repo using an underlying codehost.Repo.
|
||||
|
@ -6,7 +6,11 @@ package modfetch
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"hash"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
@ -17,6 +21,8 @@ import (
|
||||
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/modfetch/codehost"
|
||||
|
||||
"golang.org/x/mod/sumdb/dirhash"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@ -52,20 +58,22 @@ var altVgotests = map[string]string{
|
||||
}
|
||||
|
||||
type codeRepoTest struct {
|
||||
vcs string
|
||||
path string
|
||||
lookerr string
|
||||
mpath string
|
||||
rev string
|
||||
err string
|
||||
version string
|
||||
name string
|
||||
short string
|
||||
time time.Time
|
||||
gomod string
|
||||
gomoderr string
|
||||
zip []string
|
||||
ziperr string
|
||||
vcs string
|
||||
path string
|
||||
lookErr string
|
||||
mpath string
|
||||
rev string
|
||||
err string
|
||||
version string
|
||||
name string
|
||||
short string
|
||||
time time.Time
|
||||
gomod string
|
||||
gomodErr string
|
||||
zip []string
|
||||
zipErr string
|
||||
zipSum string
|
||||
zipFileHash string
|
||||
}
|
||||
|
||||
var codeRepoTests = []codeRepoTest{
|
||||
@ -82,6 +90,8 @@ var codeRepoTests = []codeRepoTest{
|
||||
"README.md",
|
||||
"pkg/p.go",
|
||||
},
|
||||
zipSum: "h1:zVEjciLdlk/TPWCOyZo7k24T+tOKRQC+u8MKq/xS80I=",
|
||||
zipFileHash: "738a00ddbfe8c329dce6b48e1f23c8e22a92db50f3cfb2653caa0d62676bc09c",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
@ -96,6 +106,8 @@ var codeRepoTests = []codeRepoTest{
|
||||
"README.md",
|
||||
"pkg/p.go",
|
||||
},
|
||||
zipSum: "h1:nOznk2xKsLGkTnXe0q9t1Ewt9jxK+oadtafSUqHM3Ec=",
|
||||
zipFileHash: "bacb08f391e29d2eaaef8281b5c129ee6d890e608ee65877e0003c0181a766c8",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
@ -116,6 +128,8 @@ var codeRepoTests = []codeRepoTest{
|
||||
"README.md",
|
||||
"pkg/p.go",
|
||||
},
|
||||
zipSum: "h1:e040hOoWGeuJLawDjK9DW6med+cz9FxMFYDMOVG8ctQ=",
|
||||
zipFileHash: "74caab65cfbea427c341fa815f3bb0378681d8f0e3cf62a7f207014263ec7be3",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
@ -140,6 +154,8 @@ var codeRepoTests = []codeRepoTest{
|
||||
"README.md",
|
||||
"pkg/p.go",
|
||||
},
|
||||
zipSum: "h1:e040hOoWGeuJLawDjK9DW6med+cz9FxMFYDMOVG8ctQ=",
|
||||
zipFileHash: "74caab65cfbea427c341fa815f3bb0378681d8f0e3cf62a7f207014263ec7be3",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
@ -201,6 +217,8 @@ var codeRepoTests = []codeRepoTest{
|
||||
"pkg/p.go",
|
||||
"LICENSE",
|
||||
},
|
||||
zipSum: "h1:iMsJ/9uQsk6MnZNnJK311f11QiSlmN92Q2aSjCywuJY=",
|
||||
zipFileHash: "95801bfa69c5197ae809af512946d22f22850068527cd78100ae3f176bc8043b",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
@ -217,16 +235,20 @@ var codeRepoTests = []codeRepoTest{
|
||||
"go.mod",
|
||||
"pkg/p.go",
|
||||
},
|
||||
zipSum: "h1:M69k7q+8bQ+QUpHov45Z/NoR8rj3DsQJUnXLWvf01+Q=",
|
||||
zipFileHash: "58af45fb248d320ea471f568e006379e2b8d71d6d1663f9b19b2e00fd9ac9265",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "github.com/rsc/vgotest1/v2",
|
||||
rev: "v2.0.1",
|
||||
version: "v2.0.1",
|
||||
name: "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9",
|
||||
short: "ea65f87c8f52",
|
||||
time: time.Date(2018, 2, 19, 23, 14, 23, 0, time.UTC),
|
||||
gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n",
|
||||
vcs: "git",
|
||||
path: "github.com/rsc/vgotest1/v2",
|
||||
rev: "v2.0.1",
|
||||
version: "v2.0.1",
|
||||
name: "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9",
|
||||
short: "ea65f87c8f52",
|
||||
time: time.Date(2018, 2, 19, 23, 14, 23, 0, time.UTC),
|
||||
gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n",
|
||||
zipSum: "h1:QmgYy/zt+uoWhDpcsgrSVzYFvKtBEjl5zT/FRz9GTzA=",
|
||||
zipFileHash: "1aedf1546d322a0121879ddfd6d0e8bfbd916d2cafbeb538ddb440e04b04b9ef",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
@ -249,25 +271,29 @@ var codeRepoTests = []codeRepoTest{
|
||||
err: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "github.com/rsc/vgotest1/v2",
|
||||
rev: "v2.0.5",
|
||||
version: "v2.0.5",
|
||||
name: "2f615117ce481c8efef46e0cc0b4b4dccfac8fea",
|
||||
short: "2f615117ce48",
|
||||
time: time.Date(2018, 2, 20, 0, 3, 59, 0, time.UTC),
|
||||
gomod: "module \"github.com/rsc/vgotest1/v2\" // v2/go.mod\n",
|
||||
vcs: "git",
|
||||
path: "github.com/rsc/vgotest1/v2",
|
||||
rev: "v2.0.5",
|
||||
version: "v2.0.5",
|
||||
name: "2f615117ce481c8efef46e0cc0b4b4dccfac8fea",
|
||||
short: "2f615117ce48",
|
||||
time: time.Date(2018, 2, 20, 0, 3, 59, 0, time.UTC),
|
||||
gomod: "module \"github.com/rsc/vgotest1/v2\" // v2/go.mod\n",
|
||||
zipSum: "h1:RIEb9q1SUSEQOzMn0zfl/LQxGFWlhWEAdeEguf1MLGU=",
|
||||
zipFileHash: "7d92c2c328c5e9b0694101353705d5843746ec1d93a1e986d0da54c8a14dfe6d",
|
||||
},
|
||||
{
|
||||
// redirect to github
|
||||
vcs: "git",
|
||||
path: "rsc.io/quote",
|
||||
rev: "v1.0.0",
|
||||
version: "v1.0.0",
|
||||
name: "f488df80bcdbd3e5bafdc24ad7d1e79e83edd7e6",
|
||||
short: "f488df80bcdb",
|
||||
time: time.Date(2018, 2, 14, 0, 45, 20, 0, time.UTC),
|
||||
gomod: "module \"rsc.io/quote\"\n",
|
||||
vcs: "git",
|
||||
path: "rsc.io/quote",
|
||||
rev: "v1.0.0",
|
||||
version: "v1.0.0",
|
||||
name: "f488df80bcdbd3e5bafdc24ad7d1e79e83edd7e6",
|
||||
short: "f488df80bcdb",
|
||||
time: time.Date(2018, 2, 14, 0, 45, 20, 0, time.UTC),
|
||||
gomod: "module \"rsc.io/quote\"\n",
|
||||
zipSum: "h1:haUSojyo3j2M9g7CEUFG8Na09dtn7QKxvPGaPVQdGwM=",
|
||||
zipFileHash: "5c08ba2c09a364f93704aaa780e7504346102c6ef4fe1333a11f09904a732078",
|
||||
},
|
||||
{
|
||||
// redirect to static hosting proxy
|
||||
@ -281,22 +307,26 @@ var codeRepoTests = []codeRepoTest{
|
||||
},
|
||||
{
|
||||
// redirect to googlesource
|
||||
vcs: "git",
|
||||
path: "golang.org/x/text",
|
||||
rev: "4e4a3210bb",
|
||||
version: "v0.3.1-0.20180208041248-4e4a3210bb54",
|
||||
name: "4e4a3210bb54bb31f6ab2cdca2edcc0b50c420c1",
|
||||
short: "4e4a3210bb54",
|
||||
time: time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC),
|
||||
vcs: "git",
|
||||
path: "golang.org/x/text",
|
||||
rev: "4e4a3210bb",
|
||||
version: "v0.3.1-0.20180208041248-4e4a3210bb54",
|
||||
name: "4e4a3210bb54bb31f6ab2cdca2edcc0b50c420c1",
|
||||
short: "4e4a3210bb54",
|
||||
time: time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC),
|
||||
zipSum: "h1:Yxu6pHX9X2RECiuw/Q5/4uvajuaowck8zOFKXgbfNBk=",
|
||||
zipFileHash: "ac2c165a5c10aa5a7545dea60a08e019270b982fa6c8bdcb5943931de64922fe",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "github.com/pkg/errors",
|
||||
rev: "v0.8.0",
|
||||
version: "v0.8.0",
|
||||
name: "645ef00459ed84a119197bfb8d8205042c6df63d",
|
||||
short: "645ef00459ed",
|
||||
time: time.Date(2016, 9, 29, 1, 48, 1, 0, time.UTC),
|
||||
vcs: "git",
|
||||
path: "github.com/pkg/errors",
|
||||
rev: "v0.8.0",
|
||||
version: "v0.8.0",
|
||||
name: "645ef00459ed84a119197bfb8d8205042c6df63d",
|
||||
short: "645ef00459ed",
|
||||
time: time.Date(2016, 9, 29, 1, 48, 1, 0, time.UTC),
|
||||
zipSum: "h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=",
|
||||
zipFileHash: "e4fa69ba057356614edbc1da881a7d3ebb688505be49f65965686bcb859e2fae",
|
||||
},
|
||||
{
|
||||
// package in subdirectory - custom domain
|
||||
@ -304,7 +334,7 @@ var codeRepoTests = []codeRepoTest{
|
||||
// but gopkg.in is special.
|
||||
vcs: "git",
|
||||
path: "gopkg.in/yaml.v2/abc",
|
||||
lookerr: "invalid module path \"gopkg.in/yaml.v2/abc\"",
|
||||
lookErr: "invalid module path \"gopkg.in/yaml.v2/abc\"",
|
||||
},
|
||||
{
|
||||
// package in subdirectory - github
|
||||
@ -315,54 +345,64 @@ var codeRepoTests = []codeRepoTest{
|
||||
err: "missing github.com/rsc/quote/buggy/go.mod at revision c4d4236f9242",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "gopkg.in/yaml.v2",
|
||||
rev: "d670f940",
|
||||
version: "v2.0.0",
|
||||
name: "d670f9405373e636a5a2765eea47fac0c9bc91a4",
|
||||
short: "d670f9405373",
|
||||
time: time.Date(2018, 1, 9, 11, 43, 31, 0, time.UTC),
|
||||
gomod: "module gopkg.in/yaml.v2\n",
|
||||
vcs: "git",
|
||||
path: "gopkg.in/yaml.v2",
|
||||
rev: "d670f940",
|
||||
version: "v2.0.0",
|
||||
name: "d670f9405373e636a5a2765eea47fac0c9bc91a4",
|
||||
short: "d670f9405373",
|
||||
time: time.Date(2018, 1, 9, 11, 43, 31, 0, time.UTC),
|
||||
gomod: "module gopkg.in/yaml.v2\n",
|
||||
zipSum: "h1:uUkhRGrsEyx/laRdeS6YIQKIys8pg+lRSRdVMTYjivs=",
|
||||
zipFileHash: "7b0a141b1b0b49772ab4eecfd11dfd6609a94a5e868cab04a3abb1861ffaa877",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "gopkg.in/check.v1",
|
||||
rev: "20d25e280405",
|
||||
version: "v1.0.0-20161208181325-20d25e280405",
|
||||
name: "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec",
|
||||
short: "20d25e280405",
|
||||
time: time.Date(2016, 12, 8, 18, 13, 25, 0, time.UTC),
|
||||
gomod: "module gopkg.in/check.v1\n",
|
||||
vcs: "git",
|
||||
path: "gopkg.in/check.v1",
|
||||
rev: "20d25e280405",
|
||||
version: "v1.0.0-20161208181325-20d25e280405",
|
||||
name: "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec",
|
||||
short: "20d25e280405",
|
||||
time: time.Date(2016, 12, 8, 18, 13, 25, 0, time.UTC),
|
||||
gomod: "module gopkg.in/check.v1\n",
|
||||
zipSum: "h1:829vOVxxusYHC+IqBtkX5mbKtsY9fheQiQn0MZRVLfQ=",
|
||||
zipFileHash: "9e7cb3f4f1e66d722306442b0dbe1f6f43d74d1736d54c510537bdfb1d6f432f",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "gopkg.in/yaml.v2",
|
||||
rev: "v2",
|
||||
version: "v2.2.5-0.20191002202810-970885f01c8b",
|
||||
name: "970885f01c8bc1fecb7ab1c8ce8e7609bda45530",
|
||||
short: "970885f01c8b",
|
||||
time: time.Date(2019, 10, 2, 20, 28, 10, 0, time.UTC),
|
||||
gomod: "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n",
|
||||
vcs: "git",
|
||||
path: "gopkg.in/yaml.v2",
|
||||
rev: "v2",
|
||||
version: "v2.2.5-0.20191002202810-970885f01c8b",
|
||||
name: "970885f01c8bc1fecb7ab1c8ce8e7609bda45530",
|
||||
short: "970885f01c8b",
|
||||
time: time.Date(2019, 10, 2, 20, 28, 10, 0, time.UTC),
|
||||
gomod: "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n",
|
||||
zipSum: "h1:c7zdkYUaqShimBvZzvhOA+Absl0aDaGKX267vSm0Z7E=",
|
||||
zipFileHash: "5856a108e1aa8ec9c35f4479f8e806652b326b648c80abd08fc403707f4eb5f1",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "vcs-test.golang.org/go/mod/gitrepo1",
|
||||
rev: "master",
|
||||
version: "v1.2.4-annotated",
|
||||
name: "ede458df7cd0fdca520df19a33158086a8a68e81",
|
||||
short: "ede458df7cd0",
|
||||
time: time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
|
||||
gomod: "module vcs-test.golang.org/go/mod/gitrepo1\n",
|
||||
vcs: "git",
|
||||
path: "vcs-test.golang.org/go/mod/gitrepo1",
|
||||
rev: "master",
|
||||
version: "v1.2.4-annotated",
|
||||
name: "ede458df7cd0fdca520df19a33158086a8a68e81",
|
||||
short: "ede458df7cd0",
|
||||
time: time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
|
||||
gomod: "module vcs-test.golang.org/go/mod/gitrepo1\n",
|
||||
zipSum: "h1:YJYZRsM9BHFTlVr8YADjT0cJH8uFIDtoc5NLiVqZEx8=",
|
||||
zipFileHash: "c15e49d58b7a4c37966cbe5bc01a0330cd5f2927e990e1839bda1d407766d9c5",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "gopkg.in/natefinch/lumberjack.v2",
|
||||
rev: "latest",
|
||||
version: "v2.0.0-20170531160350-a96e63847dc3",
|
||||
name: "a96e63847dc3c67d17befa69c303767e2f84e54f",
|
||||
short: "a96e63847dc3",
|
||||
time: time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC),
|
||||
gomod: "module gopkg.in/natefinch/lumberjack.v2\n",
|
||||
vcs: "git",
|
||||
path: "gopkg.in/natefinch/lumberjack.v2",
|
||||
rev: "latest",
|
||||
version: "v2.0.0-20170531160350-a96e63847dc3",
|
||||
name: "a96e63847dc3c67d17befa69c303767e2f84e54f",
|
||||
short: "a96e63847dc3",
|
||||
time: time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC),
|
||||
gomod: "module gopkg.in/natefinch/lumberjack.v2\n",
|
||||
zipSum: "h1:AFxeG48hTWHhDTQDk/m2gorfVHUEa9vo3tp3D7TzwjI=",
|
||||
zipFileHash: "b5de0da7bbbec76709eef1ac71b6c9ff423b9fbf3bb97b56743450d4937b06d5",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
@ -381,14 +421,16 @@ var codeRepoTests = []codeRepoTest{
|
||||
gomod: "module gopkg.in/natefinch/lumberjack.v2\n",
|
||||
},
|
||||
{
|
||||
vcs: "git",
|
||||
path: "vcs-test.golang.org/go/v2module/v2",
|
||||
rev: "v2.0.0",
|
||||
version: "v2.0.0",
|
||||
name: "203b91c896acd173aa719e4cdcb7d463c4b090fa",
|
||||
short: "203b91c896ac",
|
||||
time: time.Date(2019, 4, 3, 15, 52, 15, 0, time.UTC),
|
||||
gomod: "module vcs-test.golang.org/go/v2module/v2\n\ngo 1.12\n",
|
||||
vcs: "git",
|
||||
path: "vcs-test.golang.org/go/v2module/v2",
|
||||
rev: "v2.0.0",
|
||||
version: "v2.0.0",
|
||||
name: "203b91c896acd173aa719e4cdcb7d463c4b090fa",
|
||||
short: "203b91c896ac",
|
||||
time: time.Date(2019, 4, 3, 15, 52, 15, 0, time.UTC),
|
||||
gomod: "module vcs-test.golang.org/go/v2module/v2\n\ngo 1.12\n",
|
||||
zipSum: "h1:JItBZ+gwA5WvtZEGEbuDL4lUttGtLrs53lmdurq3bOg=",
|
||||
zipFileHash: "9ea9ae1673cffcc44b7fdd3cc89953d68c102449b46c982dbf085e4f2e394da5",
|
||||
},
|
||||
}
|
||||
|
||||
@ -411,21 +453,23 @@ func TestCodeRepo(t *testing.T) {
|
||||
}
|
||||
|
||||
repo, err := Lookup("direct", tt.path)
|
||||
if tt.lookerr != "" {
|
||||
if err != nil && err.Error() == tt.lookerr {
|
||||
if tt.lookErr != "" {
|
||||
if err != nil && err.Error() == tt.lookErr {
|
||||
return
|
||||
}
|
||||
t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookerr)
|
||||
t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookErr)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("Lookup(%q): %v", tt.path, err)
|
||||
}
|
||||
|
||||
if tt.mpath == "" {
|
||||
tt.mpath = tt.path
|
||||
}
|
||||
if mpath := repo.ModulePath(); mpath != tt.mpath {
|
||||
t.Errorf("repo.ModulePath() = %q, want %q", mpath, tt.mpath)
|
||||
}
|
||||
|
||||
info, err := repo.Stat(tt.rev)
|
||||
if err != nil {
|
||||
if tt.err != "" {
|
||||
@ -451,56 +495,86 @@ func TestCodeRepo(t *testing.T) {
|
||||
if !info.Time.Equal(tt.time) {
|
||||
t.Errorf("info.Time = %v, want %v", info.Time, tt.time)
|
||||
}
|
||||
if tt.gomod != "" || tt.gomoderr != "" {
|
||||
|
||||
if tt.gomod != "" || tt.gomodErr != "" {
|
||||
data, err := repo.GoMod(tt.version)
|
||||
if err != nil && tt.gomoderr == "" {
|
||||
if err != nil && tt.gomodErr == "" {
|
||||
t.Errorf("repo.GoMod(%q): %v", tt.version, err)
|
||||
} else if err != nil && tt.gomoderr != "" {
|
||||
if err.Error() != tt.gomoderr {
|
||||
t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomoderr)
|
||||
} else if err != nil && tt.gomodErr != "" {
|
||||
if err.Error() != tt.gomodErr {
|
||||
t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomodErr)
|
||||
}
|
||||
} else if tt.gomoderr != "" {
|
||||
t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomoderr)
|
||||
} else if tt.gomodErr != "" {
|
||||
t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomodErr)
|
||||
} else if string(data) != tt.gomod {
|
||||
t.Errorf("repo.GoMod(%q) = %q, want %q", tt.version, data, tt.gomod)
|
||||
}
|
||||
}
|
||||
if tt.zip != nil || tt.ziperr != "" {
|
||||
|
||||
needHash := !testing.Short() && (tt.zipFileHash != "" || tt.zipSum != "")
|
||||
if tt.zip != nil || tt.zipErr != "" || needHash {
|
||||
f, err := ioutil.TempFile(tmpdir, tt.version+".zip.")
|
||||
if err != nil {
|
||||
t.Fatalf("ioutil.TempFile: %v", err)
|
||||
}
|
||||
zipfile := f.Name()
|
||||
err = repo.Zip(f, tt.version)
|
||||
defer func() {
|
||||
f.Close()
|
||||
os.Remove(zipfile)
|
||||
}()
|
||||
|
||||
var w io.Writer
|
||||
var h hash.Hash
|
||||
if needHash {
|
||||
h = sha256.New()
|
||||
w = io.MultiWriter(f, h)
|
||||
} else {
|
||||
w = f
|
||||
}
|
||||
err = repo.Zip(w, tt.version)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
if tt.ziperr != "" {
|
||||
if err.Error() == tt.ziperr {
|
||||
if tt.zipErr != "" {
|
||||
if err.Error() == tt.zipErr {
|
||||
return
|
||||
}
|
||||
t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.ziperr)
|
||||
t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.zipErr)
|
||||
}
|
||||
t.Fatalf("repo.Zip(%q): %v", tt.version, err)
|
||||
}
|
||||
if tt.ziperr != "" {
|
||||
t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.ziperr)
|
||||
if tt.zipErr != "" {
|
||||
t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.zipErr)
|
||||
}
|
||||
prefix := tt.path + "@" + tt.version + "/"
|
||||
z, err := zip.OpenReader(zipfile)
|
||||
if err != nil {
|
||||
t.Fatalf("open zip %s: %v", zipfile, err)
|
||||
}
|
||||
var names []string
|
||||
for _, file := range z.File {
|
||||
if !strings.HasPrefix(file.Name, prefix) {
|
||||
t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix)
|
||||
continue
|
||||
|
||||
if tt.zip != nil {
|
||||
prefix := tt.path + "@" + tt.version + "/"
|
||||
z, err := zip.OpenReader(zipfile)
|
||||
if err != nil {
|
||||
t.Fatalf("open zip %s: %v", zipfile, err)
|
||||
}
|
||||
var names []string
|
||||
for _, file := range z.File {
|
||||
if !strings.HasPrefix(file.Name, prefix) {
|
||||
t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix)
|
||||
continue
|
||||
}
|
||||
names = append(names, file.Name[len(prefix):])
|
||||
}
|
||||
z.Close()
|
||||
if !reflect.DeepEqual(names, tt.zip) {
|
||||
t.Fatalf("zip = %v\nwant %v\n", names, tt.zip)
|
||||
}
|
||||
names = append(names, file.Name[len(prefix):])
|
||||
}
|
||||
z.Close()
|
||||
if !reflect.DeepEqual(names, tt.zip) {
|
||||
t.Fatalf("zip = %v\nwant %v\n", names, tt.zip)
|
||||
|
||||
if needHash {
|
||||
sum, err := dirhash.HashZip(zipfile, dirhash.Hash1)
|
||||
if err != nil {
|
||||
t.Errorf("repo.Zip(%q): %v", tt.version, err)
|
||||
} else if sum != tt.zipSum {
|
||||
t.Errorf("repo.Zip(%q): got file with sum %q, want %q", tt.version, sum, tt.zipSum)
|
||||
} else if zipFileHash := hex.EncodeToString(h.Sum(nil)); zipFileHash != tt.zipFileHash {
|
||||
t.Errorf("repo.Zip(%q): got file with hash %q, want %q (but content has correct sum)", tt.version, zipFileHash, tt.zipFileHash)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -508,26 +582,26 @@ func TestCodeRepo(t *testing.T) {
|
||||
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt))
|
||||
if strings.HasPrefix(tt.path, vgotest1git) {
|
||||
for vcs, alt := range altVgotests {
|
||||
// Note: Communicating with f through tt; should be cleaned up.
|
||||
old := tt
|
||||
tt.vcs = vcs
|
||||
tt.path = alt + strings.TrimPrefix(tt.path, vgotest1git)
|
||||
if strings.HasPrefix(tt.mpath, vgotest1git) {
|
||||
tt.mpath = alt + strings.TrimPrefix(tt.mpath, vgotest1git)
|
||||
altTest := tt
|
||||
altTest.vcs = vcs
|
||||
altTest.path = alt + strings.TrimPrefix(altTest.path, vgotest1git)
|
||||
if strings.HasPrefix(altTest.mpath, vgotest1git) {
|
||||
altTest.mpath = alt + strings.TrimPrefix(altTest.mpath, vgotest1git)
|
||||
}
|
||||
var m map[string]string
|
||||
if alt == vgotest1hg {
|
||||
m = hgmap
|
||||
}
|
||||
tt.version = remap(tt.version, m)
|
||||
tt.name = remap(tt.name, m)
|
||||
tt.short = remap(tt.short, m)
|
||||
tt.rev = remap(tt.rev, m)
|
||||
tt.err = remap(tt.err, m)
|
||||
tt.gomoderr = remap(tt.gomoderr, m)
|
||||
tt.ziperr = remap(tt.ziperr, m)
|
||||
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt))
|
||||
tt = old
|
||||
altTest.version = remap(altTest.version, m)
|
||||
altTest.name = remap(altTest.name, m)
|
||||
altTest.short = remap(altTest.short, m)
|
||||
altTest.rev = remap(altTest.rev, m)
|
||||
altTest.err = remap(altTest.err, m)
|
||||
altTest.gomodErr = remap(altTest.gomodErr, m)
|
||||
altTest.zipErr = remap(altTest.zipErr, m)
|
||||
altTest.zipSum = ""
|
||||
altTest.zipFileHash = ""
|
||||
t.Run(strings.ReplaceAll(altTest.path, "/", "_")+"/"+altTest.rev, f(altTest))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,11 @@ import (
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/dirhash"
|
||||
"cmd/go/internal/module"
|
||||
"cmd/go/internal/par"
|
||||
"cmd/go/internal/renameio"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/sumdb/dirhash"
|
||||
)
|
||||
|
||||
var downloadCache par.Cache
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user