2#ifndef CEL_RUNTIME_DETAIL_FRAME_HPP
3#define CEL_RUNTIME_DETAIL_FRAME_HPP
4#include <cel/runtime/raw_stack.hpp>
20struct borrowed_value {
21 const value_type& type;
22 const std::byte* data;
26 void require_type(
const value_type& expected)
const;
36 const auto expected = detail::concrete_adapter<T>::type();
37 require_type(expected);
38 return detail::concrete_adapter<T>::read(type, data);
54 std::size_t _checkpoint;
55 std::span<const value> _arguments;
56 std::span<const borrowed_value> _canonical_arguments;
58 friend class raw_segment;
59 friend class raw_stack;
60 friend struct detail::frame_access;
63 void require_active()
const;
66 void reset() noexcept;
71 T read_operand(std::
size_t from_top, const value_type& expected)
const {
72 return detail::concrete_adapter<T>::read(
73 expected, _stack->borrow_trusted(_checkpoint, from_top, expected));
79 template <
class... T, std::size_t... I>
80 std::tuple<T...> acquire_operands(
const std::array<value_type,
sizeof...(T)>& types,
81 std::index_sequence<I...>)
const {
83 raw_stack::phase_guard phase(*_stack);
84 return {read_operand<T>(
sizeof...(T) - 1 - I, types[I])...};
89 void discard(std::size_t count);
94 void push_result(
const value_type& type,
const T& source) {
97 type, &source, [](
const void* input,
const value_type& shape, std::byte* destination) {
98 detail::concrete_adapter<T>::write(*
static_cast<const T*
>(input), shape,
108 explicit frame(raw_stack& stack,
109 std::span<const value> arguments = {},
110 const void* context =
nullptr);
118 frame(raw_stack& stack,
119 std::span<const borrowed_value> arguments,
120 const void* context =
nullptr);
126 frame(
const frame&) =
delete;
128 frame& operator=(
const frame&) =
delete;
130 frame(frame&&) =
delete;
132 frame& operator=(frame&&) =
delete;
135 std::size_t depth() const noexcept;
139 raw_stack& stack() const noexcept {
return *_stack; }
143 std::span<const value> arguments() const noexcept {
return _arguments; }
147 std::span<const borrowed_value> canonical_arguments() const noexcept {
148 return _canonical_arguments;
154 borrowed_value argument(std::size_t index)
const;
157 const void* context() const noexcept {
return _context; }
164 void push_argument(std::size_t index);
170 void push(
const T& source) {
171 push_result(detail::concrete_adapter<T>::type(), source);
181 auto result = _stack->read_value<T>(_checkpoint);
190 void push_clone(
const value& source);
195 void push_take(value& source);