Compare commits
10 Commits
97d6430458
...
e3fbb58954
| Author | SHA1 | Date | |
|---|---|---|---|
| e3fbb58954 | |||
|
|
26d5e16075 | ||
|
|
6b7763407c | ||
|
|
3fc4af70d0 | ||
|
|
c43088c7a6 | ||
|
|
3d7681ebab | ||
|
|
a8f99ef1f6 | ||
|
|
96d6d38872 | ||
|
|
e30e65f7a8 | ||
|
|
d3651c5888 |
@@ -461,14 +461,9 @@ func (ctxt *Link) domacho() {
|
||||
if err != nil {
|
||||
Exitf("%v", err)
|
||||
}
|
||||
if load != nil {
|
||||
machoPlatform = load.platform
|
||||
if load != nil && load.platform != PLATFORM_MACOS {
|
||||
ml := newMachoLoad(ctxt.Arch, load.cmd.type_, uint32(len(load.cmd.data)))
|
||||
copy(ml.data, load.cmd.data)
|
||||
if machoPlatform == PLATFORM_MACOS {
|
||||
ml.data[1] = macOS.version()
|
||||
ml.data[2] = macSDK.version()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -477,7 +472,7 @@ func (ctxt *Link) domacho() {
|
||||
if buildcfg.GOOS == "ios" {
|
||||
machoPlatform = PLATFORM_IOS
|
||||
}
|
||||
if ctxt.LinkMode == LinkInternal && machoPlatform == PLATFORM_MACOS {
|
||||
if load == nil && machoPlatform == PLATFORM_MACOS {
|
||||
ml := newMachoLoad(ctxt.Arch, imacho.LC_BUILD_VERSION, 4)
|
||||
ml.data[0] = uint32(machoPlatform)
|
||||
ml.data[1] = macOS.version()
|
||||
|
||||
28
src/go/printer/math.go
Normal file
28
src/go/printer/math.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2026 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 printer
|
||||
|
||||
import "math"
|
||||
|
||||
// log2ish returns a crude approximation to log₂(x).
|
||||
// The result is only used for heuristic alignment decisions and should
|
||||
// not be used where precision matters.
|
||||
// The approximation is guaranteed to produce identical results
|
||||
// across all architectures.
|
||||
func log2ish(x float64) float64 {
|
||||
f, e := math.Frexp(x)
|
||||
return float64(e) + 2*(f-1)
|
||||
}
|
||||
|
||||
// exp2ish returns a crude approximation to 2**x.
|
||||
// The result is only used for heuristic alignment decisions and should
|
||||
// not be used where precision matters.
|
||||
// The approximation is guaranteed to produce identical results
|
||||
// across all architectures.
|
||||
func exp2ish(x float64) float64 {
|
||||
n := math.Floor(x)
|
||||
f := x - n
|
||||
return math.Ldexp(1+f, int(n))
|
||||
}
|
||||
@@ -11,7 +11,6 @@ package printer
|
||||
import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
@@ -183,9 +182,9 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
|
||||
|
||||
// We use the ratio between the geometric mean of the previous key sizes and
|
||||
// the current size to determine if there should be a break in the alignment.
|
||||
// To compute the geometric mean we accumulate the ln(size) values (lnsum)
|
||||
// To compute the geometric mean we accumulate the log₂(size) values (log2sum)
|
||||
// and the number of sizes included (count).
|
||||
lnsum := 0.0
|
||||
log2sum := 0.0
|
||||
count := 0
|
||||
|
||||
// print all list elements
|
||||
@@ -228,8 +227,8 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
|
||||
if count == 0 || prevSize <= smallSize && size <= smallSize {
|
||||
useFF = false
|
||||
} else {
|
||||
const r = 2.5 // threshold
|
||||
geomean := math.Exp(lnsum / float64(count)) // count > 0
|
||||
const r = 2.5 // threshold
|
||||
geomean := exp2ish(log2sum / float64(count)) // count > 0
|
||||
ratio := float64(size) / geomean
|
||||
useFF = r*ratio <= 1 || r <= ratio
|
||||
}
|
||||
@@ -260,7 +259,7 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
|
||||
// the section), reset the geomean variables since we are
|
||||
// starting a new group of elements with the next element.
|
||||
if nbreaks > 1 {
|
||||
lnsum = 0
|
||||
log2sum = 0
|
||||
count = 0
|
||||
}
|
||||
}
|
||||
@@ -284,7 +283,7 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
|
||||
}
|
||||
|
||||
if size > 0 {
|
||||
lnsum += math.Log(float64(size))
|
||||
log2sum += log2ish(float64(size))
|
||||
count++
|
||||
}
|
||||
|
||||
|
||||
7
src/go/printer/testdata/alignment.golden
vendored
7
src/go/printer/testdata/alignment.golden
vendored
@@ -170,3 +170,10 @@ var _ = S{
|
||||
F1____: []string{},
|
||||
F2: []string{},
|
||||
}
|
||||
|
||||
// Issue #77959: formatting must be consistent across architectures.
|
||||
var _ = []any{
|
||||
(expr_size_95_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)(0), // 0
|
||||
(expr_size_38_xxxxxxxxxxxxxxxxxxxx)(0), // 1
|
||||
(*expr_size_126_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)(nil), // 2
|
||||
}
|
||||
|
||||
7
src/go/printer/testdata/alignment.input
vendored
7
src/go/printer/testdata/alignment.input
vendored
@@ -177,3 +177,10 @@ var _ = S{
|
||||
},
|
||||
F2: []string{},
|
||||
}
|
||||
|
||||
// Issue #77959: formatting must be consistent across architectures.
|
||||
var _ = []any{
|
||||
(expr_size_95_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)(0), // 0
|
||||
(expr_size_38_xxxxxxxxxxxxxxxxxxxx)(0), // 1
|
||||
(*expr_size_126_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)(nil), // 2
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ func SendFile(fd *FD, src uintptr, size int64) (written int64, err error, handle
|
||||
chunkSize = size
|
||||
}
|
||||
|
||||
fd.setOffset(startpos + written)
|
||||
n, err := fd.execIO('w', func(o *operation) (uint32, error) {
|
||||
o.setOffset(startpos + written)
|
||||
err := syscall.TransmitFile(fd.Sysfd, hsrc, uint32(chunkSize), 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build arm64 || loong64
|
||||
//go:build arm64 || loong64 || riscv64
|
||||
|
||||
package math
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !arm64 && !loong64
|
||||
//go:build !arm64 && !loong64 && !riscv64
|
||||
|
||||
package math
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build amd64 || arm64 || loong64 || s390x
|
||||
//go:build amd64 || arm64 || loong64 || riscv64 || s390x
|
||||
|
||||
package math
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !amd64 && !arm64 && !loong64 && !s390x
|
||||
//go:build !amd64 && !arm64 && !loong64 && !riscv64 && !s390x
|
||||
|
||||
package math
|
||||
|
||||
|
||||
236
src/math/exp_riscv64.s
Normal file
236
src/math/exp_riscv64.s
Normal file
@@ -0,0 +1,236 @@
|
||||
// Copyright 2026 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define NearZero 0x3e30000000000000 // 2**-28
|
||||
#define PosInf 0x7ff0000000000000
|
||||
#define FracMask 0x000fffffffffffff
|
||||
#define C1 0x3cb0000000000000 // 2**-52
|
||||
|
||||
DATA exprodata<>+0(SB)/8, $0.0
|
||||
DATA exprodata<>+8(SB)/8, $0.5
|
||||
DATA exprodata<>+16(SB)/8, $1.0
|
||||
DATA exprodata<>+24(SB)/8, $2.0
|
||||
DATA exprodata<>+32(SB)/8, $6.93147180369123816490e-01 // Ln2Hi
|
||||
DATA exprodata<>+40(SB)/8, $1.90821492927058770002e-10 // Ln2Lo
|
||||
DATA exprodata<>+48(SB)/8, $1.44269504088896338700e+00 // Log2e
|
||||
DATA exprodata<>+56(SB)/8, $7.09782712893383973096e+02 // Overflow
|
||||
DATA exprodata<>+64(SB)/8, $-7.45133219101941108420e+02 // Underflow
|
||||
DATA exprodata<>+72(SB)/8, $1.0239999999999999e+03 // Overflow2
|
||||
DATA exprodata<>+80(SB)/8, $-1.0740e+03 // Underflow2
|
||||
DATA exprodata<>+88(SB)/8, $3.7252902984619141e-09 // NearZero
|
||||
GLOBL exprodata<>+0(SB), NOPTR|RODATA, $96
|
||||
|
||||
DATA expmultirodata<>+0(SB)/8, $1.66666666666666657415e-01 // P1
|
||||
DATA expmultirodata<>+8(SB)/8, $-2.77777777770155933842e-03 // P2
|
||||
DATA expmultirodata<>+16(SB)/8, $6.61375632143793436117e-05 // P3
|
||||
DATA expmultirodata<>+24(SB)/8, $-1.65339022054652515390e-06 // P4
|
||||
DATA expmultirodata<>+32(SB)/8, $4.13813679705723846039e-08 // P5
|
||||
GLOBL expmultirodata<>+0(SB), NOPTR|RODATA, $40
|
||||
|
||||
// Exp returns e**x, the base-e exponential of x.
|
||||
// This is an assembly implementation of the method used for function Exp in file exp.go.
|
||||
//
|
||||
// func Exp(x float64) float64
|
||||
TEXT ·archExp(SB),$0-16
|
||||
MOVD x+0(FP), F0 // F0 = x
|
||||
|
||||
MOV $exprodata<>+0(SB), X5
|
||||
MOVD 56(X5), F1 // Overflow
|
||||
MOVD 64(X5), F2 // Underflow
|
||||
MOVD 88(X5), F3 // NearZero
|
||||
MOVD 16(X5), F17 // 1.0
|
||||
|
||||
FEQD F0, F0, X7
|
||||
BEQ X0, X7, isNaN // x = NaN, return NaN
|
||||
|
||||
FLTD F0, F1, X7
|
||||
BNE X0, X7, overflow // x > Overflow, return PosInf
|
||||
|
||||
FLTD F2, F0, X7
|
||||
BNE X0, X7, underflow // x < Underflow, return 0
|
||||
|
||||
FABSD F0, F5
|
||||
FLTD F3, F5, X7
|
||||
BNE X0, X7, nearzero // fabs(x) < NearZero, return 1 + x
|
||||
|
||||
// argument reduction, x = k*ln2 + r, |r| <= 0.5*ln2
|
||||
// computed as r = hi - lo for extra precision.
|
||||
MOVD 0(X5), F5
|
||||
MOVD 8(X5), F3
|
||||
MOVD 48(X5), F2
|
||||
FLTD F0, F5, X7
|
||||
BNE X0, X7, add // x > 0
|
||||
sub:
|
||||
FMSUBD F0, F2, F3, F3 // Log2e*x - 0.5
|
||||
JMP 2(PC)
|
||||
add:
|
||||
FMADDD F0, F2, F3, F3 // Log2e*x + 0.5
|
||||
|
||||
FCVTLD.RTZ F3, X16 // float64 -> int64
|
||||
FCVTDL X16, F3 // int64 -> float64
|
||||
|
||||
MOVD 32(X5), F4
|
||||
MOVD 40(X5), F5
|
||||
FNMSUBD F3, F4, F0, F4
|
||||
FMULD F3, F5, F5
|
||||
FSUBD F5, F4, F6
|
||||
FMULD F6, F6, F7
|
||||
|
||||
// compute c
|
||||
// r=(FMA x y z) -> FMADDD z, y, x, r
|
||||
// r=(FMA x y z) -> FMADDD x, y, z, r
|
||||
MOV $expmultirodata<>+0(SB), X6
|
||||
MOVD 32(X6), F8
|
||||
MOVD 24(X6), F9
|
||||
FMADDD F7, F8, F9, F13
|
||||
MOVD 16(X6), F10
|
||||
FMADDD F7, F13, F10, F13
|
||||
MOVD 8(X6), F11
|
||||
FMADDD F7, F13, F11, F13
|
||||
MOVD 0(X6), F12
|
||||
FMADDD F7, F13, F12, F13
|
||||
FNMSUBD F21, F8, F6, F8
|
||||
|
||||
// compute y
|
||||
MOVD 24(X5), F14
|
||||
FSUBD F8, F14, F14
|
||||
FMULD F6, F8, F15
|
||||
FDIVD F14, F15, F15
|
||||
FSUBD F15, F5, F15
|
||||
FSUBD F4, F15, F15
|
||||
FSUBD F15, F17, F16
|
||||
|
||||
// inline Ldexp(y, k), benefit:
|
||||
// 1, no parameter pass overhead.
|
||||
// 2, skip unnecessary checks for Inf/NaN/Zero
|
||||
MOVD F16, X15
|
||||
MOV $FracMask, X20
|
||||
AND X20, X15, X17 // fraction
|
||||
SRL $52, X15, X18 // exponent
|
||||
ADD X16, X18
|
||||
MOV $1, X21
|
||||
BGE X18, X21, normal
|
||||
ADD $52, X18 // denormal
|
||||
MOV $C1, X19
|
||||
MOVD X19, F17
|
||||
normal:
|
||||
SLL $52, X18
|
||||
OR X18, X17, X15
|
||||
MOVD X15, F0
|
||||
FMULD F17, F0, F0 // return m * x
|
||||
MOVD F0, ret+8(FP)
|
||||
RET
|
||||
nearzero:
|
||||
FADDD F17, F0, F0
|
||||
isNaN:
|
||||
MOVD F0, ret+8(FP)
|
||||
RET
|
||||
underflow:
|
||||
MOV X0, ret+8(FP)
|
||||
RET
|
||||
overflow:
|
||||
MOV $PosInf, X15
|
||||
MOV X15, ret+8(FP)
|
||||
RET
|
||||
|
||||
|
||||
// Exp2 returns 2**x, the base-2 exponential of x.
|
||||
// This is an assembly implementation of the method used for function Exp2 in file exp.go.
|
||||
//
|
||||
// func Exp2(x float64) float64
|
||||
TEXT ·archExp2(SB),$0-16
|
||||
MOVD x+0(FP), F0 // F0 = x
|
||||
|
||||
MOV $exprodata<>+0(SB), X5
|
||||
MOVD 72(X5), F1 // Overflow2
|
||||
MOVD 80(X5), F2 // Underflow2
|
||||
MOVD 88(X5), F3 // NearZero
|
||||
|
||||
FEQD F0, F0, X7
|
||||
BEQ X0, X7, isNaN // x = NaN, return NaN
|
||||
|
||||
FLTD F0, F1, X7
|
||||
BNE X0, X7, overflow // x > Overflow, return PosInf
|
||||
|
||||
FLTD F2, F0, X7
|
||||
BNE X0, X7, underflow // x < Underflow, return 0
|
||||
|
||||
// argument reduction; x = r*lg(e) + k with |r| <= ln(2)/2
|
||||
// computed as r = hi - lo for extra precision.
|
||||
MOVD 0(X5), F10
|
||||
MOVD 8(X5), F2
|
||||
FLTD F0, F10, X7
|
||||
BNE X0, X7, add
|
||||
sub:
|
||||
FSUBD F2, F0, F3 // x - 0.5
|
||||
JMP 2(PC)
|
||||
add:
|
||||
FADDD F2, F0, F3 // x + 0.5
|
||||
|
||||
FCVTLD.RTZ F3, X16
|
||||
FCVTDL X16, F3
|
||||
|
||||
MOVD 32(X5), F4
|
||||
MOVD 40(X5), F5
|
||||
FSUBD F3, F0, F3
|
||||
FMULD F3, F4, F4
|
||||
FNMSUBD F5, F3, F10, F5
|
||||
FSUBD F5, F4, F6
|
||||
FMULD F6, F6, F7
|
||||
|
||||
// compute c
|
||||
MOV $expmultirodata<>+0(SB), X6
|
||||
MOVD 32(X6), F13
|
||||
MOVD 24(X6), F9
|
||||
FMADDD F7, F13, F9, F13
|
||||
MOVD 16(X6), F10
|
||||
FMADDD F7, F13, F10, F13
|
||||
MOVD 8(X6), F11
|
||||
FMADDD F7, F13, F11, F13
|
||||
MOVD 0(X6), F12
|
||||
FMADDD F7, F13, F12, F13
|
||||
FNMSUBD F7, F13, F6, F13
|
||||
|
||||
// compute y
|
||||
MOVD 24(X5), F14
|
||||
FSUBD F13, F14, F14
|
||||
FMULD F6, F13, F15
|
||||
FDIVD F14, F15, F15
|
||||
|
||||
MOVD 16(X5), F17
|
||||
FSUBD F15, F5, F15
|
||||
FSUBD F4, F15, F15
|
||||
FSUBD F15, F17, F16
|
||||
|
||||
// inline Ldexp(y, k), benefit:
|
||||
// 1, no parameter pass overhead.
|
||||
// 2, skip unnecessary checks for Inf/NaN/Zero
|
||||
MOVD F16, X15
|
||||
MOV $FracMask, X20
|
||||
SRL $52, X15, X18 // exponent
|
||||
AND X20, X15, X17 // fraction
|
||||
ADD X16, X18
|
||||
MOV $1, X21
|
||||
BGE X18, X21, normal
|
||||
|
||||
ADD $52, X18 // denormal
|
||||
MOV $C1, X19
|
||||
MOVD X19, F17
|
||||
normal:
|
||||
SLL $52, X18
|
||||
OR X18, X17, X15
|
||||
MOVD X15, F0
|
||||
FMULD F17, F0, F0
|
||||
isNaN:
|
||||
MOVD F0, ret+8(FP)
|
||||
RET
|
||||
underflow:
|
||||
MOV X0, ret+8(FP)
|
||||
RET
|
||||
overflow:
|
||||
MOV $PosInf, X15
|
||||
MOV X15, ret+8(FP)
|
||||
RET
|
||||
@@ -558,6 +558,11 @@ const defaultUserAgent = "Go-http-client/1.1"
|
||||
// If Body is present, Content-Length is <= 0 and [Request.TransferEncoding]
|
||||
// hasn't been set to "identity", Write adds "Transfer-Encoding:
|
||||
// chunked" to the header. Body is closed after it is sent.
|
||||
//
|
||||
// Header values for Host, Content-Length, Transfer-Encoding,
|
||||
// and Trailer are not used; these are derived from other Request fields.
|
||||
// If the Header does not contain a User-Agent value, Write uses
|
||||
// "Go-http-client/1.1".
|
||||
func (r *Request) Write(w io.Writer) error {
|
||||
return r.write(w, false, nil, nil)
|
||||
}
|
||||
|
||||
@@ -388,9 +388,8 @@ type dialClientConner interface {
|
||||
// If HTTP/3 proxies are not supported, DialClientConn should return
|
||||
// an error wrapping [errors.ErrUnsupported].
|
||||
//
|
||||
// The RoundTripper returned by DialClientConn may implement
|
||||
// any of the following methods to support the [ClientConn]
|
||||
// method of the same name:
|
||||
// The RoundTripper returned by DialClientConn must also implement the
|
||||
// following methods to support [ClientConn] methods of the same name:
|
||||
// Close() error
|
||||
// Err() error
|
||||
// Reserve() error
|
||||
@@ -411,6 +410,16 @@ type dialClientConner interface {
|
||||
DialClientConn(ctx context.Context, address string, proxy *url.URL, internalStateHook func()) (RoundTripper, error)
|
||||
}
|
||||
|
||||
type closeIdleConnectionser interface {
|
||||
// CloseIdleConnections is called by Transport.CloseIdleConnections.
|
||||
//
|
||||
// The transport will close idle connections created with DialClientConn
|
||||
// before calling this method. The HTTP/3 transport should not attempt to
|
||||
// close idle connections, but may clean up shared resources such as UDP
|
||||
// sockets if no connections remain.
|
||||
CloseIdleConnections()
|
||||
}
|
||||
|
||||
// h2Transport is the interface we expect to be able to call from
|
||||
// net/http against an *http2.Transport that's either bundled into
|
||||
// h2_bundle.go or supplied by the user via x/net/http2.
|
||||
@@ -956,6 +965,9 @@ func (t *Transport) CloseIdleConnections() {
|
||||
if t2 := t.h2transport; t2 != nil {
|
||||
t2.CloseIdleConnections()
|
||||
}
|
||||
if cc, ok := t.h3transport.(closeIdleConnectionser); ok {
|
||||
cc.CloseIdleConnections()
|
||||
}
|
||||
}
|
||||
|
||||
// prepareTransportCancel sets up state to convert Transport.CancelRequest into context cancelation.
|
||||
@@ -3088,11 +3100,16 @@ func (pc *persistConn) closeLocked(err error) {
|
||||
pc.t.decConnsPerHost(pc.cacheKey)
|
||||
// Close HTTP/1 (pc.alt == nil) connection.
|
||||
// HTTP/2 closes its connection itself.
|
||||
// Close HTTP/3 connection if it implements io.Closer.
|
||||
if pc.alt == nil {
|
||||
if err != errCallerOwnsConn {
|
||||
pc.conn.Close()
|
||||
}
|
||||
close(pc.closech)
|
||||
} else {
|
||||
if cc, ok := pc.alt.(io.Closer); ok {
|
||||
cc.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
pc.mutateHeaderFunc = nil
|
||||
|
||||
@@ -132,6 +132,10 @@ func (ip IP) IsLoopback() bool {
|
||||
|
||||
// IsPrivate reports whether ip is a private address, according to
|
||||
// RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
|
||||
// That is, it reports whether ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7.
|
||||
//
|
||||
// IsPrivate does not describe a security property of addresses,
|
||||
// and should not be used for access control.
|
||||
func (ip IP) IsPrivate() bool {
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
// Following RFC 1918, Section 3. Private Address Space which says:
|
||||
|
||||
@@ -637,6 +637,9 @@ func (ip Addr) IsGlobalUnicast() bool {
|
||||
// (IPv4 addresses) and RFC 4193 (IPv6 addresses). That is, it reports whether
|
||||
// ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7. This is the
|
||||
// same as [net.IP.IsPrivate].
|
||||
//
|
||||
// IsPrivate does not describe a security property of addresses,
|
||||
// and should not be used for access control.
|
||||
func (ip Addr) IsPrivate() bool {
|
||||
if ip.Is4In6() {
|
||||
ip = ip.Unmap()
|
||||
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var testHookSupportsSendfile func() bool
|
||||
|
||||
// sendFile copies the contents of r to c using the sendfile
|
||||
// system call to minimize copies.
|
||||
//
|
||||
|
||||
@@ -8,6 +8,8 @@ package net
|
||||
|
||||
import "io"
|
||||
|
||||
var testHookSupportsSendfile func() bool
|
||||
|
||||
func supportsSendfile() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -28,6 +28,16 @@ const (
|
||||
newtonSHA256 = "d4a9ac22462b35e7821a4f2706c211093da678620a8f9997989ee7cf8d507bbd"
|
||||
)
|
||||
|
||||
func hookSupportsSendfile(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
origHook := testHookSupportsSendfile
|
||||
testHookSupportsSendfile = func() bool { return true }
|
||||
t.Cleanup(func() {
|
||||
testHookSupportsSendfile = origHook
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// expectSendfile runs f, and verifies that internal/poll.SendFile successfully handles
|
||||
// a write to wantConn during f's execution.
|
||||
//
|
||||
@@ -35,6 +45,7 @@ const (
|
||||
// expect a call to SendFile.
|
||||
func expectSendfile(t *testing.T, wantConn Conn, f func()) {
|
||||
t.Helper()
|
||||
hookSupportsSendfile(t)
|
||||
if !supportsSendfile() {
|
||||
f()
|
||||
return
|
||||
|
||||
@@ -12,5 +12,8 @@ import "internal/syscall/windows"
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile
|
||||
// https://golang.org/issue/73746
|
||||
func supportsSendfile() bool {
|
||||
if testHookSupportsSendfile != nil {
|
||||
return testHookSupportsSendfile()
|
||||
}
|
||||
return windows.SupportUnlimitedTransmitFile()
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ package cgo
|
||||
#cgo netbsd LDFLAGS: -lpthread
|
||||
#cgo openbsd LDFLAGS: -lpthread
|
||||
#cgo aix LDFLAGS: -Wl,-berok
|
||||
#cgo solaris LDFLAGS: -lxnet
|
||||
#cgo solaris LDFLAGS: -lsocket
|
||||
|
||||
// Use -fno-stack-protector to avoid problems locating the
|
||||
// proper support functions. See issues #52919, #54313, #58385.
|
||||
|
||||
@@ -97,6 +97,9 @@ import (
|
||||
// func main() {
|
||||
// val := "hello Go"
|
||||
// h := cgo.NewHandle(val)
|
||||
// // In this example, unsafe.Pointer(&h) is valid because myprint
|
||||
// // does not keep a copy of the pointer. If the C code keeps the
|
||||
// // pointer after the call returns, use runtime.Pinner to pin it.
|
||||
// C.myprint(unsafe.Pointer(&h))
|
||||
// // Output: hello Go
|
||||
// }
|
||||
|
||||
@@ -71,6 +71,9 @@ func Pipe2(p []int, flags int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
//go:cgo_ldflag "-lxnet"
|
||||
//go:cgo_ldflag "-lsocket"
|
||||
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = libsocket.accept4
|
||||
|
||||
func Accept4(fd int, flags int) (int, Sockaddr, error) {
|
||||
|
||||
@@ -85,6 +85,28 @@ func TestTBHelperParallel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 72794.
|
||||
func TestHelperRange(t *testing.T) {
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
|
||||
rangeHelperHelper(t)
|
||||
return
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
|
||||
cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestHelperRange$")
|
||||
cmd = testenv.CleanCmdEnv(cmd)
|
||||
cmd.Env = append(cmd.Env, "GO_WANT_HELPER_PROCESS=1")
|
||||
out, _ := cmd.CombinedOutput()
|
||||
want := `--- FAIL: TestHelperRange \([^)]+\)
|
||||
helperfuncs_test.go:139: range
|
||||
helperfuncs_test.go:139: range
|
||||
`
|
||||
if !regexp.MustCompile(want).Match(out) {
|
||||
t.Errorf("got output:\n\n%s\nwant matching:\n\n%s", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkTBHelper(b *testing.B) {
|
||||
f1 := func() {
|
||||
b.Helper()
|
||||
|
||||
@@ -122,3 +122,19 @@ func doPanic(t *testing.T, msg string) {
|
||||
t.Helper()
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
func rangeHelper(t *testing.T, msg string) {
|
||||
t.Helper()
|
||||
iter := func(yield func(int) bool) {
|
||||
if yield(0) {
|
||||
yield(1)
|
||||
}
|
||||
}
|
||||
for range iter {
|
||||
t.Error(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func rangeHelperHelper(t *testing.T) {
|
||||
rangeHelper(t, "range")
|
||||
}
|
||||
|
||||
@@ -816,8 +816,15 @@ func (c *common) frameSkip(skip int) runtime.Frame {
|
||||
}
|
||||
frames := runtime.CallersFrames(pc[:n])
|
||||
var firstFrame, prevFrame, frame runtime.Frame
|
||||
skipRange := false
|
||||
for more := true; more; prevFrame = frame {
|
||||
frame, more = frames.Next()
|
||||
if skipRange {
|
||||
// Skip the iterator function when a helper
|
||||
// functions does a range over function.
|
||||
skipRange = false
|
||||
continue
|
||||
}
|
||||
if frame.Function == "runtime.gopanic" {
|
||||
continue
|
||||
}
|
||||
@@ -861,7 +868,25 @@ func (c *common) frameSkip(skip int) runtime.Frame {
|
||||
c.helperNames[pcToName(pc)] = struct{}{}
|
||||
}
|
||||
}
|
||||
if _, ok := c.helperNames[frame.Function]; !ok {
|
||||
|
||||
fnName := frame.Function
|
||||
// Ignore trailing -rangeN used for iterator functions.
|
||||
const rangeSuffix = "-range"
|
||||
if suffixIdx := strings.LastIndex(fnName, rangeSuffix); suffixIdx > 0 {
|
||||
ok := true
|
||||
for i := suffixIdx + len(rangeSuffix); i < len(fnName); i++ {
|
||||
if fnName[i] < '0' || fnName[i] > '9' {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
fnName = fnName[:suffixIdx]
|
||||
skipRange = true
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := c.helperNames[fnName]; !ok {
|
||||
// Found a frame that wasn't inside a helper function.
|
||||
return frame
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user