Skip to content

Commit 38aca5e

Browse files
authored
Fix use of disallowed internal std library functions in go 1.23 (#106)
* Fix use of disallowed internal std library functions in go 1.23 * Update workflow * update go version to test to 1.23 * Fix flaky tests
1 parent e0b5347 commit 38aca5e

File tree

5 files changed

+58
-19
lines changed

5 files changed

+58
-19
lines changed

.github/workflows/go.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ jobs:
2222
- windows-latest
2323

2424
steps:
25-
- uses: actions/checkout@v2
25+
- uses: actions/checkout@v4
2626

2727
- name: Set up Go
28-
uses: actions/setup-go@v2
28+
uses: actions/setup-go@v5
2929
with:
30-
go-version: 1.17
30+
go-version: 1.23
3131

3232
- name: All tests
3333
run: go test -tags "${{ matrix.build_tags }}" -coverprofile="coverage.txt" -covermode=atomic ./...
@@ -43,7 +43,7 @@ jobs:
4343
run: go build -tags "${{ matrix.build_tags }}"
4444

4545
- name: Check out Lua Test Suite 5.4.3
46-
uses: actions/checkout@v2
46+
uses: actions/checkout@v4
4747
with:
4848
repository: arnodel/golua-tests
4949
ref: golua-5.4

lib/runtimelib/lua/time.quotas.lua

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
-- A time bound context stops when the time is exceeded
44
local n = 0
5-
local ctx = runtime.callcontext({kill={millis=10}}, function()
5+
local ctx = runtime.callcontext({kill={millis=100}}, function()
66
local ctx = runtime.context()
77
print(ctx.kill.millis, ctx.kill.seconds)
8-
--> =10 0.01
8+
--> =100 0.1
99
while true do
1010
n = n + 1
1111
end
@@ -15,16 +15,16 @@ end)
1515
print(ctx)
1616
--> =killed
1717

18-
-- It lasted for at least 1e6ms
19-
print(ctx.used.millis >= 10)
18+
-- It lasted for at least 100ms
19+
print(ctx.used.millis >= 100)
2020
--> =true
2121

2222
-- It didn't last much more than that (could be flaky)
23-
print(ctx.used.millis <= 20)
23+
print(ctx.used.millis <= 150)
2424
--> =true
2525

2626
-- Significant work was done while it lasted (could be flaky)
27-
print(n > 20000)
27+
print(n > 100000)
2828
--> =true
2929

3030
-- The outer context keeps track of time spent in the inner context

lib/tablelib/lua/tablelib.quotas.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ do
151151
print(runtime.callcontext({kill={cpu=1000}}, table.sort, unsorted(10)))
152152
--> =done
153153

154-
print(runtime.callcontext({kill={cpu=1000}}, table.sort, unsorted(100)))
154+
print(runtime.callcontext({kill={cpu=1000}}, table.sort, unsorted(500)))
155155
--> =killed
156156
end
157157

runtime/hash.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package runtime
2+
3+
import "unsafe"
4+
5+
// Previously we used the following
6+
//
7+
// //go:linkname goRuntimeInt64Hash runtime.int64Hash //go:noescape func
8+
// goRuntimeInt64Hash(i uint64, seed uintptr) uintptr
9+
//
10+
// //go:linkname goRuntimeEfaceHash runtime.efaceHash //go:noescape func
11+
// goRuntimeEfaceHash(i interface{}, seed uintptr) uintptr
12+
//
13+
// But since go 1.23 it is no longer allowed to use //go.linkname to refer to
14+
// internal symbols in the standard library (see
15+
// https://tip.golang.org/doc/go1.23#linker).
16+
//
17+
// This means the above is no longer possible - fortunately, these functions are
18+
// implemented in Go and the functions they call are all exceptions to the rule.
19+
// So we work around the new restriction by copying those implementations into
20+
// our codebase.
21+
//
22+
// This should be fairly stable as the reasons why memhash64, nilinterhash and
23+
// noescape are exceptions is that they are used in a number of major open
24+
// source projects.
25+
26+
// The two functions below are copied from
27+
// https://github.com/golang/go/blob/release-branch.go1.23/src/runtime/alg.go#L446-L452
28+
29+
func goRuntimeInt64Hash(i uint64, seed uintptr) uintptr {
30+
return memhash64(noescape(unsafe.Pointer(&i)), seed)
31+
}
32+
33+
func goRuntimeEfaceHash(i interface{}, seed uintptr) uintptr {
34+
return nilinterhash(noescape(unsafe.Pointer(&i)), seed)
35+
}
36+
37+
//go:linkname memhash64 runtime.memhash64
38+
//go:noescape
39+
func memhash64(p unsafe.Pointer, h uintptr) uintptr
40+
41+
//go:linkname nilinterhash runtime.nilinterhash
42+
//go:noescape
43+
func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
44+
45+
//go:linkname noescape runtime.noescape
46+
//go:noescape
47+
func noescape(p unsafe.Pointer) unsafe.Pointer

runtime/value.go

-8
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,6 @@ func (v Value) Equals(v2 Value) bool {
113113
return v.iface == v2.iface
114114
}
115115

116-
//go:linkname goRuntimeInt64Hash runtime.int64Hash
117-
//go:noescape
118-
func goRuntimeInt64Hash(i uint64, seed uintptr) uintptr
119-
120-
//go:linkname goRuntimeEfaceHash runtime.efaceHash
121-
//go:noescape
122-
func goRuntimeEfaceHash(i interface{}, seed uintptr) uintptr
123-
124116
// Hash returns a hash for the value.
125117
func (v Value) Hash() uintptr {
126118
if v.scalar != 0 {

0 commit comments

Comments
 (0)