lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



Hi,


I came across an odd behaviour where the call to a __len function has 2 identical stack items. I also tested __tostring and it does have only one item. Test code:


len_fail.c
// vim: ts=4 sw=4 st=4 sta tw=80 list
#include <stdio.h>
#include <string.h>

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#define  FOO_TYPE  "TYPE_OF_FOO"

// compile:
// gcc -O3 -Wall -Werror -I/usr/include len_fail.c -o len_fail -llua

lua_State  *L;

typedef struct Foo {
	size_t  len;
} Foo;

const char luascript [] = {
	"print(  uservalue ) -- invokes tostring\n"
	"print( type( uservalue ) )\n"
	"print( 'Length:',   #uservalue )\n"
};

// meta function
static int f__len( lua_State *L )
{
	printf( "STACKSIZE SHOULD BE 1 but is %d\n", lua_gettop( L ) );
	Foo *foo1 = (Foo *) luaL_checkudata( L, 1, FOO_TYPE );
	// this prooves the second stack item is the same as the first
	Foo *foo2 = (Foo *) luaL_checkudata( L, 2, FOO_TYPE );
	printf( "Found items: 1[%p]  2[%p]\n", foo1, foo2 );
	lua_pushinteger( L, foo1->len );
	return 1;
}

static int f__tostring( lua_State *L )
{
	printf( "STACKSIZE SHOULD BE 1 and is %d\n", lua_gettop( L ) );
	Foo *foo = (Foo *) luaL_checkudata( L, 1, FOO_TYPE );
	lua_pushfstring( L, FOO_TYPE"[%d]: %p", foo->len, foo );
	return 1;
}

static const luaL_Reg foo_m [] = {
	  { "__len"        , f__len }
	, { "__tostring"   , f__tostring }
	, { NULL           , NULL}
};

int main ( int argc, char *argv[] )
{
	argc=argc;
	argv[0]=argv[0];  // make -Wall -Werror happy

	L = luaL_newstate();
	luaL_openlibs(L);

	Foo *foo = (Foo *) lua_newuserdata(L, sizeof (Foo));
	foo->len = 12;

	luaL_newmetatable( L, FOO_TYPE );
	luaL_setfuncs( L, foo_m, 0 );
	lua_setmetatable( L, -2 );

	lua_setglobal( L, "uservalue" );

	luaL_loadstring( L, luascript );
	if (lua_pcall( L, 0, LUA_MULTRET, 0 ))
		printf( "%s\n", lua_tostring(L, -1) );

	// cleanup Lua
	lua_close(L);

	return 0;
}



And here is the output:

[arch@tk lua_sample]$ ./len_fail
STACKSIZE SHOULD BE 1 but is 1
TYPE_OF_FOO[12]: 0xcbebc8
userdata
STACKSIZE SHOULD BE 1 but is 2
Found items: 1[0xcbebc8]  2[0xcbebc8]
Length:	12
[arch@tk lua_sample]$


Thoughts?

 -Tobias