Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix use of disallowed internal std library functions in go 1.23 #106

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ jobs:
- windows-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v5
with:
go-version: 1.17
go-version: 1.23

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

- name: Check out Lua Test Suite 5.4.3
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
repository: arnodel/golua-tests
ref: golua-5.4
Expand Down
12 changes: 6 additions & 6 deletions lib/runtimelib/lua/time.quotas.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

-- A time bound context stops when the time is exceeded
local n = 0
local ctx = runtime.callcontext({kill={millis=10}}, function()
local ctx = runtime.callcontext({kill={millis=100}}, function()
local ctx = runtime.context()
print(ctx.kill.millis, ctx.kill.seconds)
--> =10 0.01
--> =100 0.1
while true do
n = n + 1
end
Expand All @@ -15,16 +15,16 @@ end)
print(ctx)
--> =killed

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

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

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

-- The outer context keeps track of time spent in the inner context
Expand Down
2 changes: 1 addition & 1 deletion lib/tablelib/lua/tablelib.quotas.lua
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ do
print(runtime.callcontext({kill={cpu=1000}}, table.sort, unsorted(10)))
--> =done

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

Expand Down
47 changes: 47 additions & 0 deletions runtime/hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package runtime

import "unsafe"

// Previously we used the following
//
// //go:linkname goRuntimeInt64Hash runtime.int64Hash //go:noescape func
// goRuntimeInt64Hash(i uint64, seed uintptr) uintptr
//
// //go:linkname goRuntimeEfaceHash runtime.efaceHash //go:noescape func
// goRuntimeEfaceHash(i interface{}, seed uintptr) uintptr
//
// But since go 1.23 it is no longer allowed to use //go.linkname to refer to
// internal symbols in the standard library (see
// https://tip.golang.org/doc/go1.23#linker).
//
// This means the above is no longer possible - fortunately, these functions are
// implemented in Go and the functions they call are all exceptions to the rule.
// So we work around the new restriction by copying those implementations into
// our codebase.
//
// This should be fairly stable as the reasons why memhash64, nilinterhash and
// noescape are exceptions is that they are used in a number of major open
// source projects.

// The two functions below are copied from
// https://github.com/golang/go/blob/release-branch.go1.23/src/runtime/alg.go#L446-L452

func goRuntimeInt64Hash(i uint64, seed uintptr) uintptr {
return memhash64(noescape(unsafe.Pointer(&i)), seed)
}

func goRuntimeEfaceHash(i interface{}, seed uintptr) uintptr {
return nilinterhash(noescape(unsafe.Pointer(&i)), seed)
}

//go:linkname memhash64 runtime.memhash64
//go:noescape
func memhash64(p unsafe.Pointer, h uintptr) uintptr

//go:linkname nilinterhash runtime.nilinterhash
//go:noescape
func nilinterhash(p unsafe.Pointer, h uintptr) uintptr

//go:linkname noescape runtime.noescape
//go:noescape
func noescape(p unsafe.Pointer) unsafe.Pointer
8 changes: 0 additions & 8 deletions runtime/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,6 @@ func (v Value) Equals(v2 Value) bool {
return v.iface == v2.iface
}

//go:linkname goRuntimeInt64Hash runtime.int64Hash
//go:noescape
func goRuntimeInt64Hash(i uint64, seed uintptr) uintptr

//go:linkname goRuntimeEfaceHash runtime.efaceHash
//go:noescape
func goRuntimeEfaceHash(i interface{}, seed uintptr) uintptr

// Hash returns a hash for the value.
func (v Value) Hash() uintptr {
if v.scalar != 0 {
Expand Down
Loading