6 #include <l4/re/util/cap_alloc>
7 #include <l4/sys/types.h>
9 #include <l4/cxx/ipc_stream>
14 get_cap_cast_table(lua_State *l)
16 lua_getglobal(l, package);
17 lua_getfield(l, -1, CAST_TABLE);
26 Cap::create_class(lua_State *l, Register_methods *rm, char const *type)
30 lua_pushstring(l, type);
31 lua_setfield(l, -2, "_CLASS_NAME");
35 Cap::get_class(lua_State *l)
37 get_cap_cast_table(l);
38 lua_getfield(l, -1, "void");
43 is_valid(lua_State *l)
45 Cap *n = check_cap(l, 1);
46 lua_pushboolean(l, n && n->cap<void>().is_valid());
53 Lua::Cap *n = check_cap(l, 1);
60 tostring(lua_State *l)
62 Lua::Cap *n = check_cap(l, 1);
64 lua_rawgeti(l, -1, 0);
65 char const *type = "void";
66 if (!lua_isnil(l, -1))
68 lua_getfield(l, -1, "_CLASS_NAME");
69 type = lua_tostring(l, -1);
72 if (n->cap<void>().is_valid())
73 lua_pushfstring(l, "L4::Cap<%s>[%p] r=%p f=%p", type,
74 (void*)(n->cap<void>().cap()),
75 (void*)n->all_rights(), (void*)n->flags());
77 lua_pushfstring(l, "L4::Cap<%s>::Invalid", type);
82 __set_rights(lua_State *l, unsigned r)
84 Lua::Cap *n = check_cap(l, 1);
85 if (n->all_rights() == r)
89 Lua::Cap *t = n->clone(l);
100 __set_mode_call(lua_State *l)
103 if (lua_gettop(l) >= 2 && !lua_isnil(l, 2))
105 unsigned rights = L4_CAP_FPAGE_R;
106 if (lua_isnumber(l, 2))
107 rights = lua_tointeger(l, 2);
110 for (char const *r = lua_tostring(l, 2); *r; ++r)
115 case 'R': rights |= L4_CAP_FPAGE_R; break;
117 case 'W': rights |= L4_CAP_FPAGE_W; break;
119 case 'S': rights |= L4_CAP_FPAGE_S; break;
121 case 'D': rights |= L4_CAP_FPAGE_D; break;
123 case 'N': rights |= 0x10; break;
125 case 'C': rights |= 0x20; break;
129 c = __set_rights(l, rights);
135 lua_pushinteger(l, c->rights());
144 __set_rights(l, 0xef);
150 Cap::find_dynamic_type(lua_State *l) const
152 using L4Re::Util::Ref_cap;
153 Dbg dbg(Dbg::Warn, "lua");
154 Ref_cap<L4::Meta>::Cap _meta = L4::cap_cast<L4::Meta>(_c);
155 L4::Ipc_istream res(l4_utcb());
156 res.tag() = _meta->interface(0);
158 if (int err = l4_error(res.tag()))
160 dbg.printf("Hm, cpapbility %lx does not support the meta protocol: %d\n",
165 L4::Ipc::Varg name, proto;
169 if (!name.is_of<char const *>())
172 if (!proto.is_of_int())
175 get_method_table(l, name.value<char const *>());
176 if (lua_isnil(l, -1))
177 { // no lua representation of type found
186 Cap::index(lua_State *l) const
188 get_method_table(l, "void"); // push table
189 lua_pushvalue(l, 2); // push key
192 if (!lua_isnil(l, -1))
195 lua_pop(l, 2); // pop nil result, and method table
198 lua_rawgeti(l, -1, 0);
199 if (lua_isnil(l, -1))
202 if (!find_dynamic_type(l))
205 lua_pushvalue(l, -1); // keep table after set
206 lua_rawseti(l, -3, 0);
209 lua_pushvalue(l, 2); // push key
215 Cap::newindex(lua_State *) const
220 static int __index(lua_State *l)
222 Lua::Cap *n = Lua::check_cap(l, 1);
227 void init_cap_metatable(lua_State *l)
229 Lua::register_method(l, "__gc", gc_cap);
230 Lua::register_method(l, "__tostring", tostring);
231 Lua::register_method(l, "__index", __index);
235 void push_cap_metatable(lua_State *l)
237 if (luaL_newmetatable(l, CAP_TYPE))
238 init_cap_metatable(l);
241 void set_cap_metatable(lua_State *l)
243 push_cap_metatable(l);
244 lua_setmetatable(l, -2);
248 Cap::get_method_table(lua_State *l, char const *typ) const
250 get_cap_cast_table(l);
251 lua_getfield(l, -1, typ /*type()*/);
257 if (luaL_newmetatable(l, type()))
259 luaL_register(l, NULL, l4_cap_class);
267 push_void_cap(lua_State *l)
269 Cap *c = new (lua_newuserdata(l, sizeof(Cap))) Cap();
270 set_cap_metatable(l);
278 push_new_cap(lua_State *l, bool void_cap)
280 int const frame = lua_gettop(l);
281 get_cap_cast_table(l);
282 lua_pushvalue(l, frame);
283 //long proto = lua_tointeger(l, frame);
284 lua_remove(l, frame);
285 lua_gettable(l, frame);
286 lua_remove(l, frame); // discard cast table
288 // and the type table or nil at index 'frame'
292 if ((found_type = !lua_isnil(l, frame)) || void_cap)
293 nc = push_void_cap(l); // cap at frame + 1
297 lua_getfenv(l, frame + 1);
298 lua_pushvalue(l, frame);
299 lua_rawseti(l, -2, 0);
300 lua_pop(l, 1); // pop env table
303 lua_remove(l, frame); // cap or nothing at frame
310 if (lua_gettop(l) > 2)
311 luaL_error(l, "too man arguments to L4.cast (expected 2:type and cap)");
313 if (lua_isfunction(l, 2))
316 Cap *c = check_cap(l, 2);
318 Cap *nc = push_new_cap(l, false);
331 init_lua_cap(lua_State *l)
333 static luaL_Reg _cast_f[] =
338 luaL_register(l, package, _cast_f);
340 lua_setfield(l, -2, CAST_TABLE);
342 get_cap_cast_table(l);
343 Cap::create_class(l, Cap::register_methods, "void");
344 lua_setfield(l, -2, "void");
349 Cap::register_methods(lua_State *l)
351 static const luaL_Reg l4_cap_class[] =
353 { "is_valid", is_valid },
355 { "rights", __set_mode_call },
356 { "mode", __set_mode_call },
357 { "m", __set_mode_call },
360 luaL_register(l, NULL, l4_cap_class);