playdate->lua->callFunction fails, wrong stack size

When _progress_cb is called in the following code,

static void _progress_cb(){
    const char *err;
    if(!pd->lua->callFunction("slob_progress", 0, &err)){
        pd->system->logToConsole("%s:%i: calling slob_progress failed, %s", __FILE__, __LINE__, err);
    }
}
static int l_get(lua_State *L){
    char *content;
    slob_t *slob = pd->lua->getArgObject(1, "slob", NULL);
    uint64_t id = pd->lua->getArgInt(2);
    uint32_t bin;
    uint16_t item;
    from_blob_id(&bin, &item, id);
    slob_get_progress(&content, bin, item, _progress_cb, NULL, slob);
    pd->lua->pushString(content);
    pd->system->realloc(content, 0);
    return 1;
}

I get the following error:

src/slob_pd.c:82: calling slob_progress failed, lua_exec() expected 1 items on stack, but it has 3
src/slob_pd.c:82: calling slob_progress failed, lua_exec() expected 1 items on stack, but it has 5
[...]
src/slob_pd.c:82: calling slob_progress failed, lua_exec() expected 1 items on stack, but it has 21
main.lua:140: stack overflow at Core/minilua/lapi.c:638
stack traceback:
	[C]: in method 'get'
	main.lua:140: in function 'openChapter'

No idea what's going wrong here, this seems like the simplest possible use case for callFunction. Is it not supposed to be called from within a Lua bound function? (If not there, then where?)

Once again, just giving us lua.h functions would make this less complex :slightly_smiling_face:

No luck reproducing that with a stripped down case.

main.c

#include <stdio.h>
#include <stdlib.h>

#include "pd_api.h"

PlaydateAPI* pd;

static int test(lua_State *L)
{
	pd->lua->callFunction("callback", 0, NULL);
	pd->lua->pushString("hello");
	return 1;
}

#ifdef _WINDLL
__declspec(dllexport)
#endif
int eventHandler(PlaydateAPI* playdate, PDSystemEvent event, uint32_t arg)
{
	pd = playdate;

	if ( event == kEventInitLua )
		pd->lua->addFunction(test, "test", NULL);
	
	return 0;
}

main.lua

function callback() print("callback") end

print("test says "..test())

function playdate.update() end

result:

callback
test says hello

I tried pushing extra junk to the stack, calling the callback multiple times.. still works as expected. :confused:

Hmm, thanks for taking a look at it. On second thought I'm wondering if this is related to my l_get function being part of a table, passed into Lua with registerClass (which I neglected to mention in my example code.) I already refactored my game so I'll be able to ship it without worrying about this bug, but in a few days I'll come back and see if I can make a properly stripped down test case.

I was able to reproduce this error by calling Lua -> C -> Lua in that order.
In this test, the error occurs only when the C function call has arguments.

LuaTest.zip (3.5 KB)

main.lua

local gfx = playdate.graphics

function LuaFunction()
	print("[Called] LuaFunction.")
end

local _first = true
function playdate.update()
	if _first then
		print("\n[Call] CFunction argc:0")
		CFunction()
		
		print("\n[Call] CFunction argc:1")
		CFunction("hoge")
		_first = false
	end
end

main.c

#include "pd_api.h"
static PlaydateAPI* gpd = NULL;
static const char* err = NULL;

static int _CFunction(lua_State* L)
{
	gpd->system->logToConsole("[Called] CFunction.");

	gpd->system->logToConsole("[Call] LuaFunction.");
	if (!gpd->lua->callFunction("LuaFunction", 0, &err))
	{
		gpd->system->logToConsole(err);
	}

	return 0;
}

#ifdef _WINDLL
__declspec(dllexport)
#endif
int eventHandler(PlaydateAPI* pd, PDSystemEvent event, uint32_t arg)
{
	if ( event == kEventInitLua)
	{
		gpd = pd;
		if (!gpd->lua->addFunction(_CFunction, "CFunction", &err))
		{
			gpd->system->logToConsole("%s:%i: addFunction failed, %s", __FILE__, __LINE__, err);
		}
	}
	return 0;
}

logConsole

[Call] CFunction argc:0
[Called] CFunction.
[Call] LuaFunction.
[Called] LuaFunction.

[Call] CFunction argc:1
[Called] CFunction.
[Call] LuaFunction.
lua_exec() expected 1 items on stack, but it has 2
1 Like