yuin / gopher-lua

GopherLua: VM and compiler for Lua in Go
MIT License
6.24k stars 648 forks source link

bug: pcall affecting function upvalues #448

Open cloudwindy opened 1 year ago

cloudwindy commented 1 year ago

You must post issues only here. Questions, ideas must be posted in discussions.

Please answer the following before submitting your issue:

  1. What version of GopherLua are you using? : I'm using cmd/glua
  2. What version of Go are you using? : 1.20.5
  3. What operating system and processor architecture are you using? : linux/amd64
  4. What did you do? : I tried to run ilua.lua, but it failed and after experimenting I made a simple version of the code to reproduce the bug
    
    local a

function Use_a() print(a) a('test') end

pcall(function() error('an error') end) a = function(prompt) print(prompt) end

Use_a()

6. What did you expect to see? : pcall should not affect upvalues as in Lua 5.1.5. Its output is as follows:

$ lua test.lua function: 0x556330c5dfa0 test

7. What did you see instead? :

$ glua test.lua nil test.lua:5: attempt to call a non-function object stack traceback: test.lua:5: in function 'Use_a' test.lua:15: in main chunk

cloudwindy commented 1 year ago

In my experiment, removing the pcall method:

local a

function Use_a()
  print(a)
  a('test')
end

a = function(prompt)
  print(prompt)
end

Use_a()

Produces same result for lua and glua:

$ lua test.lua
function: 0x564dc15af480
test

$ glua test.lua
function: 0xc000156f00
test
cloudwindy commented 1 year ago

@yuin

cloudwindy commented 1 year ago

In my experiment I also found that in certain situations this bug won't reproduce if:

  1. no error is raised in pcall
  2. a is declared before the first failed pcall
  3. a is a global variable instead of local one

Looks like the environment is isolated in error() and everything before become read-only.

local a = 123
function Print_a()
  print(a)
end
pcall(function() error() end)
a = 456
print(a)
Print_a()
$ lua test.lua
456
456
$ glua test.lua
456
123
cloudwindy commented 1 year ago

I found https://github.com/yuin/gopher-lua/blob/2b3f02d9173010b12bb3ff2c0e758921accb4096/_state.go#L626-L632 Is this an intented behavior?