Re[2]: Unexpected behaviour of lua_newuserdata()

  • From: Roman Tsisyk <roman@xxxxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Fri, 19 Jun 2015 12:35:44 +0300

Friday, June 19, 2015 10:53 AM +02:00 from Mike Pall < mike-1506@xxxxxxxxxx >:

Roman Tsisyk wrote:
Proper ordering of allocations and resource acquisition. See,
e.g. io.open().

Let's take a look on more concrete example (this is pseudo-code):

```
int
mybinding(lua_State *L)
{
    tx_begin(); /* get some resource */
    struct data *data = get_data(); /* get some other resource */

    try {
          /* Allocate userdata depending on resource parameters */
          struct data *udata = (struct data **) luaL_newuserdata(L,
data_size(data));
          memcpy(udata, data, data_size(data));
          data_free(data); /* free resource */
          tx_commit(); /* free resource */
          return 1;
    } catch(...) {
        data_free(data); /* free resource */
        tx_rollback(); /* free resource */
        return luaL_error(L, "OOM");
    }
}
```

How I can rewrite this code in C?
For malloc() I can check that return value is not NULL and then perform
required cleanup logic.
For luaL_newuserdata() I can't do anything without C++ try-catch block or C++
destructor, which are only work with EXTERNAL_UNWIND.

For example, lua_newuserdata() raises out of memory exception instead of
returning NULL as expected by C developer.

The Lua manual clearly documents that it raises an exception (the
'm' in parentheses on the right).

The Lua uses longjmps, it is completely different story.

There is no way properly free resources using C/C++ in case if LuaJIT
doesn't support full C++ exceptions interoperability (for example, on ARM).

That's conjecture.

I have compilation error with LUAJIT_EXTERNAL_UNWIND on ARM - lj_err_throw()
(or something like that) is not defined.

Without EXTERNAL_UNWIND LuaJIT has "limited interoperability" [1]:

- Lua errors cannot be caught on the C++ side.
- Throwing Lua errors across C++ frames will not call C++ destructors.

I have no idea how to implement the example above in such case...

[1]: http://luajit.org/extensions.html

--
WBR,
   Roman Tsisyk < roman@xxxxxxxxxxxxx >
    http://tarantool.org/ - an efficient in-memory data store and a Lua
application server

Other related posts: