1 /*
2  * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  */
9 #include <lua.h>
10 #include <lauxlib.h>
11 #include <lualib.h>
12 
13 #include <l4/re/util/cap_alloc>
14 #include <l4/re/util/unique_cap>
15 #include <l4/re/env>
16 #include <l4/sys/factory>
17 
18 #include "lua_cap.h"
19 #include "lua.h"
20 
21 #include <cstring>
22 #include <cstdio>
23 
24 
25 namespace Lua { namespace {
26 
__error(lua_State * l,int r)27 static void __error(lua_State *l, int r)
28 {
29   // start table
30   lua_createtable(l, 0, 2);
31 
32   // push current position in the script
33   luaL_where(l, 1);
34   lua_pushfstring(l, "runtime error %s (%d)", l4sys_errtostr(r), r);
35   // combine the last two strings
36   lua_concat(l, 2);
37   lua_setfield(l, -2, "msg");
38 
39   // add error code
40   lua_pushinteger(l, r);
41   lua_setfield(l, -2, "code");
42 }
43 
44 static int
__alloc(lua_State * l)45 __alloc(lua_State *l)
46 {
47   int argc = lua_gettop(l);
48   Lua::Cap *n = check_cap(l, 1);
49   int objt = luaL_checkinteger(l, 2);
50 
51   auto obj = L4Re::Util::make_unique_cap<L4::Kobject>();
52 
53   if (!obj.is_valid())
54     luaL_error(l, "out of caps");
55 
56   L4::Cap<L4::Factory> f(n->cap<L4::Factory>().get());
57   L4::Ipc::Varg args[argc-1];
58   for (int i = 3; i <= argc; ++i)
59     {
60       if (lua_isnumber(l, i))
61         args[i-3] = L4::Ipc::Varg((l4_mword_t)luaL_checkinteger(l, i));
62       else if (lua_isstring(l, i))
63         args[i-3] = L4::Ipc::Varg(luaL_checkstring(l, i));
64       else if (lua_isnil(l, i))
65         args[i-3] = L4::Ipc::Varg::nil();
66     }
67   args[argc-2] = L4::Ipc::Varg::nil();
68 
69   l4_msgtag_t t = L4::Factory::create_t::call(f, obj.get(), objt, args);
70   int r = l4_error(t);
71 
72   if (r < 0)
73     {
74       __error(l, r);
75       lua_error(l);
76     }
77 
78   lua_pushinteger(l, objt);
79   Cap *nc = Lua::push_new_cap(l, true);
80   nc->set(obj.get());
81 
82   obj.release();
83   return 1;
84 }
85 
86 
87 struct Factory_model
88 {
89   static void
register_methodsLua::__anonde75913b0111::Factory_model90   register_methods(lua_State *l)
91   {
92     static const luaL_Reg l4_cap_class[] =
93     {
94       { "create", __alloc },
95       { NULL, NULL }
96     };
97     luaL_setfuncs(l, l4_cap_class, 0);
98     Cap::add_class_metatable(l);
99   }
100 };
101 
102 static Lua::Cap_type_lib<L4::Factory, Factory_model> __lib;
103 
104 }}
105