aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-26 00:30:06 +0200
committerEugen Wissner <belka@caraus.de>2026-08-26 00:30:06 +0200
commit4d4537866690a1ef3d882f5e9a6e01d8220a3650 (patch)
treeece440e4dfdab7958280903792b8d360bc85f4c8
parent74b1bee5415aefba988002319f374abb6a95380a (diff)
downloadelna-4d4537866690a1ef3d882f5e9a6e01d8220a3650.tar.gz
Make type_info alias owner
-rw-r--r--boot/symbol.cc21
-rw-r--r--include/elna/boot/dependency.h6
-rw-r--r--include/elna/boot/symbol.h9
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: