3 module ("L4", package.seeall)
5 -- Add this alias, it sounds better for some cases
6 L4.Env.user_factory = L4.Env.mem_alloc;
8 -- L4 protocol constants
35 eager_map = 0x1, -- L4RE_AUX_LDR_FLAG_EAGER_MAP
36 all_segs_cow = 0x2, -- L4RE_AUX_LDR_FLAG_ALL_SEGS_COW
37 pinned_segs = 0x4, -- L4RE_AUX_LDR_FLAG_PINNED_SEGS
40 -- L4Re debug constants
53 -- Loader class, encapsulates a loader instance.
54 -- * A memory allocator
55 -- * A factory used for name-space creation (ns_fab)
56 -- * A factory used for region-map creation (rm_fab)
57 -- * A Factory used for log creation (log_fab)
58 -- * A Scheduler factory (sched_fab)
61 Loader.__index = Loader;
65 function Class.check(obj, class)
66 if not obj or getmetatable(obj) ~= class then
67 error("method called with incompatible object", 3);
71 function Loader.new(proto)
72 local f = proto or {};
75 local lfab = f.loader or f.mem;
76 f.log_fab = f.log_fab or lfab;
77 f.ns_fab = f.ns_fab or lfab;
78 f.rm_fab = f.rm_fab or lfab;
79 f.sched_fab = f.sched_fab or lfab;
80 f.factory = f.factory or Env.factory;
83 setmetatable(f, Loader);
87 function mangle_class(n)
89 for i in string.gmatch(n, "([^:%s]+)") do
95 function get_cap_class(id)
98 return _CAP_TYPES[id];
99 elseif t == "string" then
100 return _CAP_TYPES[mangle_class(id)];
106 local ns_class = get_cap_class("L4Re::Namespace");
108 ns_class.register = function (self, key, value, fab)
109 if type(value) == "function" then
110 value = value(self, key);
114 if type(value) ~= "table" then
115 self:__register(key, value);
117 self:__register(key, fab(value));
121 ns_class.r = ns_class.register;
123 error("Could not find type information for L4Re::Namespace");
128 function Loader.fill_namespace(ns, tmpl, fab)
129 local function cns(value)
130 return self:create_namespace(value, fab);
133 for k, v in pairs(tmpl) do
139 function Loader:create_namespace(n, fab)
140 Class.check(self, Loader);
142 if type(n) ~= "table" then
146 local ns_fab = fab or self.ns_fab;
147 local ns = ns_fab:create(Proto.Namespace);
148 self.fill_namespace(ns, n, ns_fab);
155 App_env.__index = App_env;
157 function App_env.new(proto)
158 local f = proto or {};
160 f.loader = f.loader or default_loader;
161 f.rm_fab = f.loader.rm_fab;
162 f.factory = f.factory or f.loader.factory or L4.Env.factory;
163 -- f.scheduler = f.scheduler or f.loader.scheduler;
165 f.mem = f.mem or f.loader.mem;
167 if type(f.log) == "table" then
170 elseif type(f.log) == "function" then
176 setmetatable(f, App_env);
178 if type(f.ns) == "table" then
179 f.ns = f.loader:create_namespace(f.ns, f.ns_fab);
185 function App_env:log()
186 Class.check(self, App_env);
187 if self.loader.log_fab == nil or self.loader.log_fab.create == nil then
188 error ("Starting an application without valid log factory", 4);
190 return self.loader.log_fab:create(Proto.Log, unpack(self.log_args));
193 function App_env:start(...)
194 Class.check(self, App_env);
197 return string.gsub(a, ".*/", "");
199 local old_log_tag = self.log_args[1];
200 self.log_args[1] = self.log_args[1] or fa(...);
201 local res = exec(self, ...);
202 self.log_args[1] = old_log_tag;
206 function App_env:set_ns(tmpl)
207 Class.check(self, App_env);
208 self.ns = Namespace.new(tmpl, self.ns_fab);
211 function App_env:set_loader_fab(fab)
212 Class.check(self, App_env);
218 function App_env:set_mem_alloc(mem)
219 Class.check(self, App_env);
223 function Loader:startv(env, ...)
224 Class.check(self, Loader);
226 local caps = env.caps or {};
228 if (type(caps) == "table") then
229 caps.rom = caps.rom or Env.rom;
234 env.l4re_dbg = env.l4re_dbg or L4.Dbg.Warn;
235 local e = App_env.new(env);
239 -- Create a new IPC gate for a client-server connection
240 function L4.Loader:new_channel()
241 return self.factory:create(Proto.Ipc_gate);
244 function Loader.split_args(cmd, posix_env)
247 for w in string.gmatch(cmd, "[^%s]+") do
255 function Loader:start(env, cmd, posix_env)
256 Class.check(self, Loader);
257 return self:startv(env, self.split_args(cmd, posix_env));
260 default_loader = Loader.new({factory = Env.factory, mem = Env.mem_alloc});