diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 38e589a2..a4a256c2 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -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 ./... @@ -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 diff --git a/lib/runtimelib/lua/time.quotas.lua b/lib/runtimelib/lua/time.quotas.lua index 804741f7..adc036d0 100644 --- a/lib/runtimelib/lua/time.quotas.lua +++ b/lib/runtimelib/lua/time.quotas.lua @@ -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 @@ -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 diff --git a/lib/tablelib/lua/tablelib.quotas.lua b/lib/tablelib/lua/tablelib.quotas.lua index 97ab2d7a..bf7468e3 100644 --- a/lib/tablelib/lua/tablelib.quotas.lua +++ b/lib/tablelib/lua/tablelib.quotas.lua @@ -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 diff --git a/runtime/hash.go b/runtime/hash.go new file mode 100644 index 00000000..6f98fa6a --- /dev/null +++ b/runtime/hash.go @@ -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 diff --git a/runtime/value.go b/runtime/value.go index 25f49642..bd5c51a5 100644 --- a/runtime/value.go +++ b/runtime/value.go @@ -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 {