diff options
| -rw-r--r-- | boot/symbol.cc | 21 | ||||
| -rw-r--r-- | include/elna/boot/dependency.h | 6 | ||||
| -rw-r--r-- | include/elna/boot/symbol.h | 9 |
3 files changed, 20 insertions, 16 deletions
diff --git a/boot/symbol.cc b/boot/symbol.cc index fcafae4..8855d52 100644 --- a/boot/symbol.cc +++ b/boot/symbol.cc @@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see #include "elna/boot/symbol.h" +#include <cassert> #include <utility> namespace elna::boot @@ -256,7 +257,7 @@ namespace elna::boot } type_info::type_info(const type& symbol) - : symbol(symbol) + : symbol(symbol), owner(symbol.get<alias_type>()) { } @@ -293,8 +294,7 @@ namespace elna::boot static void builtin_integers(const std::shared_ptr<symbol_table>& symbols, const std::array<type_properties, target_integer_count>& properties, - const std::string& integer_name, - std::vector<std::shared_ptr<alias_type>>& alias_owners) + const std::string& integer_name) { for (std::size_t i = 1; i < properties.size(); ++i) { @@ -310,7 +310,6 @@ namespace elna::boot { auto alias = std::make_shared<alias_type>(integer_name, variant_type); - alias_owners.push_back(alias); symbols->enter(integer_name, std::make_shared<type_info>(type(alias))); } } @@ -322,13 +321,12 @@ namespace elna::boot } } - std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target, - std::vector<std::shared_ptr<alias_type>>& alias_owners) + std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target) { auto result = std::make_shared<symbol_table>(); - builtin_integers(result, target.int_properties, "Int", alias_owners); - builtin_integers(result, target.word_properties, "Word", alias_owners); + builtin_integers(result, target.int_properties, "Int"); + builtin_integers(result, target.word_properties, "Word"); result->enter("Char", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Char", target.char_properties)))); @@ -403,9 +401,14 @@ namespace elna::boot std::shared_ptr<alias_type> symbol_bag::resolve(const std::string& symbol_name, type& resolution) { - auto unresolved_declaration = this->unresolved.at(symbol_name); + auto unresolved_node = this->unresolved.extract(symbol_name); + + assert(!unresolved_node.empty()); + auto unresolved_declaration = unresolved_node.mapped(); unresolved_declaration->referent = resolution; + // The alias is owned by the type_info the caller enters into the + // symbol table from now on. return unresolved_declaration; } diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h index bcd0035..028dcf1 100644 --- a/include/elna/boot/dependency.h +++ b/include/elna/boot/dependency.h @@ -142,10 +142,6 @@ namespace elna::boot // Modules being compiled right now. Used to detect circular imports. std::unordered_set<std::filesystem::path> in_progress; - // The builtin table stores global aliases (such as Int, Word) as weak - // pointers, so the state keeps their owners alive. - std::vector<std::shared_ptr<alias_type>> alias_owners; - public: const std::shared_ptr<symbol_table> globals; T custom; @@ -153,7 +149,7 @@ namespace elna::boot using const_iterator = std::unordered_map<std::filesystem::path, symbol_bag>::const_iterator; explicit dependency_state(T custom, const target_info& target) - : globals(builtin_symbol_table(target, this->alias_owners)), custom(std::move(custom)) + : globals(builtin_symbol_table(target)), custom(std::move(custom)) { } diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h index e67f0f7..46fb9e2 100644 --- a/include/elna/boot/symbol.h +++ b/include/elna/boot/symbol.h @@ -352,6 +352,12 @@ namespace elna::boot explicit type_info(const type& symbol); std::shared_ptr<type_info> is_type() override; + + private: + // Strong owner of the alias if \c symbol is an alias. Aliases are + // stored weakly in \c type, so the owning type_info keeps them alive + // for the whole lifetime of the symbol table. + const std::shared_ptr<alias_type> owner; }; /** @@ -413,8 +419,7 @@ namespace elna::boot std::shared_ptr<variable_info> is_variable() override; }; - std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target, - std::vector<std::shared_ptr<alias_type>>& alias_owners); + std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target); /** * Symbol bag contains: |
