playdate->lua->registerClass lua_val crashes on device

Hi folks!

I have an odd bug which I assume may be a C compiler/linker thing, but which has really stumped me. I have code that calls playdate->lua->registerClass that works on the simulator but crashes on the device. More specifically it worked great on both the simulator and device when the code was all in main.c. But when I moved it to it's own file, it still works on the simulator but crashes the device.

The crash in playdate->lua->registerClass class function only occurs when you are passing something to the third parameter (const lua_val* vals). This is used when you want to create constants as class attributes for lua.

I created a minimal test case in this repo: github.com/notpeter/playdate-lua-c.

There are two branches and two builds.
-- built from works branch (works on device)
-- built from main branch (crashes on device)

playdate-lua-c-works-4c6d9de-sdk2.0.3.pdx.zip (3.5 KB)
playdate-lua-c-crashes-d32c832-sdk2.0.3.pdx.zip (3.2 KB)

This PR shows the changes between them.


My device (v1 playdate) is running firmware 2.1.0-beta1.
Built with Playdate SDK 2.0.3 and PlaydateSDK 2.1.0-beta1 on MacOS 13.6 (Intel).

I was getting one of the following errors (sometimes 229, 225 or 33):

invalid constant type in lua_registerClass: 229

But at somepoint it stopped letting me "hit b to the see the error" and now it just throws an e0 error and now only gives "hit a to restart" with no option to see the error. :person_shrugging:

I apologize in advance as I don't have an answer to your question but instead use your thread to ask you a question about something I am dealing with and you seem like you should be able to answer.

What do you mean about "create constants as class attributes for lua"?

I'm asking because I am currently trying to find the best way to pass a collection of values (not functions) from C to Lua and I tried using lua_val as that seemed like a plausable way based on the documentation. But I ran into two problems. 1. the data is immutable. 2. And when trying to run what I have managed to do (reference: How does lua_val work) on the console I get a crash like yours.

It's funny, I had kind of forgotten I never got this portion of the Lua/C API working correctly. I had tried to get it working for settings constants (auto, low, medium, high) for Crunk-QRcode: Fast QRCodes from Lua (C-Accelerated). In the end I just gave up and instead offered it as a single function interface and explicitly documented the integer constants in the associated LuaCATS documentation:

But to answer your question, I was trying to use registerClass doucmented Inside Playdate with C, 7.11 Lua

int playdate->lua->registerClass(const char* name, const lua_reg* reg, const luaL_Val* vals, int isstatic, const char** outErr);

As vals is marked const I wouldn't expect it to work with values generated dynamically. I was just using it for constants and still never got it working.

Depending on your use case you might be able to just expose a function returns a Lua value from a statically allocated collection of values in C. Ultimately I think the issue is that Lua number values are allocated and have their lifecycle managed by the Lua Garbage collector and so aren't just a pointer to a particular int or whatever.

To be honest I'm a novice with implementing Lua stuff in C, maybe someone like @scratchminer has some insights or has had better success.

None of the examples of folks using pd->lua->registerClass I could find in open source code had a non-null value for the third param (const luaL_Val* vals):

Which leads me to believe either the implementation is non-functioning or incorrectly documented. :confused:

Oh, you need another value (like the {NULL, NULL} in reg) reading {NULL, kInt, {0}} (or at least that's how I fixed it).