[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Call to __len metamethod has userdata/table twice on stack
- From: tobias@...
- Date: Thu, 16 Feb 2017 22:28:32 +0100
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