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

lupa coroutines choke on nested pcalls & yield #48

Closed
immerrr opened this issue Feb 9, 2015 · 4 comments
Closed

lupa coroutines choke on nested pcalls & yield #48

immerrr opened this issue Feb 9, 2015 · 4 comments

Comments

@immerrr
Copy link

immerrr commented Feb 9, 2015

I have been running after a weird error in error handling error lately when hacking splash and I seem to have pinned the issue down. Here's an example that looks admittedly contrived when all the unnecessary details are omitted:

from lupa import LuaRuntime
lua = LuaRuntime()

py_coro = lua.execute("""
coro = require("coroutine")

function main()
  print('pcall result:', pcall(pcall, coro.yield))
end

lua_coro = coro.create(main)

step = 1
while coro.status(lua_coro) ~= 'dead' do
   print('lua step '.. step .. ':', coro.resume(lua_coro, i))
   step = step + 1
end

return coro.create(main)
""")

for i, r in enumerate(py_coro(), 1):
    print 'py step %d:' % i, r

It produces the following output for me:

lua step 1: true
pcall result:   true    true    nil
lua step 2: true
py step 1: None
Traceback (most recent call last):
  File "test_lupa.py", line 22, in <module>
    for i, r in enumerate(py_coro(), 1):
  File "lupa/_lupa.pyx", line 810, in lupa._lupa._LuaThread.__next__ (lupa/_lupa.c:12213)
  File "lupa/_lupa.pyx", line 886, in lupa._lupa.resume_lua_thread (lupa/_lupa.c:13091)
  File "lupa/_lupa.pyx", line 1207, in lupa._lupa.raise_lua_error (lupa/_lupa.c:16746)
lupa._lupa.LuaError: error in error handling

As you can see, the coroutine is easily traversed inside Lua code but not in Python code. The issue is reproduced when all three following conditions are true:

  • there are nested pcalls in the coroutine
  • there is coro.yield somewhere inside those pcalls
  • outermost pcall invocation is not a functioncall statement, but an expression whose value is used afterwards and is not optimized away
@kmike
Copy link
Collaborator

kmike commented Apr 23, 2015

@immerrr that's strange, but for me your example prints

lua step 1: true
pcall result:   true    true    nil
lua step 2: true
py step 1: None
pcall result:   true    true

@kmike
Copy link
Collaborator

kmike commented Apr 23, 2015

Lua 5.2.3, lupa 1.1 from pypi, OS X

@immerrr
Copy link
Author

immerrr commented Apr 23, 2015

Still fails for me on Ubuntu 12.04, lupa=1.1 and Lua 5.2.0.

But probably this is a hint in the right direction: pcall should return all the outputs of the function it wraps after true, so the inner pcall should return true nil (would have been true 2 if i'd write coro.resume(lua_coro, step) instead of coro.resume(lua_coro, i)), and the outer should return true true nil, like in lua section, but this value gets lost.

Maybe 5.2.3 is more liberal and doesn't think this is an error :)

@immerrr
Copy link
Author

immerrr commented Nov 9, 2015

This is a problem with Lua 5.2.0 which is fixed in 5.2.1: http://www.lua.org/bugs.html#5.2.0-4, closing the issue.

@immerrr immerrr closed this as completed Nov 9, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants