aboutsummaryrefslogtreecommitdiff
path: root/build/module.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-12-10 13:54:59 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-12-10 13:54:59 +0200
commit0d0d9a9c56822919e9794658d31db57f8fc3e2bf (patch)
tree6dcb1649706dc7fc3f02cd5646b4611b3309fbd1 /build/module.cxx
parent5f29fc16fb85a934280e00e54bc6307685c4e05d (diff)
Implement two-phase initialization of modules loaded from bootstrap.build
Diffstat (limited to 'build/module.cxx')
-rw-r--r--build/module.cxx57
1 files changed, 55 insertions, 2 deletions
diff --git a/build/module.cxx b/build/module.cxx
index 5f1aeff..79a9bdb 100644
--- a/build/module.cxx
+++ b/build/module.cxx
@@ -16,6 +16,41 @@ namespace build
{
available_module_map builtin_modules;
+ void
+ boot_module (const string& name, scope& rs, const location& loc)
+ {
+ // First see if this modules has already been loaded for this project.
+ //
+ loaded_module_map& lm (rs.modules);
+ auto i (lm.find (name));
+
+ if (i != lm.end ())
+ {
+ module_state& s (i->second);
+
+ // The only valid situation here is if the module has already been
+ // bootstrapped.
+ //
+ assert (s.boot);
+ return;
+ }
+
+ // Otherwise search for this module.
+ //
+ auto j (builtin_modules.find (name));
+
+ if (j == builtin_modules.end ())
+ fail (loc) << "unknown module " << name;
+
+ const module_functions& mf (j->second);
+
+ if (mf.boot == nullptr)
+ fail (loc) << "module " << name << " shouldn't be loaded in bootstrap";
+
+ i = lm.emplace (name, module_state {true, mf.init, nullptr, loc}).first;
+ mf.boot (rs, loc, i->second.module);
+ }
+
bool
load_module (bool opt,
const string& name,
@@ -41,11 +76,29 @@ namespace build
fail (loc) << "unknown module " << name;
}
else
- i = lm.emplace (name, make_pair (j->second, nullptr)).first;
+ {
+ const module_functions& mf (j->second);
+
+ if (mf.boot != nullptr)
+ fail (loc) << "module " << name << " should be loaded in bootstrap";
+
+ i = lm.emplace (
+ name, module_state {false, mf.init, nullptr, loc}).first;
+ }
+ }
+ else
+ {
+ module_state& s (i->second);
+
+ if (s.boot)
+ {
+ s.boot = false;
+ f = true; // This is a first call to init.
+ }
}
bool l (i != lm.end ());
- bool c (l && i->second.first (rs, bs, loc, i->second.second, f, opt));
+ bool c (l && i->second.init (rs, bs, loc, i->second.module, f, opt));
const variable& lv (var_pool.find (name + ".loaded",
variable_visibility::project,