lua-users home
lua-l archive

Call to __len metamethod has userdata/table twice on stack

[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

AltStyle によって変換されたページ (->オリジナル) /