Lua load function seems to expect a second argument. Why?

I got up this morning and thought, "I did half the work here, might as well finish the job." Wasn't quite as simple as I'd thought but it was an interesting journey. First step is setting up the project then getting all the Lua code we'll need. This is pretty simple, you just try to compile then see which functions it complains are missing, find those functions in the lua source, add those files, repeat. In the end it was only complaining that an abort() call in there was linked to low-level system stuff that we don't have on playdate, so I added our own abort() implementation that calls pd->system->error(), and it compiled!

Running that in the simulator I next ran into a parse error in the luaL_loadstring() call. Classic string escaping goof: pdc unescapes that backslash in can\'t, so when it goes into the compile() call it looks like

  compile("print('it worked! I can't believe it!");

which throws a syntax error. I brute forced it by changing that to can\\\'t in main.lua. If you're getting strings from a text file or such you probably won't have this problem, but it's something to be aware of.

Next problem: it compiles but the generated bytecode doesn't run, looks like it's corrupted. Eventually I remembered that due to a historical accident our opcodes are shifted from standard Lua, so I copied over our lopcodes.[ch] files and got past that hurdle.

Now the code runs in the simulator! ..but not on the device. I connected the hardware debugger and got to the crash location, things look a little weird.. The Lua global struct doesn't look the same there as it does in the main firmware. The place it diverges is TValue l_registry, TValue is a union of types including numbers, and we're using 32 bit numbers instead of 64 on Playdate. Bingo. Setting LUA_32BITS to 1 in luaconf.h fixes that.

So here you go, a replacement for load():
evalC.zip (215.2 KB)

Disclaimer: This code is completely unsupported, may break at any time in the future. For entertainment purposes only. Past performance does not guarantee future returns.

4 Likes