~maelkum/viuavm

5663a74cf945828cf792170dcec7270d51083cf8 — Marek Marecki 4 months ago b7ee007
Make get_value() and get_proxy() public

They are still an implementation detail of viua::vm::ins namespace, but
since some instructions' implementations may be stored in separate
files, having private linkage no longer makes sense for get_value() and
get_proxy().
2 files changed, 75 insertions(+), 58 deletions(-)

M new/include/viua/vm/ins.h
M new/src/vm/ins.cpp
M new/include/viua/vm/ins.h => new/include/viua/vm/ins.h +70 -0
@@ 133,6 133,76 @@ auto print_backtrace(viua::vm::Stack const&,
                     std::optional<size_t> const = std::nullopt) -> void;
auto dump_registers(std::vector<Value> const&, std::string_view const) -> void;
auto dump_memory(std::vector<Page> const&) -> void;

/*
 * Implementation details.
 */
auto get_value(std::vector<viua::vm::Value>&,
               viua::arch::Register_access const,
               viua::arch::instruction_type const*) -> viua::vm::types::Cell_view;
auto get_value(viua::vm::Stack&,
               viua::arch::Register_access const,
               viua::arch::instruction_type const*) -> viua::vm::types::Cell_view;

struct Proxy {
    using slot_type = std::reference_wrapper<viua::vm::Value>;
    using cell_type = viua::vm::types::Cell_view;

    std::variant<slot_type, cell_type> slot;

    explicit Proxy(slot_type s) : slot{s}
    {}
    explicit Proxy(cell_type c) : slot{c}
    {}

    auto hard() const -> bool
    {
        return std::holds_alternative<slot_type>(slot);
    }
    auto soft() const -> bool
    {
        return not hard();
    }

    auto view() const -> cell_type const
    {
        if (hard()) {
            return std::get<slot_type>(slot).get().value.view();
        } else {
            return std::get<cell_type>(slot);
        }
    }
    auto view() -> cell_type
    {
        if (hard()) {
            return std::get<slot_type>(slot).get().value.view();
        } else {
            return std::get<cell_type>(slot);
        }
    }
    auto overwrite() -> slot_type::type&
    {
        return std::get<slot_type>(slot).get();
    }

    template<typename T> auto operator=(T&& v) -> Proxy&
    {
        overwrite() = std::move(v);
        return *this;
    }

    template<typename T>
    inline auto boxed_of() -> std::optional<std::reference_wrapper<T>>
    {
        return view().boxed_of<T>();
    }
};
auto get_proxy(std::vector<viua::vm::Value>&,
               viua::arch::Register_access const,
               viua::arch::instruction_type const*) -> Proxy;
auto get_proxy(Stack&,
               viua::arch::Register_access const,
               viua::arch::instruction_type const*) -> Proxy;
}  // namespace viua::vm::ins

#endif

M new/src/vm/ins.cpp => new/src/vm/ins.cpp +5 -58
@@ 318,59 318,12 @@ auto get_slot(viua::arch::Register_access const ra,
    throw abort_execution{ip, "impossible"};
}

struct Proxy {
    using slot_type = std::reference_wrapper<viua::vm::Value>;
    using cell_type = viua::vm::types::Cell_view;

    std::variant<slot_type, cell_type> slot;

    explicit Proxy(slot_type s) : slot{s}
    {}
    explicit Proxy(cell_type c) : slot{c}
    {}

    auto hard() const -> bool
    {
        return std::holds_alternative<slot_type>(slot);
    }
    auto soft() const -> bool
    {
        return not hard();
    }

    auto view() const -> cell_type const
    {
        if (hard()) {
            return std::get<slot_type>(slot).get().value.view();
        } else {
            return std::get<cell_type>(slot);
        }
    }
    auto view() -> cell_type
    {
        if (hard()) {
            return std::get<slot_type>(slot).get().value.view();
        } else {
            return std::get<cell_type>(slot);
        }
    }
    auto overwrite() -> slot_type::type&
    {
        return std::get<slot_type>(slot).get();
    }

    template<typename T> auto operator=(T&& v) -> Proxy&
    {
        overwrite() = std::move(v);
        return *this;
    }
auto type_name(Proxy const& p) -> std::string
{
    return type_name(p.view());
}
}  // namespace

    template<typename T>
    inline auto boxed_of() -> std::optional<std::reference_wrapper<T>>
    {
        return view().boxed_of<T>();
    }
};
auto get_proxy(std::vector<viua::vm::Value>& registers,
               viua::arch::Register_access const a,
               ip_type const ip) -> Proxy


@@ 415,11 368,6 @@ auto get_proxy(Stack& stack,
    }
}

auto type_name(Proxy const& p) -> std::string
{
    return type_name(p.view());
}

auto get_value(std::vector<viua::vm::Value>& registers,
               viua::arch::Register_access const a,
               ip_type const ip) -> viua::vm::types::Cell_view


@@ 464,7 412,6 @@ auto get_value(Stack& stack,
            throw abort_execution{ip, "illegal read access to register " + a.to_string()};
    }
}
}  // namespace

template<typename T> auto cast_to(viua::vm::types::Cell_view value) -> T
{