"attempt to yield across metamethod/C-call boundary" with LuaJIT but not with Lua

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

"attempt to yield across metamethod/C-call boundary" with LuaJIT but not with Lua

Szymon Gatner
Hi,

this is my first post on this list so I hope I am following all rules properly.

I just encountered the dreadful "attempt to yield across
metamethod/C-call boundary" error.
Worst part is I am getting different behavior with different
lua51.dll. With original Lua 5.1.4
attached code runs fine - no errors but when LuaJIT 1.1.7 is used error occurs.

My question is: is this code correct? If yes, why LuaJIT reports error?

Code:

#include <iostream>
#include <lua.hpp>
#include <luabind/luabind.hpp>
#include <luabind/yield_policy.hpp>

using namespace std;
using namespace luabind;

void func()
{
  cout << "c func" << endl;
}

int main()
{
  lua_State* L = luaL_newstate();
  luaL_openlibs(L);

  open(L);

  module(L)
  [
    def("func", func, yield)
  ];

  luaL_dostring(L, "function funcWrap() func() \nprint('resumed') end");

  lua_State* coro = lua_newthread(L);

  try
  {
    resume_function<void>(L, "funcWrap");
  }
  catch (error& e)
  {
    luabind::object msg(from_stack(L, 1));

    cout << e.what() << ":" << msg << cout;
  }

  cin.get();
}


--
Szymon Gatner
The Lordz Games Studio
www.thelordzgamesstudio.com

Reply | Threaded
Open this post in threaded view
|

Re: "attempt to yield across metamethod/C-call boundary" with LuaJIT but not with Lua

Tim Mensch
On 10/15/2011 5:35 PM, Szymon Gatner wrote:
>   lua_State* coro = lua_newthread(L);

You need to use lua_newcthread(). Otherwise LuaJIT 1.x doesn't create a
C stack.

Or you can use LuaJIT 2.x, which uses a different yielding method.

Tim


Reply | Threaded
Open this post in threaded view
|

Re: "attempt to yield across metamethod/C-call boundary" with LuaJIT but not with Lua

Patrick Rapin
Side note. I tried to compile your example. It was not easy because I
had to install both luabind and the huge Boost++ library.
For the matter of comparison, I tried to port that code to my
LuaClassBasedCall binding (a single header file).
I realized that unlike luabind, my library has no special support for
coroutines, so it was easier to create / resume the coroutine in Lua
language.
Still the resulting code is shorter, and IMHO easier to understand...


#include <iostream>
#include <lgencall.hpp>

using namespace std;
using namespace lua;

int func(lua_State* L)
{
 cout << "c func" << endl;
 return lua_yield(L, 0);
}

int main()
{
 Lua<> L;

 const char* error = L.PCall(
  "local func = ...\n"
  "function funcWrap() func(); print('resumed') end\n"
  "coro = coroutine.create(funcWrap)\n"
  "coroutine.resume(coro)", Input(func));
 if(error)
  cout << error << endl;

 cin.get();
}

Reply | Threaded
Open this post in threaded view
|

Re: "attempt to yield across metamethod/C-call boundary" with LuaJIT but not with Lua

Szymon Gatner
In reply to this post by Szymon Gatner
Hi,

thanks for bot answers. I got them in "digest mode" so my reply might look
bit weird.

Tim Mensch <[hidden email]> wrote:

>>   lua_State* coro = lua_newthread(L);

> You need to use lua_newcthread(). Otherwise LuaJIT 1.x doesn't create a
> C stack.
>
> Or you can use LuaJIT 2.x, which uses a different yielding method.

So code I posted is in fact valid? I though LuaJIT was suppos e to be
"drop-in replacement". Obliviously both VMs behave very differently.
To be hones I still don't quite understand what that error message means.

Patrick Rapin <[hidden email]> wrote:

> Side note. I tried to compile your example. [snip]

Thanks for the effort but I am way too far with luabind to switch now
and actually I am very happy with it. Other thing is that I don't want
scripters to be even aware of their code running in coroutines. All
yielding/resuming is happening in C++ while scripters only focus on
game logic.



Cheers,
Simon

--
Szymon Gatner
The Lordz Games Studio
www.thelordzgamesstudio.com