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)));
36 return literal_max_value;
42uint32_t trimmed_pointer_address(uint32_t pointer_address_seed, uint32_t max_operand_address)
44 return pointer_address_seed % (max_operand_address + 1);
47uint32_t trimmed_relative_operand_address(uint32_t base_offset_seed,
48 uint32_t relative_target,
49 uint32_t max_operand_address)
51 uint32_t max_operand = std::min(relative_target, max_operand_address);
52 return (base_offset_seed % (max_operand + 1));
55uint32_t trimmed_base_pointer(uint32_t base_offset_seed, uint32_t relative_target, uint32_t max_operand_address)
57 return relative_target - trimmed_relative_operand_address(base_offset_seed, relative_target, max_operand_address);
82 if (stored_tag ==
tag) {
95 uint32_t absolute_address,
96 uint32_t max_operand_address)
101 switch (variable.
mode) {
103 uint32_t trimmed_pointer_address_value =
111 trimmed_base_pointer(variable.
base_offset_seed, absolute_address, max_operand_address);
113 trimmed_relative_operand_address(variable.
base_offset_seed, absolute_address, max_operand_address);
128 return resolved_address;
140 uint32_t trimmed_pointer_address_value =
141 trimmed_pointer_address(
address.pointer_address_seed, max_operand_address);
156 trimmed_base_pointer(
address.base_offset_seed,
address.pointer_address_seed, max_operand_address);
158 address.base_offset_seed,
address.pointer_address_seed, max_operand_address);
167 return resolved_address;
201 if (!actual_address.has_value()) {
206 BB_ASSERT_LTE(resolved_address.operand_address, uint32_t{ 255 });
208 auto operand = OperandBuilder::from<uint8_t>(
static_cast<uint8_t
>(resolved_address.operand_address));
217 auto operand = OperandBuilder::from<uint8_t>(
static_cast<uint8_t
>(resolved_address.operand_address));
232 auto actual_address =
234 if (!actual_address.has_value()) {
240 BB_ASSERT_LTE(resolved_address.operand_address, uint32_t{ 65535 });
241 auto operand = OperandBuilder::from<uint16_t>(
static_cast<uint16_t
>(resolved_address.operand_address));
249 auto operand = OperandBuilder::from<uint16_t>(
static_cast<uint16_t
>(resolved_address.operand_address));
255 return get_nth_filtered(this->
stored_variables[tag], [max_value](uint32_t val) {
return val <= max_value; },
index);
261 if (!
value.has_value()) {
265 return static_cast<uint8_t
>(
value.value());
271 if (!
value.has_value()) {
275 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::vector< bb::avm2::FF > emitted_note_hashes
std::optional< bb::avm2::FF > get_emitted_note_hash(uint16_t note_hash_index)
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)
std::optional< uint16_t > get_leaf_index(uint16_t note_hash_index)
void set_memory_address(bb::avm2::MemoryTag tag, uint32_t address)
void append_slot(bb::avm2::FF slot)
std::optional< uint32_t > get_variable_address(bb::avm2::MemoryTag tag, uint32_t index, uint32_t max_value)
std::optional< uint8_t > get_memory_offset_8(bb::avm2::MemoryTag tag, uint32_t address_index)
void append_emitted_note_hash(bb::avm2::FF note_hash)
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...
std::optional< uint32_t > base_pointer
uint32_t absolute_address
std::optional< uint32_t > pointer_address
AddressingModeWrapper mode
uint32_t base_offset_seed
A seed for the generation of the base offset Used for Relative/IndirectRelative modes only Sets M[0] ...
uint16_t pointer_address_seed
A seed for the generation of the pointer address Used for Indirect/IndirectRelative modes only.
OperandBuilder & indirect()
OperandBuilder & relative()