feat: implement module loading

I couldn't care less to commit all the changes separately after fight
with this stupid codebase.
Also I am closing the issue since serializing contexts meant doing
something like jars which I don't want to do right now. I'll reopen the
issue though for sure clueless.

Closes: #23
This commit is contained in:
2026-07-04 18:41:06 +02:00
parent 100c542fe1
commit f89f643870
9 changed files with 352 additions and 50 deletions
@@ -16,6 +16,14 @@ namespace detail {
* @return The output stream.
*/
std::ostream& serialize(std::ostream& os, std::int8_t value);
/**
* @brief Serializes an integer.
*
* @param os Output stream.
* @param value Integer.
* @return The output stream.
*/
std::ostream& serialize(std::ostream& os, std::int16_t value);
/**
@@ -26,6 +34,14 @@ std::ostream& serialize(std::ostream& os, std::int16_t value);
* @return The output stream.
*/
std::ostream& serialize(std::ostream& os, std::int32_t value);
/**
* @brief Serializes an integer.
*
* @param os Output stream.
* @param value Integer.
* @return The output stream.
*/
std::ostream& serialize(std::ostream& os, std::int64_t value);
/**
@@ -73,6 +89,87 @@ std::ostream& serialize(std::ostream& os, std::uint64_t value);
*/
std::ostream& serialize(std::ostream& os, const std::string& value);
/**
* @brief Deserializes an integer.
*
* @param is Input stream.
* @param value Integer.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::int8_t& value);
/**
* @brief Deserializes an integer.
*
* @param is Input stream.
* @param value Integer.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::int16_t& value);
/**
* @brief Deserializes an integer.
*
* @param is Input stream.
* @param value Integer.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::int32_t& value);
/**
* @brief Deserializes an integer.
*
* @param is Input stream.
* @param value Integer.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::int64_t& value);
/**
* @brief Deserializes an integer.
*
* @param is Input stream.
* @param value Integer.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::uint8_t& value);
/**
* @brief Deserializes an integer.
*
* @param is Input stream.
* @param value Integer.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::uint16_t& value);
/**
* @brief Deserializes an integer.
*
* @param is Input stream.
* @param value Integer.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::uint32_t& value);
/**
* @brief Deserializes an integer.
*
* @param is Input stream.
* @param value Integer.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::uint64_t& value);
/**
* @brief Deserializes a string.
*
* @param is Input stream.
* @param value String.
* @return The input stream.
*/
std::istream& load(std::istream& is, std::string& value);
} // namespace detail
} // namespace furvm
+12 -2
View File
@@ -63,8 +63,18 @@ public:
/**
* @brief Constructs an import function.
*
* @param paramCount Parameter count.
* @param imp Import function.
* @param mod Module's id.
* @param function Function's id.
*/
template <typename ModFwd, typename = std::enable_if_t<std::is_constructible_v<mod_id, ModFwd>>>
function(ModFwd&& mod, function_id function)
: m_type(function_t::Import), m_paramCount(0), m_value(import_function{ std::forward<ModFwd>(mod), function }) {}
/**
* @brief Constructs an import function.
*
* @param mod Module.
* @param function Function.
*/
function(const mod_h& mod, const function_h& function);
+12 -3
View File
@@ -98,6 +98,8 @@ public:
using const_pointer = const Value*; /** Constant pointer type. */
public:
using id_type = typename Header::id_type; /** Id type of the header. */
using header_type = Header;
public:
using pair_type = std::pair<Header, Value>; /** Type of a header-value pair. */
public:
@@ -362,9 +364,16 @@ public:
delete m_pairs[id];
}
pair_type* newPair = new pair_type(std::piecewise_construct,
std::forward_as_tuple(id, 0, [&](const id_type& id) { erase(id); }),
std::forward_as_tuple(std::forward<Args>(args)...));
pair_type* newPair = nullptr;
if constexpr (detail::header_has_refcount_v<typename Handle::header_type>) {
newPair = new pair_type(std::piecewise_construct,
std::forward_as_tuple(id, 0, [&](const id_type& id) { erase(id); }),
std::forward_as_tuple(std::forward<Args>(args)...));
} else {
newPair = new pair_type(std::piecewise_construct,
std::forward_as_tuple(id),
std::forward_as_tuple(std::forward<Args>(args)...));
}
m_pairs[id] = newPair;
return { newPair };
+24 -4
View File
@@ -7,8 +7,10 @@
#include "furvm/type.hpp" // IWYU pragma: keep
#include <functional>
#include <istream>
#include <ostream>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -82,7 +84,13 @@ public:
*/
template <typename... Args>
function_h emplace_function(Args&&... args) {
function_h function = m_functions.emplace_back(std::forward<Args>(args)...);
function_h function;
if constexpr (std::is_constructible_v<class function, Args...>) {
function = m_functions.emplace_back(std::forward<Args>(args)...);
} else {
function = m_functions.emplace(std::forward<Args>(args)...);
}
m_functionMap[function->name()] = function.id();
m_publicFunctions[function->name()] = function.id();
return std::move(function);
@@ -145,7 +153,7 @@ public:
* @param name Name of the function.
* @return A handle to the function.
*/
template <typename NameFwd>
template <typename NameFwd, typename = std::enable_if_t<std::is_constructible_v<std::string, NameFwd>>>
auto function_at(NameFwd&& name) {
return function_at(m_publicFunctions.at(std::forward<NameFwd>(name)));
}
@@ -156,7 +164,7 @@ public:
* @param name Name of the function.
* @return A handle to the function.
*/
template <typename NameFwd>
template <typename NameFwd, typename = std::enable_if_t<std::is_constructible_v<std::string, NameFwd>>>
auto function_at(NameFwd&& name) const {
return function_at(m_publicFunctions.at(std::forward<NameFwd>(name)));
}
@@ -197,7 +205,11 @@ public:
*/
template <typename... Args>
auto emplace_type(Args&&... args) {
return m_types.emplace_back(std::forward<Args>(args)...);
if constexpr (std::is_constructible_v<type_p, Args...>) {
return m_types.emplace_back(std::forward<Args>(args)...);
} else {
return m_types.emplace(std::forward<Args>(args)...);
}
}
/**
@@ -239,6 +251,14 @@ public:
* @return The output stream.
*/
std::ostream& serialize(std::ostream& os) const;
/**
* @brief Loads a module in a bytecode form from an input stream.
*
* @param is Input stream.
* @return The loaded module.
*/
static mod load(std::istream& is);
private:
bytecode_t m_bytecode;
-1
View File
@@ -5,7 +5,6 @@
#include "furvm/handle.hpp" // IWYU pragma: keep
#include <cstdint>
namespace furvm {
enum class type_t : std::uint32_t {