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