diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-12-10 13:54:59 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-12-10 13:54:59 +0200 |
commit | 0d0d9a9c56822919e9794658d31db57f8fc3e2bf (patch) | |
tree | 6dcb1649706dc7fc3f02cd5646b4611b3309fbd1 /build/module.cxx | |
parent | 5f29fc16fb85a934280e00e54bc6307685c4e05d (diff) |
Implement two-phase initialization of modules loaded from bootstrap.build
Diffstat (limited to 'build/module.cxx')
-rw-r--r-- | build/module.cxx | 57 |
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, |