Skip to content

Commit 7b2b95a

Browse files
committed
Make internal/intern unsupported and avoid its usage in net/netip.
The optimization this package implements relies heavily on finalizers, which GopherJS doesn't support. As such it would create a memory leak rather than an actual optimization. Until we decide that we can use WeakMap API, this package can't be safely supported. The only current use of this package is in the `net/netip` package and this commit adds overlays that replace uses of the intern package with direct use of strings.
1 parent 69c7cf6 commit 7b2b95a

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

.std_test_pkg_exclusions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ go/build
33
go/internal/srcimporter
44
go/types
55
internal/abi
6+
internal/intern
67
internal/syscall/windows
78
internal/syscall/windows/registry
89
internal/syscall/windows/sysdll
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//go:build js
2+
3+
package intern
4+
5+
var (
6+
eth0 = &Value{cmpVal: "eth0"}
7+
eth1 = &Value{cmpVal: "eth1"}
8+
)
9+
10+
func get(k key) *Value {
11+
// Interning implementation in this package unavoidably relies upon
12+
// runtime.SetFinalizer(), which GopherJS doesn't support (at least until it
13+
// is considered safe to use the WeakMap API). Without working finalizers
14+
// using this package would create memory leaks.
15+
//
16+
// Considering that this package is supposed to serve as an optimization tool,
17+
// it is better to make it explicitly unusable and work around it at the call
18+
// sites.
19+
20+
// net/netip tests use intern API with a few fixed values. It is easier to
21+
// special-case them here than to override the entire test set.
22+
if k.isString && k.s == "eth0" {
23+
return eth0
24+
} else if k.isString && k.s == "eth1" {
25+
return eth1
26+
}
27+
28+
panic("internal/intern is not supported by GopherJS")
29+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//go:build js
2+
3+
package netip
4+
5+
import (
6+
"fmt"
7+
"internal/intern"
8+
)
9+
10+
//gopherjs:prune-original
11+
func MkAddr(u Uint128, z any) Addr {
12+
switch z := z.(type) {
13+
case *intern.Value:
14+
return Addr{u, z.Get().(string)}
15+
case string:
16+
return Addr{u, z}
17+
default:
18+
panic(fmt.Errorf("unexpected type %T of the z argument"))
19+
}
20+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//go:build js
2+
3+
package netip
4+
5+
type Addr struct {
6+
addr uint128
7+
// Unlike the upstream, we store the string directly instead of trying to
8+
// use internal/intern package for optimization.
9+
z string
10+
}
11+
12+
var (
13+
// Sentinel values for different zones. \x00 character makes it unlikely for
14+
// the sentinel value to clash with any real-life IPv6 zone index.
15+
z0 = ""
16+
z4 = "\x00ipv4"
17+
z6noz = "\x00ipv6noz"
18+
)
19+
20+
//gopherjs:prune-original
21+
func (ip Addr) Zone() string {
22+
if ip.z == z4 || ip.z == z6noz {
23+
return ""
24+
}
25+
return ip.z
26+
}
27+
28+
//gopherjs:prune-original
29+
func (ip Addr) WithZone(zone string) Addr {
30+
if !ip.Is6() {
31+
return ip
32+
}
33+
if zone == "" {
34+
ip.z = z6noz
35+
return ip
36+
}
37+
ip.z = zone
38+
return ip
39+
}

0 commit comments

Comments
 (0)