MMU: Replace TryReadResult and TryWriteResult with std::optional

This commit is contained in:
Pokechu22 2021-09-04 11:05:35 -07:00
parent 673f886a7e
commit 525e6b2194
3 changed files with 129 additions and 129 deletions

View File

@ -101,87 +101,87 @@ std::vector<u8> Cheats::GetValueAsByteVector(const Cheats::SearchValue& value)
namespace namespace
{ {
template <typename T> template <typename T>
static PowerPC::TryReadResult<T> static std::optional<PowerPC::ReadResult<T>>
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space); TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space);
template <> template <>
PowerPC::TryReadResult<u8> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<u8>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
return PowerPC::HostTryReadU8(addr, space); return PowerPC::HostTryReadU8(addr, space);
} }
template <> template <>
PowerPC::TryReadResult<u16> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<u16>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
return PowerPC::HostTryReadU16(addr, space); return PowerPC::HostTryReadU16(addr, space);
} }
template <> template <>
PowerPC::TryReadResult<u32> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<u32>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
return PowerPC::HostTryReadU32(addr, space); return PowerPC::HostTryReadU32(addr, space);
} }
template <> template <>
PowerPC::TryReadResult<u64> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<u64>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
return PowerPC::HostTryReadU64(addr, space); return PowerPC::HostTryReadU64(addr, space);
} }
template <> template <>
PowerPC::TryReadResult<s8> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<s8>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
auto tmp = PowerPC::HostTryReadU8(addr, space); auto tmp = PowerPC::HostTryReadU8(addr, space);
if (!tmp) if (!tmp)
return PowerPC::TryReadResult<s8>(); return std::nullopt;
return PowerPC::TryReadResult<s8>(tmp.translated, Common::BitCast<s8>(tmp.value)); return PowerPC::ReadResult<s8>(tmp->translated, Common::BitCast<s8>(tmp->value));
} }
template <> template <>
PowerPC::TryReadResult<s16> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<s16>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
auto tmp = PowerPC::HostTryReadU16(addr, space); auto tmp = PowerPC::HostTryReadU16(addr, space);
if (!tmp) if (!tmp)
return PowerPC::TryReadResult<s16>(); return std::nullopt;
return PowerPC::TryReadResult<s16>(tmp.translated, Common::BitCast<s16>(tmp.value)); return PowerPC::ReadResult<s16>(tmp->translated, Common::BitCast<s16>(tmp->value));
} }
template <> template <>
PowerPC::TryReadResult<s32> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<s32>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
auto tmp = PowerPC::HostTryReadU32(addr, space); auto tmp = PowerPC::HostTryReadU32(addr, space);
if (!tmp) if (!tmp)
return PowerPC::TryReadResult<s32>(); return std::nullopt;
return PowerPC::TryReadResult<s32>(tmp.translated, Common::BitCast<s32>(tmp.value)); return PowerPC::ReadResult<s32>(tmp->translated, Common::BitCast<s32>(tmp->value));
} }
template <> template <>
PowerPC::TryReadResult<s64> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<s64>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
auto tmp = PowerPC::HostTryReadU64(addr, space); auto tmp = PowerPC::HostTryReadU64(addr, space);
if (!tmp) if (!tmp)
return PowerPC::TryReadResult<s64>(); return std::nullopt;
return PowerPC::TryReadResult<s64>(tmp.translated, Common::BitCast<s64>(tmp.value)); return PowerPC::ReadResult<s64>(tmp->translated, Common::BitCast<s64>(tmp->value));
} }
template <> template <>
PowerPC::TryReadResult<float> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<float>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
return PowerPC::HostTryReadF32(addr, space); return PowerPC::HostTryReadF32(addr, space);
} }
template <> template <>
PowerPC::TryReadResult<double> TryReadValueFromEmulatedMemory(u32 addr, std::optional<PowerPC::ReadResult<double>>
PowerPC::RequestedAddressSpace space) TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
{ {
return PowerPC::HostTryReadF64(addr, space); return PowerPC::HostTryReadF64(addr, space);
} }
@ -230,11 +230,11 @@ Cheats::NewSearch(const std::vector<Cheats::MemoryRange>& memory_ranges,
if (!current_value) if (!current_value)
continue; continue;
if (validator(current_value.value)) if (validator(current_value->value))
{ {
auto& r = results.emplace_back(); auto& r = results.emplace_back();
r.m_value = current_value.value; r.m_value = current_value->value;
r.m_value_state = current_value.translated ? r.m_value_state = current_value->translated ?
Cheats::SearchResultValueState::ValueFromVirtualMemory : Cheats::SearchResultValueState::ValueFromVirtualMemory :
Cheats::SearchResultValueState::ValueFromPhysicalMemory; Cheats::SearchResultValueState::ValueFromPhysicalMemory;
r.m_address = addr; r.m_address = addr;
@ -284,11 +284,11 @@ Cheats::NextSearch(const std::vector<Cheats::SearchResult<T>>& previous_results,
// if the previous state was invalid we always update the value to avoid getting stuck in an // if the previous state was invalid we always update the value to avoid getting stuck in an
// invalid state // invalid state
if (!previous_result.IsValueValid() || if (!previous_result.IsValueValid() ||
validator(current_value.value, previous_result.m_value)) validator(current_value->value, previous_result.m_value))
{ {
auto& r = results.emplace_back(); auto& r = results.emplace_back();
r.m_value = current_value.value; r.m_value = current_value->value;
r.m_value_state = current_value.translated ? r.m_value_state = current_value->translated ?
Cheats::SearchResultValueState::ValueFromVirtualMemory : Cheats::SearchResultValueState::ValueFromVirtualMemory :
Cheats::SearchResultValueState::ValueFromPhysicalMemory; Cheats::SearchResultValueState::ValueFromPhysicalMemory;
r.m_address = addr; r.m_address = addr;

View File

@ -468,34 +468,35 @@ u32 HostRead_Instruction(const u32 address)
return ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address); return ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
} }
TryReadResult<u32> HostTryReadInstruction(const u32 address, RequestedAddressSpace space) std::optional<ReadResult<u32>> HostTryReadInstruction(const u32 address,
RequestedAddressSpace space)
{ {
if (!HostIsInstructionRAMAddress(address, space)) if (!HostIsInstructionRAMAddress(address, space))
return TryReadResult<u32>(); return std::nullopt;
switch (space) switch (space)
{ {
case RequestedAddressSpace::Effective: case RequestedAddressSpace::Effective:
{ {
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address); const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
return TryReadResult<u32>(!!MSR.DR, value); return ReadResult<u32>(!!MSR.DR, value);
} }
case RequestedAddressSpace::Physical: case RequestedAddressSpace::Physical:
{ {
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32, true>(address); const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32, true>(address);
return TryReadResult<u32>(false, value); return ReadResult<u32>(false, value);
} }
case RequestedAddressSpace::Virtual: case RequestedAddressSpace::Virtual:
{ {
if (!MSR.DR) if (!MSR.DR)
return TryReadResult<u32>(); return std::nullopt;
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address); const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
return TryReadResult<u32>(true, value); return ReadResult<u32>(true, value);
} }
} }
ASSERT(0); ASSERT(0);
return TryReadResult<u32>(); return std::nullopt;
} }
static void Memcheck(u32 address, u64 var, bool write, size_t size) static void Memcheck(u32 address, u64 var, bool write, size_t size)
@ -574,70 +575,70 @@ float Read_F32(const u32 address)
} }
template <typename T> template <typename T>
static TryReadResult<T> HostTryReadUX(const u32 address, RequestedAddressSpace space) static std::optional<ReadResult<T>> HostTryReadUX(const u32 address, RequestedAddressSpace space)
{ {
if (!HostIsRAMAddress(address, space)) if (!HostIsRAMAddress(address, space))
return TryReadResult<T>(); return std::nullopt;
switch (space) switch (space)
{ {
case RequestedAddressSpace::Effective: case RequestedAddressSpace::Effective:
{ {
T value = ReadFromHardware<XCheckTLBFlag::NoException, T>(address); T value = ReadFromHardware<XCheckTLBFlag::NoException, T>(address);
return TryReadResult<T>(!!MSR.DR, std::move(value)); return ReadResult<T>(!!MSR.DR, std::move(value));
} }
case RequestedAddressSpace::Physical: case RequestedAddressSpace::Physical:
{ {
T value = ReadFromHardware<XCheckTLBFlag::NoException, T, true>(address); T value = ReadFromHardware<XCheckTLBFlag::NoException, T, true>(address);
return TryReadResult<T>(false, std::move(value)); return ReadResult<T>(false, std::move(value));
} }
case RequestedAddressSpace::Virtual: case RequestedAddressSpace::Virtual:
{ {
if (!MSR.DR) if (!MSR.DR)
return TryReadResult<T>(); return std::nullopt;
T value = ReadFromHardware<XCheckTLBFlag::NoException, T>(address); T value = ReadFromHardware<XCheckTLBFlag::NoException, T>(address);
return TryReadResult<T>(true, std::move(value)); return ReadResult<T>(true, std::move(value));
} }
} }
ASSERT(0); ASSERT(0);
return TryReadResult<T>(); return std::nullopt;
} }
TryReadResult<u8> HostTryReadU8(u32 address, RequestedAddressSpace space) std::optional<ReadResult<u8>> HostTryReadU8(u32 address, RequestedAddressSpace space)
{ {
return HostTryReadUX<u8>(address, space); return HostTryReadUX<u8>(address, space);
} }
TryReadResult<u16> HostTryReadU16(u32 address, RequestedAddressSpace space) std::optional<ReadResult<u16>> HostTryReadU16(u32 address, RequestedAddressSpace space)
{ {
return HostTryReadUX<u16>(address, space); return HostTryReadUX<u16>(address, space);
} }
TryReadResult<u32> HostTryReadU32(u32 address, RequestedAddressSpace space) std::optional<ReadResult<u32>> HostTryReadU32(u32 address, RequestedAddressSpace space)
{ {
return HostTryReadUX<u32>(address, space); return HostTryReadUX<u32>(address, space);
} }
TryReadResult<u64> HostTryReadU64(u32 address, RequestedAddressSpace space) std::optional<ReadResult<u64>> HostTryReadU64(u32 address, RequestedAddressSpace space)
{ {
return HostTryReadUX<u64>(address, space); return HostTryReadUX<u64>(address, space);
} }
TryReadResult<float> HostTryReadF32(u32 address, RequestedAddressSpace space) std::optional<ReadResult<float>> HostTryReadF32(u32 address, RequestedAddressSpace space)
{ {
const auto result = HostTryReadUX<u32>(address, space); const auto result = HostTryReadUX<u32>(address, space);
if (!result) if (!result)
return TryReadResult<float>(); return std::nullopt;
return TryReadResult<float>(result.translated, Common::BitCast<float>(result.value)); return ReadResult<float>(result->translated, Common::BitCast<float>(result->value));
} }
TryReadResult<double> HostTryReadF64(u32 address, RequestedAddressSpace space) std::optional<ReadResult<double>> HostTryReadF64(u32 address, RequestedAddressSpace space)
{ {
const auto result = HostTryReadUX<u64>(address, space); const auto result = HostTryReadUX<u64>(address, space);
if (!result) if (!result)
return TryReadResult<double>(); return std::nullopt;
return TryReadResult<double>(result.translated, Common::BitCast<double>(result.value)); return ReadResult<double>(result->translated, Common::BitCast<double>(result->value));
} }
u32 Read_U8_ZX(const u32 address) u32 Read_U8_ZX(const u32 address)
@ -763,62 +764,68 @@ void HostWrite_F64(const double var, const u32 address)
HostWrite_U64(integral, address); HostWrite_U64(integral, address);
} }
static TryWriteResult HostTryWriteUX(const u32 var, const u32 address, const u32 size, static std::optional<WriteResult> HostTryWriteUX(const u32 var, const u32 address, const u32 size,
RequestedAddressSpace space) RequestedAddressSpace space)
{ {
if (!HostIsRAMAddress(address, space)) if (!HostIsRAMAddress(address, space))
return TryWriteResult(); return std::nullopt;
switch (space) switch (space)
{ {
case RequestedAddressSpace::Effective: case RequestedAddressSpace::Effective:
WriteToHardware<XCheckTLBFlag::NoException>(address, var, size); WriteToHardware<XCheckTLBFlag::NoException>(address, var, size);
return TryWriteResult(!!MSR.DR); return WriteResult(!!MSR.DR);
case RequestedAddressSpace::Physical: case RequestedAddressSpace::Physical:
WriteToHardware<XCheckTLBFlag::NoException, true>(address, var, size); WriteToHardware<XCheckTLBFlag::NoException, true>(address, var, size);
return TryWriteResult(false); return WriteResult(false);
case RequestedAddressSpace::Virtual: case RequestedAddressSpace::Virtual:
if (!MSR.DR) if (!MSR.DR)
return TryWriteResult(); return std::nullopt;
WriteToHardware<XCheckTLBFlag::NoException>(address, var, size); WriteToHardware<XCheckTLBFlag::NoException>(address, var, size);
return TryWriteResult(true); return WriteResult(true);
} }
ASSERT(0); ASSERT(0);
return TryWriteResult(); return std::nullopt;
} }
TryWriteResult HostTryWriteU8(const u32 var, const u32 address, RequestedAddressSpace space) std::optional<WriteResult> HostTryWriteU8(const u32 var, const u32 address,
RequestedAddressSpace space)
{ {
return HostTryWriteUX(var, address, 1, space); return HostTryWriteUX(var, address, 1, space);
} }
TryWriteResult HostTryWriteU16(const u32 var, const u32 address, RequestedAddressSpace space) std::optional<WriteResult> HostTryWriteU16(const u32 var, const u32 address,
RequestedAddressSpace space)
{ {
return HostTryWriteUX(var, address, 2, space); return HostTryWriteUX(var, address, 2, space);
} }
TryWriteResult HostTryWriteU32(const u32 var, const u32 address, RequestedAddressSpace space) std::optional<WriteResult> HostTryWriteU32(const u32 var, const u32 address,
RequestedAddressSpace space)
{ {
return HostTryWriteUX(var, address, 4, space); return HostTryWriteUX(var, address, 4, space);
} }
TryWriteResult HostTryWriteU64(const u64 var, const u32 address, RequestedAddressSpace space) std::optional<WriteResult> HostTryWriteU64(const u64 var, const u32 address,
RequestedAddressSpace space)
{ {
const TryWriteResult result = HostTryWriteUX(static_cast<u32>(var >> 32), address, 4, space); const auto result = HostTryWriteUX(static_cast<u32>(var >> 32), address, 4, space);
if (!result) if (!result)
return result; return result;
return HostTryWriteUX(static_cast<u32>(var), address + 4, 4, space); return HostTryWriteUX(static_cast<u32>(var), address + 4, 4, space);
} }
TryWriteResult HostTryWriteF32(const float var, const u32 address, RequestedAddressSpace space) std::optional<WriteResult> HostTryWriteF32(const float var, const u32 address,
RequestedAddressSpace space)
{ {
const u32 integral = Common::BitCast<u32>(var); const u32 integral = Common::BitCast<u32>(var);
return HostTryWriteU32(integral, address, space); return HostTryWriteU32(integral, address, space);
} }
TryWriteResult HostTryWriteF64(const double var, const u32 address, RequestedAddressSpace space) std::optional<WriteResult> HostTryWriteF64(const double var, const u32 address,
RequestedAddressSpace space)
{ {
const u64 integral = Common::BitCast<u64>(var); const u64 integral = Common::BitCast<u64>(var);
return HostTryWriteU64(integral, address, space); return HostTryWriteU64(integral, address, space);
@ -840,25 +847,26 @@ std::string HostGetString(u32 address, size_t size)
return s; return s;
} }
TryReadResult<std::string> HostTryReadString(u32 address, size_t size, RequestedAddressSpace space) std::optional<ReadResult<std::string>> HostTryReadString(u32 address, size_t size,
RequestedAddressSpace space)
{ {
auto c = HostTryReadU8(address, space); auto c = HostTryReadU8(address, space);
if (!c) if (!c)
return TryReadResult<std::string>(); return std::nullopt;
if (c.value == 0) if (c->value == 0)
return TryReadResult<std::string>(c.translated, ""); return ReadResult<std::string>(c->translated, "");
std::string s; std::string s;
s += static_cast<char>(c.value); s += static_cast<char>(c->value);
while (size == 0 || s.length() < size) while (size == 0 || s.length() < size)
{ {
++address; ++address;
const auto res = HostTryReadU8(address, space); const auto res = HostTryReadU8(address, space);
if (!res || res.value == 0) if (!res || res->value == 0)
break; break;
s += static_cast<char>(res.value); s += static_cast<char>(res->value);
} }
return TryReadResult<std::string>(c.translated, std::move(s)); return ReadResult<std::string>(c->translated, std::move(s));
} }
bool IsOptimizableRAMAddress(const u32 address) bool IsOptimizableRAMAddress(const u32 address)

View File

@ -37,11 +37,8 @@ u32 HostRead_Instruction(u32 address);
std::string HostGetString(u32 address, size_t size = 0); std::string HostGetString(u32 address, size_t size = 0);
template <typename T> template <typename T>
struct TryReadResult struct ReadResult
{ {
// whether the read succeeded; if false, the other fields should not be touched
bool success;
// whether the address had to be translated (given address was treated as virtual) or not (given // whether the address had to be translated (given address was treated as virtual) or not (given
// address was treated as physical) // address was treated as physical)
bool translated; bool translated;
@ -49,37 +46,31 @@ struct TryReadResult
// the actual value that was read // the actual value that was read
T value; T value;
TryReadResult() : success(false) {} ReadResult(bool translated_, T&& value_) : translated(translated_), value(std::forward<T>(value_))
TryReadResult(bool translated_, T&& value_)
: success(true), translated(translated_), value(std::move(value_))
{ {
} }
TryReadResult(bool translated_, const T& value_) ReadResult(bool translated_, const T& value_) : translated(translated_), value(value_) {}
: success(true), translated(translated_), value(value_)
{
}
explicit operator bool() const { return success; }
}; };
// Try to read a value from emulated memory at the given address in the given memory space. // Try to read a value from emulated memory at the given address in the given memory space.
// If the read succeeds, the returned TryReadResult contains the read value and information on // If the read succeeds, the returned value will be present and the ReadResult contains the read
// whether the given address had to be translated or not. Unlike the HostRead functions, this does // value and information on whether the given address had to be translated or not. Unlike the
// not raise a user-visible alert on failure. // HostRead functions, this does not raise a user-visible alert on failure.
TryReadResult<u8> HostTryReadU8(u32 address, std::optional<ReadResult<u8>>
RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryReadU8(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryReadResult<u16> HostTryReadU16(u32 address, std::optional<ReadResult<u16>>
RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryReadU16(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryReadResult<u32> HostTryReadU32(u32 address, std::optional<ReadResult<u32>>
RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryReadU32(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryReadResult<u64> HostTryReadU64(u32 address, std::optional<ReadResult<u64>>
RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryReadU64(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryReadResult<float> HostTryReadF32(u32 address, std::optional<ReadResult<float>>
RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryReadF32(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryReadResult<double> std::optional<ReadResult<double>>
HostTryReadF64(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryReadF64(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryReadResult<u32> std::optional<ReadResult<u32>>
HostTryReadInstruction(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryReadInstruction(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryReadResult<std::string> std::optional<ReadResult<std::string>>
HostTryReadString(u32 address, size_t size = 0, HostTryReadString(u32 address, size_t size = 0,
RequestedAddressSpace space = RequestedAddressSpace::Effective); RequestedAddressSpace space = RequestedAddressSpace::Effective);
@ -93,36 +84,37 @@ void HostWrite_U64(u64 var, u32 address);
void HostWrite_F32(float var, u32 address); void HostWrite_F32(float var, u32 address);
void HostWrite_F64(double var, u32 address); void HostWrite_F64(double var, u32 address);
struct TryWriteResult struct WriteResult
{ {
// whether the write succeeded; if false, the other fields should not be touched
bool success;
// whether the address had to be translated (given address was treated as virtual) or not (given // whether the address had to be translated (given address was treated as virtual) or not (given
// address was treated as physical) // address was treated as physical)
bool translated; bool translated;
TryWriteResult() : success(false) {} explicit WriteResult(bool translated_) : translated(translated_) {}
TryWriteResult(bool translated_) : success(true), translated(translated_) {}
explicit operator bool() const { return success; }
}; };
// Try to a write a value to memory at the given address in the given memory space. // Try to a write a value to memory at the given address in the given memory space.
// If the write succeeds, the returned TryWriteResult contains information on whether the given // If the write succeeds, the returned TryWriteResult contains information on whether the given
// address had to be translated or not. Unlike the HostWrite functions, this does not raise a // address had to be translated or not. Unlike the HostWrite functions, this does not raise a
// user-visible alert on failure. // user-visible alert on failure.
TryWriteResult HostTryWriteU8(u32 var, const u32 address, std::optional<WriteResult>
RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryWriteU8(u32 var, const u32 address,
TryWriteResult HostTryWriteU16(u32 var, const u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
RequestedAddressSpace space = RequestedAddressSpace::Effective); std::optional<WriteResult>
TryWriteResult HostTryWriteU32(u32 var, const u32 address, HostTryWriteU16(u32 var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective); RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryWriteResult HostTryWriteU64(u64 var, const u32 address, std::optional<WriteResult>
RequestedAddressSpace space = RequestedAddressSpace::Effective); HostTryWriteU32(u32 var, const u32 address,
TryWriteResult HostTryWriteF32(float var, const u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
RequestedAddressSpace space = RequestedAddressSpace::Effective); std::optional<WriteResult>
TryWriteResult HostTryWriteF64(double var, const u32 address, HostTryWriteU64(u64 var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective); RequestedAddressSpace space = RequestedAddressSpace::Effective);
std::optional<WriteResult>
HostTryWriteF32(float var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
std::optional<WriteResult>
HostTryWriteF64(double var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
// Returns whether a read or write to the given address will resolve to a RAM access in the given // Returns whether a read or write to the given address will resolve to a RAM access in the given
// address space. // address space.