# HG changeset patch # User Tero Marttila # Date 1240174561 -10800 # Node ID a5582e1a83da45217037c938a2bc9dd33623b18e # Parent 51f96539f9f3d65878cb260d4491698cae5ebf93 implement lua_type diff -r 51f96539f9f3 -r a5582e1a83da src/lua_func.c --- a/src/lua_func.c Sun Apr 19 23:53:37 2009 +0300 +++ b/src/lua_func.c Sun Apr 19 23:56:01 2009 +0300 @@ -126,10 +126,8 @@ va_list vargs; // first, the obj argument - if (func->type) { - *obj_ptr = lua_obj_get_obj(L, func->name, func->type); - argidx++; - } + if (func->type) + *obj_ptr = lua_type_get(L, func->type, argidx++); // were we given a table of arguments? if (lua_istable(L, argidx)) diff -r 51f96539f9f3 -r a5582e1a83da src/lua_func.h --- a/src/lua_func.h Sun Apr 19 23:53:37 2009 +0300 +++ b/src/lua_func.h Sun Apr 19 23:56:01 2009 +0300 @@ -40,8 +40,8 @@ * Function def */ struct lua_func { - /** Type name, or NULL */ - const char *type; + /** Object type, or NULL */ + const struct lua_type *type; /** Function name */ const char *name; @@ -64,11 +64,12 @@ */ #define LUA_FUNC_ARG_STRING(name, def) { (name), LUA_ARG_STRING, { .string = (def) } } #define LUA_FUNC_ARG_BOOL(name, def) { (name), LUA_ARG_BOOL, { .boolean = (def) } } +#define LUA_FUNC_ARG_END { NULL, 0, { 0 } } /** * Define a function */ -#define LUA_FUNC(type, name, help, ...) { (type), (name), (help), { __VA_ARGS__, { NULL, 0, { 0 } } } } +#define LUA_FUNC(type, name, help, ...) { (type), (name), (help), { __VA_ARGS__, LUA_FUNC_ARG_END } } /** * Parse and return a string argument diff -r 51f96539f9f3 -r a5582e1a83da src/lua_irc.c --- a/src/lua_irc.c Sun Apr 19 23:53:37 2009 +0300 +++ b/src/lua_irc.c Sun Apr 19 23:56:01 2009 +0300 @@ -4,13 +4,15 @@ #include #include +static struct lua_type lua_chan_type = LUA_TYPE("evirc.chan"); + /** * Create a lua_chan userdata from the given irc_chan and leave it on the stack, returning 1 */ static int lua_chan_create (lua_State *L, struct irc_chan *chan) { // create the new obj - struct lua_chan *lua_chan = lua_obj_create_obj(L, "evirc.chan", sizeof(*lua_chan)); + struct lua_chan *lua_chan = lua_type_create(L, &lua_chan_type, sizeof(*lua_chan)); // initialize lua_chan->chan = chan; @@ -22,9 +24,17 @@ /** * Return the channel name as a lua string */ -static int lua_chan_tostring (lua_State *L) +static struct lua_func lua_chan__tostring_func = LUA_FUNC(&lua_chan_type, "__tostring", + "format using channel name", + + LUA_FUNC_ARG_END + ); + +static int lua_chan__tostring (lua_State *L) { - struct lua_chan *lua_chan = lua_obj_get_obj(L, __func__, "evirc.chan"); + struct lua_chan *lua_chan; + + lua_args_parse(L, &lua_chan__tostring_func, (void *) &lua_chan); lua_pushfstring(L, "", irc_chan_name(lua_chan->chan)); @@ -34,14 +44,22 @@ /** * Send a PRIVMSG to the channel */ +static struct lua_func lua_chan_say_func = LUA_FUNC(&lua_chan_type, "evirc.chan.say", + "send a message to a channel", + + LUA_FUNC_ARG_STRING("message", LUA_ARG_STRING_REQUIRED ) + ); + static int lua_chan_say (lua_State *L) { + struct lua_chan *lua_chan; err_t err; + const char *message; - struct lua_chan *lua_chan = lua_obj_get_obj(L, __func__, "evirc.chan"); - - // the message - const char *message = luaL_checkstring(L, 2); + // parse args + lua_args_parse(L, &lua_chan_say_func, (void *) &lua_chan, + &message + ); // send if ((err = irc_chan_PRIVMSG(lua_chan->chan, message))) @@ -51,19 +69,14 @@ return 0; } -static const struct luaL_Reg lua_chan_methods[] = { - { "__tostring", &lua_chan_tostring }, - { "say", &lua_chan_say }, - { NULL, NULL }, -}; +static struct lua_method lua_chan_methods[] = LUA_METHODS( + LUA_METHOD("__tostring", lua_chan__tostring, &lua_chan__tostring_func ), + LUA_METHOD("say", lua_chan_say, &lua_chan_say_func ) + ); -/** - * Initialize the lua_chan object type - */ -static void lua_chan_init (lua_State *L) -{ - lua_obj_create_type(L, "evirc.chan", lua_chan_methods); -} + + +static struct lua_type lua_net_type = LUA_TYPE("evirc.net"); /** * Create a lua_net userdata from the given irc_net and push it onto the stack, returning 1. @@ -71,7 +84,7 @@ static int lua_net_create (lua_State *L, struct irc_net *net) { // create the new obj - struct lua_net *lua_net = lua_obj_create_obj(L, "evirc.net", sizeof(*lua_net)); + struct lua_net *lua_net = lua_type_create(L, &lua_net_type, sizeof(*lua_net)); // initialize lua_net->net = net; @@ -83,9 +96,17 @@ /** * Return the network name as a lua string */ -static int lua_net_tostring (lua_State *L) +static struct lua_func lua_net__tostring_func = LUA_FUNC(&lua_net_type, "__tostring", + "format using network name", + + LUA_FUNC_ARG_END + ); + +static int lua_net__tostring (lua_State *L) { - struct lua_net *lua_net = lua_obj_get_obj(L, __func__, "evirc.net"); + struct lua_net *lua_net; + + lua_args_parse(L, &lua_net__tostring_func, (void *) &lua_net); lua_pushfstring(L, "", irc_net_name(lua_net->net)); @@ -95,16 +116,24 @@ /** * Join a new channel, returning the lua_chan */ +static struct lua_func lua_net_join_func = LUA_FUNC(&lua_net_type, "join", + "create a new channel and join it", + + LUA_FUNC_ARG_STRING("channel", LUA_ARG_STRING_REQUIRED) + ); + + static int lua_net_join (lua_State *L) { - struct lua_net *lua_net = lua_obj_get_obj(L, __func__, "evirc.net"); + struct lua_net *lua_net; struct irc_chan_info chan_info; struct irc_chan *chan; struct error_info err; // the channel name - // XXX: bad! bad! bad! - chan_info.channel = strdup(luaL_checkstring(L, 2)); + lua_args_parse(L, &lua_net_join_func, (void *) &lua_net, + &chan_info.channel + ); // add it if (irc_net_add_chan(lua_net->net, &chan, &chan_info, &err)) @@ -117,13 +146,22 @@ /** * Look up a channel by name, returning the lua_chan */ +static struct lua_func lua_net_get_chan_func = LUA_FUNC(&lua_net_type, "channel", + "look up a channel by name", + + LUA_FUNC_ARG_STRING("channel", LUA_ARG_STRING_REQUIRED) + ); + static int lua_net_get_chan (lua_State *L) { - struct lua_net *lua_net = lua_obj_get_obj(L, __func__, "evirc.net"); + struct lua_net *lua_net; struct irc_chan *chan; - - // the channel name - const char *channel = luaL_checkstring(L, 2); + const char *channel; + + // parse args + lua_args_parse(L, &lua_net_get_chan_func, (void *) &lua_net, + &channel + ); // lookup the irc_chan if ((chan = irc_net_get_chan(lua_net->net, channel)) == NULL) @@ -133,22 +171,18 @@ return lua_chan_create(L, chan); } -static const struct luaL_Reg lua_net_methods[] = { - { "__tostring", &lua_net_tostring }, - { "join", &lua_net_join }, - { "channel", &lua_net_get_chan }, - { NULL, NULL } -}; +static struct lua_method lua_net_methods[] = LUA_METHODS( + LUA_METHOD("__tostring", lua_net__tostring, &lua_net__tostring_func ), + LUA_METHOD("join", lua_net_join, &lua_net_join_func ), + LUA_METHOD("channel", lua_net_get_chan, &lua_net_get_chan_func ) + ); -/** - * Initialize the lua_net object type - */ -static void lua_net_init (lua_State *L) -{ - lua_obj_create_type(L, "evirc.net", lua_net_methods); -} -static struct lua_func lua_client_set_defaults_func = LUA_FUNC("evirc.client", "set_defaults", + +static struct lua_type lua_client_type = LUA_TYPE("evirc.client"); + + +static struct lua_func lua_client_set_defaults_func = LUA_FUNC(&lua_client_type, "set_defaults", "set the default settings to use for evirc.client.connect", LUA_FUNC_ARG_STRING("nickname", LUA_ARG_STRING_REQUIRED ), @@ -156,7 +190,7 @@ LUA_FUNC_ARG_STRING("realname", LUA_ARG_STRING_REQUIRED ), LUA_FUNC_ARG_STRING("service", IRC_PORT ), LUA_FUNC_ARG_STRING("service_ssl", IRC_SSL_PORT ) -); + ); static int lua_client_set_defaults (lua_State *L) { @@ -165,8 +199,8 @@ // parse args lua_args_parse(L, &lua_client_set_defaults_func, (void *) &lua_client, - &nickname, &username, &realname, &service, &service_ssl - ); + &nickname, &username, &realname, &service, &service_ssl + ); // set struct irc_client_defaults defaults = { @@ -187,7 +221,7 @@ return 0; } -static struct lua_func lua_client_connect_func = LUA_FUNC("evirc.client", "connect", +static struct lua_func lua_client_connect_func = LUA_FUNC(&lua_client_type, "connect", "Create and return a new IRC network", LUA_FUNC_ARG_STRING("network", LUA_ARG_STRING_REQUIRED ), @@ -239,13 +273,22 @@ return lua_net_create(L, net); } +static struct lua_func lua_client_get_network_func = LUA_FUNC(&lua_client_type, "network", + "Lookup an existing network by name", + + LUA_FUNC_ARG_STRING("network", LUA_ARG_STRING_REQUIRED) + ); + static int lua_client_get_network (lua_State *L) { - struct lua_client *lua_client = lua_obj_get_obj(L, __func__, "evirc.client"); + struct lua_client *lua_client; struct irc_net *net; - - // the network name - const char *network = luaL_checkstring(L, 2); + const char *network; + + // parse args + lua_args_parse(L, &lua_client_get_network_func, (void *) &lua_client, + &network + ); // lookup the irc_net if ((net = irc_client_get_net(lua_client->client, network)) == NULL) @@ -255,13 +298,22 @@ return lua_net_create(L, net); } +static struct lua_func lua_client_quit_func = LUA_FUNC(&lua_client_type, "quit", + "Disconnect from all networks", + + LUA_FUNC_ARG_STRING("message", "Bye") + ); + static int lua_client_quit (lua_State *L) { - struct lua_client *lua_client = lua_obj_get_obj(L, __func__, "evirc.client"); + struct lua_client *lua_client; err_t err; - - // the message - const char *message = luaL_checkstring(L, 2); + const char *message; + + // parse args + lua_args_parse(L, &lua_client_quit_func, (void *) &lua_client, + &message + ); // execute if ((err = irc_client_quit(lua_client->client, message))) @@ -271,31 +323,23 @@ return 0; } -static const struct luaL_Reg lua_client_methods[] = { - { "set_defaults", &lua_client_set_defaults }, - { "connect", &lua_client_connect }, - { "network", &lua_client_get_network }, - { "quit", &lua_client_quit }, - { NULL, NULL } -}; - -/** - * Initialize the evirc.client type for lua_client, and registers an instance bound to the given irc_client at - * 'client'. - */ -static void lua_client_init (lua_State *L, struct irc_client *client) -{ - // allocate the global "client" object - struct lua_client *lua_client = lua_obj_create_global_type(L, "evirc.client", lua_client_methods, "client", sizeof(*lua_client)); - - // initialize it - lua_client->client = client; -} +static struct lua_method lua_client_methods[] = LUA_METHODS( + LUA_METHOD("set_defaults", lua_client_set_defaults, &lua_client_set_defaults_func ), + LUA_METHOD("connect", lua_client_connect, &lua_client_connect_func ), + LUA_METHOD("network", lua_client_get_network, &lua_client_get_network_func ), + LUA_METHOD("quit", lua_client_quit, &lua_client_quit_func ) + ); void lua_irc_init (struct nexus_lua *lua) { - lua_client_init(lua->st, lua->nexus->client); - lua_net_init(lua->st); - lua_chan_init(lua->st); + // register types + lua_type_register(lua->st, &lua_chan_type, lua_chan_methods); + lua_type_register(lua->st, &lua_net_type, lua_net_methods); + + // register the global "client" object + struct lua_client *lua_client = lua_type_register_global(lua->st, &lua_client_type, lua_client_methods, "client", sizeof(*lua_client)); + + // initialize it + lua_client->client = lua->nexus->client; } diff -r 51f96539f9f3 -r a5582e1a83da src/lua_objs.c --- a/src/lua_objs.c Sun Apr 19 23:53:37 2009 +0300 +++ b/src/lua_objs.c Sun Apr 19 23:56:01 2009 +0300 @@ -12,6 +12,8 @@ struct module *module; }; +static struct lua_type lua_module_type = LUA_TYPE("spbot.module"); + /** * Create a lua_module userdata from the given module and push it onto the stack, returning 1. * @@ -20,7 +22,7 @@ static int lua_module_create (lua_State *L, struct module *module) { // create the new obj - struct lua_module *lua_module = lua_obj_create_obj(L, "spbot.module", sizeof(*lua_module)); + struct lua_module *lua_module = lua_type_create(L, &lua_module_type, sizeof(*lua_module)); // initialize lua_module->module = module; @@ -34,7 +36,7 @@ */ static int lua_module__gc (lua_State *L) { - struct lua_module *lua_module = lua_obj_get_obj(L, __func__, "spbot.module"); + struct lua_module *lua_module = lua_type_get(L, &lua_module_type, 1); // put it module_put(lua_module->module); @@ -44,7 +46,7 @@ static int lua_module_conf (lua_State *L) { - struct lua_module *lua_module = lua_obj_get_obj(L, __func__, "spbot.module"); + struct lua_module *lua_module = lua_type_get(L, &lua_module_type, 1); const struct config_option *option; struct error_info err; bool is_err = true; @@ -170,7 +172,7 @@ static int lua_module_unload (lua_State *L) { - struct lua_module *lua_module = lua_obj_get_obj(L, __func__, "spbot.module"); + struct lua_module *lua_module = lua_type_get(L, &lua_module_type, 1); struct error_info err; // just unload it @@ -181,20 +183,11 @@ return 0; } -static const struct luaL_Reg lua_module_methods[] = { - { "__gc", &lua_module__gc }, - { "conf", &lua_module_conf }, - { "unload", &lua_module_unload }, - { NULL, NULL } -}; - -/** - * Initialize the lua_module object type - */ -static void lua_module_init (lua_State *L) -{ - lua_obj_create_type(L, "spbot.module", lua_module_methods); -} +static struct lua_method lua_module_methods[] = LUA_METHODS( + LUA_METHOD("__gc", lua_module__gc, NULL ), + LUA_METHOD("conf", lua_module_conf, NULL ), + LUA_METHOD("unload", lua_module_unload, NULL ) +); /** * Wrapper for modules @@ -207,9 +200,11 @@ char *path; }; +static struct lua_type lua_modules_type = LUA_TYPE("spbot.modules"); + static int lua_modules__gc (lua_State *L) { - struct lua_modules *lua_modules = lua_obj_get_obj(L, __func__, "spbot.modules"); + struct lua_modules *lua_modules = lua_type_get(L, &lua_modules_type, 1); // remove the modules path if it was set by us if (lua_modules->path && modules_path(lua_modules->modules, NULL) == lua_modules->path) @@ -224,7 +219,7 @@ static int lua_modules_path (lua_State *L) { - struct lua_modules *lua_modules = lua_obj_get_obj(L, __func__, "spbot.modules"); + struct lua_modules *lua_modules = lua_type_get(L, &lua_modules_type, 1); char *path = NULL; const char *old_path; @@ -255,7 +250,7 @@ static int lua_modules_load (lua_State *L) { - struct lua_modules *lua_modules = lua_obj_get_obj(L, __func__, "spbot.modules"); + struct lua_modules *lua_modules = lua_type_get(L, &lua_modules_type, 1); struct module *module; struct module_info info; struct error_info err; @@ -274,7 +269,7 @@ static int lua_modules_module (lua_State *L) { - struct lua_modules *lua_modules = lua_obj_get_obj(L, __func__, "spbot.modules"); + struct lua_modules *lua_modules = lua_type_get(L, &lua_modules_type, 1); struct module *module; // the module name @@ -288,13 +283,14 @@ return lua_module_create(L, module); } -static const struct luaL_Reg lua_modules_methods[] = { - { "__gc", &lua_modules__gc }, - { "path", &lua_modules_path }, - { "load", &lua_modules_load }, - { "module", &lua_modules_module }, - { NULL, NULL } -}; +static struct lua_method lua_modules_methods[] = LUA_METHODS( + LUA_METHOD("__gc", lua_modules__gc, NULL ), + LUA_METHOD("path", lua_modules_path, NULL ), + LUA_METHOD("load", lua_modules_load, NULL ), + LUA_METHOD("module", lua_modules_module, NULL ) + ); + + /** * Initialize the spbot.modules type for lua_modules, and registers an instance bound to the given modules list at @@ -303,7 +299,7 @@ static void lua_modules_init (lua_State *L, struct modules *modules) { // allocate the global "modules" object - struct lua_modules *lua_modules = lua_obj_create_global_type(L, "spbot.modules", lua_modules_methods, "modules", sizeof(*lua_modules)); + struct lua_modules *lua_modules = lua_type_register_global(L, &lua_modules_type, lua_modules_methods, "modules", sizeof(*lua_modules)); // initialize it lua_modules->modules = modules; @@ -316,9 +312,11 @@ struct nexus *nexus; }; +static struct lua_type lua_nexus_type = LUA_TYPE("spbot.nexus"); + static int lua_nexus_shutdown (lua_State *L) { - struct lua_nexus *lua_nexus = lua_obj_get_obj(L, __func__, "spbot.nexus"); + struct lua_nexus *lua_nexus = lua_type_get(L, &lua_nexus_type, 1); // just shut it down nexus_shutdown(lua_nexus->nexus); @@ -328,7 +326,7 @@ static int lua_nexus_load_config (lua_State *L) { - struct lua_nexus *lua_nexus = lua_obj_get_obj(L, __func__, "spbot.nexus"); + struct lua_nexus *lua_nexus = lua_type_get(L, &lua_nexus_type, 1); struct error_info err; const char *path = luaL_checkstring(L, 2); @@ -340,11 +338,11 @@ return 0; } -static const struct luaL_Reg lua_nexus_methods[] = { - { "shutdown", &lua_nexus_shutdown }, - { "load_config", &lua_nexus_load_config }, - { NULL, NULL } -}; + +static struct lua_method lua_nexus_methods[] = LUA_METHODS( + LUA_METHOD("shutdown", lua_nexus_shutdown, NULL ), + LUA_METHOD("load_config", lua_nexus_load_config, NULL ) + ); /** * Initialize the spbot.nexus type for lua_nexus, and registers an instance bound to the given nexus list at @@ -353,12 +351,13 @@ static void lua_nexus_init (lua_State *L, struct nexus *nexus) { // allocate the global "nexus" object - struct lua_nexus *lua_nexus = lua_obj_create_global_type(L, "spbot.nexus", lua_nexus_methods, "nexus", sizeof(*lua_nexus)); + struct lua_nexus *lua_nexus = lua_type_register_global(L, &lua_nexus_type, lua_nexus_methods, "nexus", sizeof(*lua_nexus)); // initialize it lua_nexus->nexus = nexus; } + /** * Global functions */ @@ -410,10 +409,15 @@ void lua_objs_init (struct nexus_lua *lua) { - // init the various bits - lua_global_init(lua->st); + // register types + lua_type_register(lua->st, &lua_module_type, lua_module_methods); + + // globals lua_nexus_init(lua->st, lua->nexus); lua_modules_init(lua->st, lua->nexus->modules); - lua_module_init(lua->st); + + // global functions + lua_global_init(lua->st); } + diff -r 51f96539f9f3 -r a5582e1a83da src/lua_type.c --- a/src/lua_type.c Sun Apr 19 23:53:37 2009 +0300 +++ b/src/lua_type.c Sun Apr 19 23:56:01 2009 +0300 @@ -2,38 +2,45 @@ #include -void lua_obj_create_type (lua_State *L, const char *name, const struct luaL_Reg methods[]) +void lua_type_register (lua_State *L, const struct lua_type *type, const struct lua_method methods[]) { - luaL_newmetatable(L, name); + const struct lua_method *method; + + // create the metatable + luaL_newmetatable(L, type->name); // set the metatable __index to itself lua_pushvalue(L, -1); lua_setfield(L, -1, "__index"); - // register the methods to the metatable - luaL_register(L, NULL, methods); + // add the methods to the metatable + for (method = methods; method->func && method->info; method++) { + lua_pushcfunction(L, method->func); + lua_setfield(L, -2, method->name); + } } -void* lua_obj_create_obj (lua_State *L, const char *name, size_t size) +void* lua_type_create (lua_State *L, const struct lua_type *type, size_t size) { // create the new userdata on the stack void *ud = lua_newuserdata(L, size); // get the type and set it - luaL_getmetatable(L, name); + luaL_getmetatable(L, type->name); lua_setmetatable(L, -2); - + // ok return ud; } -void* lua_obj_create_global_type (lua_State *L, const char *type_name, const struct luaL_Reg methods[], const char *global_name, size_t size) +void* lua_type_register_global (lua_State *L, const struct lua_type *type, const struct lua_method methods[], + const char *global_name, size_t size) { // allocate the global object void *obj = lua_newuserdata(L, size); // create the type metatable - lua_obj_create_type(L, type_name, methods); + lua_type_register(L, type, methods); // set the userdata's metatable lua_setmetatable(L, -2); @@ -45,16 +52,13 @@ return obj; } -void* lua_obj_get_obj (lua_State *L, const char *func, const char *name) +void* lua_type_get (lua_State *L, const struct lua_type *type, int index) { void *ud; // validate the userdata arg - if ((ud = luaL_checkudata(L, 1, name)) == NULL) { - luaL_error(L, "bad type argument to %s: `%s` expected", func, name); - - // XXX: needs a __noreturn__ attribute - return NULL; + if ((ud = luaL_checkudata(L, index, type->name)) == NULL) { + luaL_error(L, "bad type argument: `%s` expected", type->name); return NULL; } else { // ok diff -r 51f96539f9f3 -r a5582e1a83da src/lua_type.h --- a/src/lua_type.h Sun Apr 19 23:53:37 2009 +0300 +++ b/src/lua_type.h Sun Apr 19 23:56:01 2009 +0300 @@ -12,23 +12,63 @@ #include /** - * Register a new metatable for a named type, this leaves the metatable on the stack. + * A type's method + * + * XXX: a name field? */ -void lua_obj_create_type (lua_State *L, const char *name, const struct luaL_Reg methods[]); +struct lua_method { + /** The name of the method */ + const char *name; -/** - * Create a new userdata with the given type metatable name, return the pointer, and keep it on the stack. - */ -void* lua_obj_create_obj (lua_State *L, const char *name, size_t size); + /** The function pointer */ + lua_CFunction func; + + /** The function definition, optional */ + const struct lua_func *info; +}; + +#define LUA_METHOD(name, func, info) \ + { (name), (func), (info) } + +#define LUA_METHODS(...) \ + { __VA_ARGS__, { NULL, NULL, NULL } } /** - * Create a new metatable for a type, a userdata for that type, and register it as a global + * A type */ -void* lua_obj_create_global_type (lua_State *L, const char *type_name, const struct luaL_Reg methods[], const char *global_name, size_t size); +struct lua_type { + /** The name of the type */ + const char *name; +}; + +#define LUA_TYPE(name) \ + { (name) } /** - * Get a userdata with the given type metatable name as the first argument for a function. + * Register a new metadata table for the given type in the given lua state. + * + * This leaves the new type (metatable) on the stack. */ -void* lua_obj_get_obj (lua_State *L, const char *func, const char *name); +void lua_type_register (lua_State *L, const struct lua_type *type, const struct lua_method methods[]); + +/** + * Create a new instance of the given type. + * + * This leaves the new userdata object on the stack. + */ +void* lua_type_create (lua_State *L, const struct lua_type *type, size_t size); + +/** + * Create a new userdata type, and also create an instance of it, register it as a global, and return it. + * + * This leaves the new userdata object on the stack. + */ +void* lua_type_register_global (lua_State *L, const struct lua_type *type, const struct lua_method methods[], + const char *global_name, size_t size); + +/** + * Get an object of the given type from the given stack position + */ +void* lua_type_get (lua_State *L, const struct lua_type *type, int index); #endif