2 * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
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.
14 #include <l4/re/util/cap_alloc>
15 #include <l4/sys/types.h>
16 #include <l4/sys/meta>
17 #include <l4/cxx/ipc_stream>
22 get_cap_cast_table(lua_State *l)
24 lua_getglobal(l, package);
25 lua_getfield(l, -1, CAST_TABLE);
34 Cap::create_class(lua_State *l, Register_methods *rm, char const *type)
38 lua_pushstring(l, type);
39 lua_setfield(l, -2, "_CLASS_NAME");
43 Cap::get_class(lua_State *l)
45 get_cap_cast_table(l);
46 lua_getfield(l, -1, "void");
51 is_valid(lua_State *l)
53 Cap *n = check_cap(l, 1);
54 lua_pushboolean(l, n && n->cap<void>().is_valid());
61 Lua::Cap *n = check_cap(l, 1);
68 tostring(lua_State *l)
70 Lua::Cap *n = check_cap(l, 1);
72 lua_rawgeti(l, -1, 0);
73 char const *type = "void";
74 if (!lua_isnil(l, -1))
76 lua_getfield(l, -1, "_CLASS_NAME");
77 type = lua_tostring(l, -1);
80 if (n->cap<void>().is_valid())
81 lua_pushfstring(l, "L4::Cap<%s>[%p] r=%p f=%p", type,
82 (void*)(n->cap<void>().cap()),
83 (void*)(l4_addr_t)n->all_rights(), (void*)(l4_addr_t)n->flags());
85 lua_pushfstring(l, "L4::Cap<%s>::Invalid", type);
90 __set_rights(lua_State *l, unsigned r)
92 Lua::Cap *n = check_cap(l, 1);
93 if (n->all_rights() == r)
97 Lua::Cap *t = n->clone(l);
108 __set_mode_call(lua_State *l)
111 if (lua_gettop(l) >= 2 && !lua_isnil(l, 2))
113 unsigned rights = L4_CAP_FPAGE_R;
114 if (lua_isnumber(l, 2))
115 rights = lua_tointeger(l, 2);
118 for (char const *r = lua_tostring(l, 2); *r; ++r)
123 case 'R': rights |= L4_CAP_FPAGE_R; break;
125 case 'W': rights |= L4_CAP_FPAGE_W; break;
127 case 'S': rights |= L4_CAP_FPAGE_S; break;
129 case 'D': rights |= L4_CAP_FPAGE_D; break;
131 case 'N': rights |= 0x10; break;
133 case 'C': rights |= 0x20; break;
137 c = __set_rights(l, rights);
143 lua_pushinteger(l, c->rights());
152 __set_rights(l, 0xef);
158 Cap::find_dynamic_type(lua_State *l) const
160 using L4Re::Util::Ref_cap;
161 Dbg dbg(Dbg::Warn, "lua");
162 Ref_cap<L4::Meta>::Cap _meta = L4::cap_cast<L4::Meta>(_c);
163 L4::Ipc::Istream res(l4_utcb());
164 res.tag() = _meta->interface(0);
166 if (int err = l4_error(res.tag()))
168 dbg.printf("Warning: Capability %lx does not support the meta protocol: %d\n",
173 L4::Ipc::Varg name, proto;
177 if (!name.is_of<char const *>())
180 if (!proto.is_of_int())
183 get_method_table(l, name.value<char const *>());
184 if (lua_isnil(l, -1))
185 { // no lua representation of type found
194 Cap::index(lua_State *l) const
196 get_method_table(l, "void"); // push table
197 lua_pushvalue(l, 2); // push key
200 if (!lua_isnil(l, -1))
203 lua_pop(l, 2); // pop nil result, and method table
206 lua_rawgeti(l, -1, 0);
207 if (lua_isnil(l, -1))
210 if (!find_dynamic_type(l))
213 lua_pushvalue(l, -1); // keep table after set
214 lua_rawseti(l, -3, 0);
217 lua_pushvalue(l, 2); // push key
223 Cap::newindex(lua_State *) const
228 static int __index(lua_State *l)
230 Lua::Cap *n = Lua::check_cap(l, 1);
235 void init_cap_metatable(lua_State *l)
237 Lua::register_method(l, "__gc", gc_cap);
238 Lua::register_method(l, "__tostring", tostring);
239 Lua::register_method(l, "__index", __index);
243 void push_cap_metatable(lua_State *l)
245 if (luaL_newmetatable(l, CAP_TYPE))
246 init_cap_metatable(l);
249 void set_cap_metatable(lua_State *l)
251 push_cap_metatable(l);
252 lua_setmetatable(l, -2);
256 Cap::get_method_table(lua_State *l, char const *typ) const
258 get_cap_cast_table(l);
259 lua_getfield(l, -1, typ /*type()*/);
265 if (luaL_newmetatable(l, type()))
267 luaL_register(l, NULL, l4_cap_class);
275 push_void_cap(lua_State *l)
277 Cap *c = new (lua_newuserdata(l, sizeof(Cap))) Cap();
278 set_cap_metatable(l);
286 push_new_cap(lua_State *l, bool void_cap)
288 int const frame = lua_gettop(l);
289 get_cap_cast_table(l);
290 lua_pushvalue(l, frame);
291 //long proto = lua_tointeger(l, frame);
292 lua_remove(l, frame);
293 lua_gettable(l, frame);
294 lua_remove(l, frame); // discard cast table
296 // and the type table or nil at index 'frame'
300 if ((found_type = !lua_isnil(l, frame)) || void_cap)
301 nc = push_void_cap(l); // cap at frame + 1
305 lua_getfenv(l, frame + 1);
306 lua_pushvalue(l, frame);
307 lua_rawseti(l, -2, 0);
308 lua_pop(l, 1); // pop env table
311 lua_remove(l, frame); // cap or nothing at frame
318 if (lua_gettop(l) > 2)
319 luaL_error(l, "too man arguments to L4.cast (expected 2:type and cap)");
321 if (lua_isfunction(l, 2))
324 Cap *c = check_cap(l, 2);
326 Cap *nc = push_new_cap(l, false);
339 init_lua_cap(lua_State *l)
341 static luaL_Reg _cast_f[] =
346 luaL_register(l, package, _cast_f);
348 lua_setfield(l, -2, CAST_TABLE);
350 get_cap_cast_table(l);
351 Cap::create_class(l, Cap::register_methods, "void");
352 lua_setfield(l, -2, "void");
357 Cap::register_methods(lua_State *l)
359 static const luaL_Reg l4_cap_class[] =
361 { "is_valid", is_valid },
363 { "rights", __set_mode_call },
364 { "mode", __set_mode_call },
365 { "m", __set_mode_call },
368 luaL_register(l, NULL, l4_cap_class);