Skip to content
10 changes: 8 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,10 @@ Sharing byte code is safe as it is read only and cannot be altered by lua script

// Example shows how to share the compiled byte code from a lua script between multiple VMs.
func Example() {
codeToShare := CompileLua("mylua.lua")
codeToShare, err := CompileLua("mylua.lua")
if err != nil {
panic(err)
}
a := lua.NewState()
b := lua.NewState()
c := lua.NewState()
Expand Down Expand Up @@ -847,7 +850,7 @@ Lua has an interpreter called ``lua`` . GopherLua has an interpreter called ``gl
----------------------------------------------------------------
How to Contribute
----------------------------------------------------------------
See `Guidlines for contributors <https://github.com/yuin/gopher-lua/tree/master/.github/CONTRIBUTING.md>`_ .
See `Guidelines for contributors <https://github.com/yuin/gopher-lua/tree/master/.github/CONTRIBUTING.md>`_ .

----------------------------------------------------------------
Libraries for GopherLua
Expand All @@ -865,6 +868,7 @@ Libraries for GopherLua
- `gluaxmlpath <https://github.com/ailncode/gluaxmlpath>`_ : An xmlpath module for gopher-lua
- `gmoonscript <https://github.com/rucuriousyet/gmoonscript>`_ : Moonscript Compiler for the Gopher Lua VM
- `loguago <https://github.com/rucuriousyet/loguago>`_ : Zerolog wrapper for Gopher-Lua
- `gluabit32 <https://github.com/PeerDB-io/gluabit32>`_ : [Port of Lua 5.2 bit32](https://www.lua.org/manual/5.2/manual.html#6.7)
- `gluacrypto <https://github.com/tengattack/gluacrypto>`_ : A native Go implementation of crypto library for the GopherLua VM.
- `gluasql <https://github.com/tengattack/gluasql>`_ : A native Go implementation of SQL client for the GopherLua VM.
- `purr <https://github.com/leyafo/purr>`_ : A http mock testing tool.
Expand All @@ -873,6 +877,8 @@ Libraries for GopherLua
- `glua-async <https://github.com/CuberL/glua-async>`_ : An async/await implement for gopher-lua.
- `gopherlua-debugger <https://github.com/edolphin-ydf/gopherlua-debugger>`_ : A debugger for gopher-lua
- `gluamahonia <https://github.com/super1207/gluamahonia>`_ : An encoding converter for gopher-lua
- `awesome-gopher-lua <https://github.com/Root-lee/awesome-gopher-lua>`_ : Collections of awesome libraries for GopherLua.

----------------------------------------------------------------
Donation
----------------------------------------------------------------
Expand Down
7 changes: 3 additions & 4 deletions auxlib_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package lua

import (
"io/ioutil"
"os"
"testing"
)
Expand Down Expand Up @@ -300,10 +299,10 @@ func TestOptChannel(t *testing.T) {
}

func TestLoadFileForShebang(t *testing.T) {
tmpFile, err := ioutil.TempFile("", "")
tmpFile, err := os.CreateTemp("", "")
errorIfNotNil(t, err)

err = ioutil.WriteFile(tmpFile.Name(), []byte(`#!/path/to/lua
err = os.WriteFile(tmpFile.Name(), []byte(`#!/path/to/lua
print("hello")
`), 0644)
errorIfNotNil(t, err)
Expand All @@ -321,7 +320,7 @@ print("hello")
}

func TestLoadFileForEmptyFile(t *testing.T) {
tmpFile, err := ioutil.TempFile("", "")
tmpFile, err := os.CreateTemp("", "")
errorIfNotNil(t, err)

defer func() {
Expand Down
2 changes: 1 addition & 1 deletion compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func (cd *codeStore) PropagateMV(top int, save *int, reg *int, inc int) {

func (cd *codeStore) AddLoadNil(a, b, line int) {
last := cd.Last()
if opGetOpCode(last) == OP_LOADNIL && (opGetArgA(last)+opGetArgB(last)) == a {
if opGetOpCode(last) == OP_LOADNIL && (opGetArgB(last)+1) == a {
cd.SetB(cd.LastPC(), b)
} else {
cd.AddABC(OP_LOADNIL, a, b, 0, line)
Expand Down
5 changes: 2 additions & 3 deletions iolib.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"syscall"
Expand Down Expand Up @@ -373,7 +372,7 @@ func fileReadAux(L *LState, file *lFile, idx int) int {
L.Push(v)
case 'a':
var buf []byte
buf, err = ioutil.ReadAll(file.reader)
buf, err = io.ReadAll(file.reader)
if err == io.EOF {
L.Push(emptyLString)
goto normalreturn
Expand Down Expand Up @@ -704,7 +703,7 @@ func ioType(L *LState) int {
}

func ioTmpFile(L *LState) int {
file, err := ioutil.TempFile("", "")
file, err := os.CreateTemp("", "")
if err != nil {
L.Push(LNil)
L.Push(LString(err.Error()))
Expand Down
3 changes: 1 addition & 2 deletions oslib.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package lua

import (
"io/ioutil"
"os"
"strings"
"time"
Expand Down Expand Up @@ -223,7 +222,7 @@ func osTime(L *LState) int {
}

func osTmpname(L *LState) int {
file, err := ioutil.TempFile("", "")
file, err := os.CreateTemp("", "")
if err != nil {
L.RaiseError("unable to generate a unique filename")
}
Expand Down
84 changes: 84 additions & 0 deletions script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"runtime"
"strings"
"sync/atomic"
"testing"
"time"
Expand Down Expand Up @@ -146,3 +147,86 @@ func TestGlua(t *testing.T) {
func TestLua(t *testing.T) {
testScriptDir(t, luaTests, "_lua5.1-tests")
}

func TestMergingLoadNilBug(t *testing.T) {
// there was a bug where a multiple load nils were being incorrectly merged, and the following code exposed it
s := `
function test()
local a = 0
local b = 1
local c = 2
local d = 3
local e = 4 -- reg 4
local f = 5
local g = 6
local h = 7

if e == 4 then
e = nil -- should clear reg 4, but clears regs 4-8 by mistake
end
if f == nil then
error("bad f")
end
if g == nil then
error("bad g")
end
if h == nil then
error("bad h")
end
end

test()
`

L := NewState()
defer L.Close()
if err := L.DoString(s); err != nil {
t.Error(err)
}
}

func TestMergingLoadNil(t *testing.T) {
// multiple nil assignments to consecutive registers should be merged
s := `
function test()
local a = 0
local b = 1
local c = 2

-- this should generate just one LOADNIL byte code instruction
a = nil
b = nil
c = nil

print(a,b,c)
end

test()`

chunk, err := parse.Parse(strings.NewReader(s), "test")
if err != nil {
t.Fatal(err)
}

compiled, err := Compile(chunk, "test")
if err != nil {
t.Fatal(err)
}

if len(compiled.FunctionPrototypes) != 1 {
t.Fatal("expected 1 function prototype")
}

// there should be exactly 1 LOADNIL instruction in the byte code generated for the above
// anymore, and the LOADNIL merging is not working correctly
count := 0
for _, instr := range compiled.FunctionPrototypes[0].Code {
if opGetOpCode(instr) == OP_LOADNIL {
count++
}
}

if count != 1 {
t.Fatalf("expected 1 LOADNIL instruction, found %d", count)
}
}
Loading