/* * (c) 2010 Alexander Warg * economic rights: Technische Universität Dresden (Germany) * * This file is part of TUD:OS and distributed under the terms of the * GNU General Public License 2. * Please see the COPYING-GPL-2 file for details. */ #include #include #include #include #include #include #include #include "lua_cap.h" #include "lua.h" #include #include namespace Lua { namespace { static void __error(lua_State *l, int r) { // start table lua_createtable(l, 0, 2); // push current position in the script luaL_where(l, 1); lua_pushfstring(l, "runtime error %s (%d)", l4sys_errtostr(r), r); // combine the last two strings lua_concat(l, 2); lua_setfield(l, -2, "msg"); // add error code lua_pushinteger(l, r); lua_setfield(l, -2, "code"); } static int __alloc(lua_State *l) { int argc = lua_gettop(l); Lua::Cap *n = check_cap(l, 1); int objt = luaL_checkinteger(l, 2); auto obj = L4Re::Util::make_unique_cap(); if (!obj.is_valid()) luaL_error(l, "out of caps"); L4::Cap f(n->cap().get()); L4::Ipc::Varg args[argc-1]; for (int i = 3; i <= argc; ++i) { if (lua_isnumber(l, i)) args[i-3] = L4::Ipc::Varg((l4_mword_t)luaL_checkinteger(l, i)); else if (lua_isstring(l, i)) args[i-3] = L4::Ipc::Varg(luaL_checkstring(l, i)); else if (lua_isnil(l, i)) args[i-3] = L4::Ipc::Varg::nil(); } args[argc-2] = L4::Ipc::Varg::nil(); l4_msgtag_t t = L4::Factory::create_t::call(f, obj.get(), objt, args); int r = l4_error(t); if (r < 0) { __error(l, r); lua_error(l); } lua_pushinteger(l, objt); Cap *nc = Lua::push_new_cap(l, true); nc->set(obj.get()); obj.release(); return 1; } struct Factory_model { static void register_methods(lua_State *l) { static const luaL_Reg l4_cap_class[] = { { "create", __alloc }, { NULL, NULL } }; luaL_setfuncs(l, l4_cap_class, 0); Cap::add_class_metatable(l); } }; static Lua::Cap_type_lib __lib; }}