20template <std::ranges::input_range Range,
typename Predicate>
23 auto filtered = range | std::views::filter(predicate);
25 auto count = std::ranges::distance(filtered);
30 return *std::ranges::next(filtered.begin(),
static_cast<long>(
index %
static_cast<size_t>(count)));
33uint32_t get_max_variable_address(
AddressingMode mode, uint32_t base_offset, uint32_t max_operand_address)
37 return max_operand_address;
39 return base_offset + max_operand_address;
58uint32_t trimmed_pointer_address(uint32_t pointer_address_seed, uint32_t max_operand_address)
60 return pointer_address_seed % (max_operand_address + 1);
63uint32_t trimmed_relative_pointer_address(uint32_t pointer_address_seed,
65 uint32_t max_operand_address)
67 return base_offset + (pointer_address_seed % (max_operand_address + 1));
92 if (stored_tag ==
tag) {
105 uint32_t absolute_address,
106 uint32_t max_operand_address)
111 switch (variable.
mode) {
113 uint32_t trimmed_pointer_address_value =
124 uint32_t trimmed_pointer_address_value =
138 return resolved_address;
150 uint32_t trimmed_pointer_address_value =
151 trimmed_pointer_address(
address.pointer_address_seed, max_operand_address);
162 uint32_t trimmed_pointer_address_value =
163 trimmed_relative_pointer_address(
address.pointer_address_seed,
base_offset, max_operand_address);
175 return resolved_address;
212 if (!actual_address.has_value()) {
217 auto operand = OperandBuilder::from<uint8_t>(
static_cast<uint8_t
>(resolved_address.operand_address));
227 auto operand = OperandBuilder::from<uint8_t>(
static_cast<uint8_t
>(resolved_address.operand_address));
246 if (!actual_address.has_value()) {
252 auto operand = OperandBuilder::from<uint16_t>(
static_cast<uint16_t
>(resolved_address.operand_address));
261 auto operand = OperandBuilder::from<uint16_t>(
static_cast<uint16_t
>(resolved_address.operand_address));
270 return get_nth_filtered(
272 [min_value, max_value](uint32_t val) {
return val >= min_value && val <= max_value; },
279 if (!
value.has_value()) {
282 return static_cast<uint8_t
>(
value.value());
288 if (!
value.has_value()) {
291 return static_cast<uint16_t
>(
value.value());
#define BB_ASSERT_LTE(left, right,...)
#define AVM_HIGHEST_MEM_ADDRESS
bb::avm2::testing::OperandBuilder get_memory_address_operand(bb::avm2::testing::OperandBuilder operand, AddressingMode mode)
std::optional< uint16_t > get_memory_offset_16(bb::avm2::MemoryTag tag, uint32_t address_index)
std::map< bb::avm2::MemoryTag, std::vector< uint32_t > > stored_variables
MemoryManager & operator=(const MemoryManager &other)
std::optional< std::pair< ResolvedAddress, bb::avm2::testing::OperandBuilder > > get_resolved_address_and_operand_8(ParamRef address)
std::map< uint32_t, bb::avm2::MemoryTag > memory_address_to_tag
ResolvedAddress resolve_address(VariableRef address, uint32_t absolute_address, uint32_t max_operand_address)
std::optional< bb::avm2::FF > get_slot(uint16_t slot_offset_index)
bool is_memory_address_set(uint16_t address)
void set_memory_address(bb::avm2::MemoryTag tag, uint32_t address)
void append_slot(bb::avm2::FF slot)
void set_base_offset(uint32_t base_offset)
std::optional< uint8_t > get_memory_offset_8(bb::avm2::MemoryTag tag, uint32_t address_index)
std::optional< uint32_t > get_variable_address(bb::avm2::MemoryTag tag, uint32_t index, uint32_t min_value, uint32_t max_value)
std::vector< bb::avm2::FF > storage_addresses
std::optional< std::pair< ResolvedAddress, bb::avm2::testing::OperandBuilder > > get_resolved_address_and_operand_16(ParamRef address)
std::variant< VariableRef, AddressRef > ParamRef
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Output of resolving an address in the memory manager In order to resolve a given absolute address wit...
uint32_t absolute_address
std::optional< uint32_t > pointer_address
AddressingModeWrapper mode
uint16_t pointer_address_seed
A seed for the generation of the pointer address Used for Indirect/IndirectRelative modes only.
OperandBuilder & indirect()
OperandBuilder & relative()