1 /*
2 * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
5 *
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
9 */
10 #pragma once
11
12 #include <lua.h>
13 #include <lauxlib.h>
14 #include <lualib.h>
15
16 #include <l4/re/util/cap_alloc>
17
18 #if 0
19 #include <cstdio>
20 #include <typeinfo>
21 #endif
22
23 #include "lua.h"
24
25 namespace Lua {
26
27 static char const *const CAP_TYPE = "L4::Cap";
28 static char const *const CAST_TABLE = "_CAP_TYPES";
29 void set_cap_metatable(lua_State *l);
30
31 #define L4_LUA_DECLARE_KOBJECT(_cap_type) \
32 private: \
33 void operator = (_cap_type const &); \
34 _cap_type(_cap_type const &) = default; \
35 public: \
36 virtual _cap_type *clone(lua_State *l) const \
37 { \
38 _cap_type *c = new (lua_newuserdata(l, sizeof(_cap_type))) \
39 _cap_type(*this); \
40 set_cap_metatable(l); \
41 return c; \
42 } \
43 private:
44
45
46 class Cap
47 {
48 L4_LUA_DECLARE_KOBJECT(Cap)
49
50 public:
51 template< typename T >
52 struct C : public L4Re::Util::Ref_cap<T> {};
53
54 template< typename T >
cap()55 typename C<T>::Cap cap() const
56 { return L4::cap_cast<T>(_c); }
57
fpage()58 l4_fpage_t fpage() const
59 { return _c.fpage(_rights & L4_CAP_FPAGE_RWSD); }
60
ext_rights()61 unsigned long ext_rights() const
62 { return _rights & 0xf0; }
63
flags()64 unsigned flags() const { return _flags; }
65
all_rights()66 unsigned all_rights() const
67 { return _rights; }
68
rights()69 L4_cap_fpage_rights rights() const
70 { return L4_cap_fpage_rights(_rights & 0xf); }
71
72 Cap(C<void>::Cap c = C<void>::Cap(), unsigned flags = 0)
_c(c)73 : _c(c), _rights(L4_FPAGE_RO), _flags(flags) {}
74
75 template< typename T >
set(typename C<T>::Cap c)76 void set(typename C<T>::Cap c)
77 { _c = c; }
78
set(C<void>::Cap c)79 void set(C<void>::Cap c)
80 { _c = c; }
81
trim_rights(L4_cap_fpage_rights keep)82 void trim_rights(L4_cap_fpage_rights keep)
83 { _rights = _rights & (keep | (~0U << 4)); }
84
set_flags(unsigned flags)85 void set_flags(unsigned flags)
86 { _flags |= flags; }
87
set_rights(unsigned char r)88 void set_rights(unsigned char r)
89 { _rights = r | L4_FPAGE_RO; }
90
91 virtual ~Cap();
92
93 int index(lua_State *l) const;
94 int get_method_table(lua_State *l, char const *typ) const;
95
new(size_t,void * p)96 void *operator new (size_t, void *p) throw() { return p; }
delete(void *)97 void operator delete (void *) {}
98
assign(Cap * o)99 void assign(Cap *o)
100 {
101 if (o == this)
102 return;
103
104 _c = o->_c;
105 _rights = o->_rights;
106 }
107
108 public:
109 typedef void Register_methods(lua_State *l);
110 static void register_methods(lua_State *l);
111 static void create_class(lua_State *l, Register_methods *rm,
112 char const *type);
113 static void get_class(lua_State *l);
114
115
add_class_metatable(lua_State * l)116 static void add_class_metatable(lua_State *l)
117 {
118 lua_newtable(l);
119 get_class(l);
120 lua_setfield(l, -2, "__index");
121 lua_setmetatable(l, -2);
122 }
123
124 bool find_dynamic_type(lua_State *) const;
125
126 private:
127 C<void>::Cap _c;
128 unsigned _rights : 16;
129 unsigned _flags : 16;
130 };
131
132
133 Cap *
134 push_new_cap(lua_State *l, bool void_cap = false);
135
136 Cap *
137 push_void_cap(lua_State *l);
138
139 void
140 register_cap(lua_State *l, char const *name, L4::Cap<void> i, long proto = 0);
141
142 inline
143 Cap *
check_cap(lua_State * l,int idx)144 check_cap(lua_State *l, int idx)
145 { return (Cap*)luaL_checkudata(l, idx, CAP_TYPE); }
146
147 void get_cap_cast_table(lua_State *l);
148
149 template< typename C, typename Register_func >
150 void
register_cap_type(lua_State * l,Register_func r)151 register_cap_type(lua_State *l, Register_func r)
152 {
153 get_cap_cast_table(l);
154 L4::Type_info const *m = L4::kobject_typeid<C>();
155 char const *class_name = m->name() ? m->name() : "<unk-class>";
156 Cap::create_class(l, r, class_name);
157
158 if (0)
159 printf("register new cap type %s: '%s'\n", typeid(C).name(), class_name);
160 long proto = m->proto();
161 if (proto)
162 {
163 lua_pushinteger(l, proto);
164 lua_pushvalue(l, -2);
165 lua_settable(l, -4);
166 }
167
168 lua_setfield(l, -2, class_name);
169 lua_pop(l, 1);
170 }
171
172 template< typename KO, typename Lua_model >
173 class Cap_type_lib : public Lib
174 {
175 public:
Cap_type_lib()176 Cap_type_lib() : Lib(P_cap_type) {}
init(lua_State * l)177 void init(lua_State *l)
178 { register_cap_type<KO>(l, Lua_model::register_methods); }
179 };
180
181 void init_lua_cap(lua_State *l);
182
183 }
184
185
186