mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-25 16:10:57 +00:00
New floats format, STAmount compatible (#6600)
This commit is contained in:
@@ -249,6 +249,7 @@ words:
|
||||
- STATSDCOLLECTOR
|
||||
- stissue
|
||||
- stnum
|
||||
- stnumber
|
||||
- stobj
|
||||
- stobject
|
||||
- stpath
|
||||
|
||||
@@ -381,6 +381,9 @@ public:
|
||||
friend Number
|
||||
root2(Number f);
|
||||
|
||||
friend Number
|
||||
log10(Number const&, int);
|
||||
|
||||
// Thread local rounding control. Default is to_nearest
|
||||
enum rounding_mode { to_nearest, towards_zero, downward, upward };
|
||||
static rounding_mode
|
||||
|
||||
@@ -37,6 +37,8 @@ enum class HostFunctionError : int32_t {
|
||||
OUT_OF_GAS = -22,
|
||||
};
|
||||
|
||||
using FloatPair = std::pair<int64_t, int32_t>;
|
||||
|
||||
inline int32_t
|
||||
HfErrorToInt(HostFunctionError e)
|
||||
{
|
||||
@@ -54,6 +56,24 @@ floatFromIntImpl(int64_t x, int32_t mode);
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromUintImpl(uint64_t x, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromSTAmountImpl(STAmount const& x, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromSTNumberImpl(STNumber const& x, int32_t mode);
|
||||
|
||||
Expected<int64_t, HostFunctionError>
|
||||
floatToIntImpl(Slice const& x, int32_t mode);
|
||||
|
||||
Expected<FloatPair, HostFunctionError>
|
||||
floatToMantissaAndExponentImpl(Slice const& x);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatNegateImpl(Slice const& x);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatAbsImpl(Slice const& x);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatSetImpl(int64_t mantissa, int32_t exponent, int32_t mode);
|
||||
|
||||
@@ -440,6 +460,42 @@ struct HostFunctions
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromSTAmount(STAmount const& x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromSTNumber(STNumber const& x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int64_t, HostFunctionError>
|
||||
floatToInt(Slice const& x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<FloatPair, HostFunctionError>
|
||||
floatToMantissaAndExponent(Slice const& x) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatNegate(Slice const& x) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatAbs(Slice const& x) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const
|
||||
{
|
||||
|
||||
@@ -254,6 +254,24 @@ public:
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromUint(uint64_t x, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromSTAmount(STAmount const& x, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromSTNumber(STNumber const& x, int32_t mode) const override;
|
||||
|
||||
Expected<int64_t, HostFunctionError>
|
||||
floatToInt(Slice const& x, int32_t mode) const override;
|
||||
|
||||
Expected<FloatPair, HostFunctionError>
|
||||
floatToMantissaAndExponent(Slice const& x) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatNegate(Slice const& x) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatAbs(Slice const& x) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const override;
|
||||
|
||||
@@ -282,14 +300,4 @@ public:
|
||||
floatLog(Slice const& x, int32_t mode) const override;
|
||||
};
|
||||
|
||||
namespace wasm_float {
|
||||
|
||||
// The range for the mantissa and exponent when normalized
|
||||
static std::int64_t constexpr wasmMinMantissa = 1'000'000'000'000'000ll;
|
||||
static std::int64_t constexpr wasmMaxMantissa = wasmMinMantissa * 10 - 1;
|
||||
static int constexpr wasmMinExponent = -96;
|
||||
static int constexpr wasmMaxExponent = 80;
|
||||
|
||||
} // namespace wasm_float
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -260,6 +260,31 @@ using floatFromUint_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t,
|
||||
wasm_trap_t*
|
||||
floatFromUint_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatFromSTAmount_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromSTAmount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatFromSTNumber_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromSTNumber_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatToInt_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatToInt_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatToMantissaAndExponent_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
floatToMantissaAndExponent_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatNegate_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
floatNegate_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatAbs_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
floatAbs_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatSet_proto = int32_t(int32_t, int64_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatSet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
@@ -949,10 +949,10 @@ power(Number const& f, unsigned n)
|
||||
static Number
|
||||
ln(Number const& x, int iterations = 50)
|
||||
{
|
||||
static Number const N0(0);
|
||||
static Number const N2(2, 0);
|
||||
static Number const N05(5, -1);
|
||||
static Number const LN2(693'147'180'559'945'309ll, -18);
|
||||
Number const N0(0);
|
||||
Number const N2(2, 0);
|
||||
Number const N05(5, -1);
|
||||
Number const LN2(693'147'180'559'945'309ll, -18);
|
||||
|
||||
if (x <= 0)
|
||||
{
|
||||
@@ -993,8 +993,8 @@ ln(Number const& x, int iterations = 50)
|
||||
Number
|
||||
log10(Number const& x, int iterations)
|
||||
{
|
||||
static Number const N0(0);
|
||||
static Number const LN10(2'302'585'092'994'046ll, -15);
|
||||
Number const N0(0);
|
||||
Number const LN10(2'302'585'092'994'045'684ll, -18);
|
||||
|
||||
if (x <= 0)
|
||||
{
|
||||
@@ -1012,8 +1012,9 @@ log10(Number const& x, int iterations)
|
||||
}
|
||||
|
||||
// (1 <= normalX < 10)
|
||||
// x = normalX * 10^norm
|
||||
// ln(x) = ln(normalX * 10^norm) = ln(normalX) + norm * ln(10)
|
||||
int const diffExp = 15 + x.exponent();
|
||||
int const diffExp = Number::mantissaLog() + x.exponent_;
|
||||
Number const normalX = x / Number(1, diffExp);
|
||||
auto const lnX = ln(normalX, iterations) + diffExp * LN10;
|
||||
auto const lgX = lnX / LN10;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STBitString.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/tx/wasm/HostFuncImpl.h>
|
||||
|
||||
@@ -12,137 +14,78 @@ namespace wasm_float {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class Number2 : public Number
|
||||
class WasmNumber : public Number
|
||||
{
|
||||
protected:
|
||||
static Bytes const floatNull;
|
||||
static unsigned constexpr encodedFloatSize = 8;
|
||||
static int32_t constexpr encodedMantissaBits = 54;
|
||||
static int32_t constexpr encodedExponentBits = 8;
|
||||
|
||||
static_assert(wasmMinExponent < 0);
|
||||
|
||||
static uint64_t constexpr maxEncodedMantissa = (1ull << (encodedMantissaBits + 1)) - 1;
|
||||
|
||||
bool good_;
|
||||
static unsigned constexpr encodedFloatSize = 12;
|
||||
bool good_ = false;
|
||||
|
||||
public:
|
||||
Number2(Slice const& data) : good_(false)
|
||||
WasmNumber(Slice const& data)
|
||||
{
|
||||
if (data.size() != encodedFloatSize)
|
||||
return;
|
||||
|
||||
if (std::ranges::equal(floatNull, data))
|
||||
try
|
||||
{
|
||||
SerialIter it(data);
|
||||
Number const x = STNumber(it, sfNumber).value();
|
||||
*static_cast<Number*>(this) = x;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
good_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t const v = SerialIter(data).get64();
|
||||
if ((v & STAmount::cIssuedCurrency) == 0u)
|
||||
return;
|
||||
|
||||
int32_t const e = static_cast<int32_t>((v >> encodedMantissaBits) & 0xFFull);
|
||||
int32_t const decodedExponent = e + wasmMinExponent - 1; // e - 97
|
||||
if (decodedExponent < wasmMinExponent || decodedExponent > wasmMaxExponent)
|
||||
return;
|
||||
|
||||
int64_t const neg = ((v & STAmount::cPositive) != 0u) ? 1 : -1;
|
||||
int64_t const m = neg * static_cast<int64_t>(v & ((1ull << encodedMantissaBits) - 1));
|
||||
if (m == 0)
|
||||
return;
|
||||
|
||||
Number const x(makeNumber(m, decodedExponent));
|
||||
if (m != x.mantissa() || decodedExponent != x.exponent())
|
||||
return; // not canonical
|
||||
*static_cast<Number*>(this) = x;
|
||||
|
||||
good_ = true;
|
||||
}
|
||||
|
||||
WasmNumber(Number const& n) : WasmNumber(n.mantissa(), n.exponent()) // ensure Number canonized
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Number2(T mantissa = 0, int32_t exponent = 0) : Number(), good_(false)
|
||||
WasmNumber(T mantissa = 0, int32_t exponent = 0)
|
||||
{
|
||||
if (!mantissa)
|
||||
try
|
||||
{
|
||||
Number n;
|
||||
if constexpr (std::is_signed_v<T>)
|
||||
{
|
||||
n = Number(static_cast<int64_t>(mantissa), exponent);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = Number(static_cast<uint64_t>(mantissa), exponent, Number::normalized());
|
||||
}
|
||||
*static_cast<Number*>(this) = n;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
good_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
auto const n = makeNumber(mantissa, exponent);
|
||||
auto const e = n.exponent();
|
||||
if (e < wasmMinExponent)
|
||||
{
|
||||
good_ = true; // value is zero(as in Numbers behavior)
|
||||
return;
|
||||
}
|
||||
|
||||
if (e > wasmMaxExponent)
|
||||
return;
|
||||
|
||||
*static_cast<Number*>(this) = n;
|
||||
good_ = true;
|
||||
}
|
||||
|
||||
Number2(Number const& n) : Number2(n.mantissa(), n.exponent()) // ensure Number canonized
|
||||
{
|
||||
}
|
||||
|
||||
static Number
|
||||
makeNumber(int64_t mantissa, int32_t exponent)
|
||||
{
|
||||
if (mantissa < 0)
|
||||
return Number(true, -static_cast<uint64_t>(mantissa), exponent, Number::normalized());
|
||||
return Number(false, mantissa, exponent, Number::normalized());
|
||||
}
|
||||
|
||||
static Number
|
||||
makeNumber(uint64_t mantissa, int32_t exponent)
|
||||
{
|
||||
return Number(false, mantissa, exponent, Number::normalized());
|
||||
}
|
||||
WasmNumber&
|
||||
operator=(WasmNumber const&) = default;
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return good_;
|
||||
}
|
||||
|
||||
explicit
|
||||
operator int64_t() const
|
||||
{
|
||||
return Number::operator int64_t();
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
toBytes() const
|
||||
{
|
||||
if (!good_)
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
|
||||
auto const m = mantissa();
|
||||
auto const e = exponent();
|
||||
|
||||
uint64_t v = m >= 0 ? STAmount::cPositive : 0;
|
||||
v |= STAmount::cIssuedCurrency;
|
||||
|
||||
uint64_t const absM = std::abs(m);
|
||||
if (absM == 0u)
|
||||
{
|
||||
return floatNull;
|
||||
}
|
||||
if (absM > maxEncodedMantissa)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); // LCOV_EXCL_LINE
|
||||
}
|
||||
v |= absM;
|
||||
|
||||
if (e > wasmMaxExponent)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
if (e < wasmMinExponent)
|
||||
{
|
||||
return floatNull;
|
||||
}
|
||||
uint64_t const normExp = e - wasmMinExponent + 1; //+97
|
||||
v |= normExp << encodedMantissaBits;
|
||||
|
||||
Serializer msg;
|
||||
msg.add64(v);
|
||||
STNumber(sfNumber, *this).add(msg);
|
||||
auto data = msg.getData();
|
||||
|
||||
#ifdef DEBUG_OUTPUT
|
||||
@@ -153,33 +96,26 @@ public:
|
||||
std::cout << std::setw(2) << (unsigned)c << " ";
|
||||
std::cout << std::dec << std::setfill(' ') << std::endl;
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
Bytes const Number2::floatNull = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
struct FloatState
|
||||
{
|
||||
Number::rounding_mode oldMode_;
|
||||
MantissaRange::mantissa_scale oldScale_;
|
||||
bool good_{false};
|
||||
bool good_ = false;
|
||||
|
||||
FloatState(int32_t mode) : oldMode_(Number::getround()), oldScale_(Number::getMantissaScale())
|
||||
FloatState(int32_t mode) : oldMode_(Number::getround())
|
||||
{
|
||||
if (mode < Number::rounding_mode::to_nearest || mode > Number::rounding_mode::upward)
|
||||
return;
|
||||
|
||||
Number::setround(static_cast<Number::rounding_mode>(mode));
|
||||
Number::setMantissaScale(MantissaRange::mantissa_scale::small);
|
||||
good_ = true;
|
||||
}
|
||||
|
||||
~FloatState()
|
||||
{
|
||||
Number::setround(oldMode_);
|
||||
Number::setMantissaScale(oldScale_);
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
@@ -195,7 +131,7 @@ floatToString(Slice const& data)
|
||||
{
|
||||
// set default mode as we don't expect it will be used here
|
||||
detail::FloatState const rm(Number::rounding_mode::to_nearest);
|
||||
detail::Number2 const num(data);
|
||||
detail::WasmNumber const num(data);
|
||||
if (!num)
|
||||
{
|
||||
std::string hex;
|
||||
@@ -203,7 +139,6 @@ floatToString(Slice const& data)
|
||||
boost::algorithm::hex(data.begin(), data.end(), std::back_inserter(hex));
|
||||
return "Invalid data: " + hex;
|
||||
}
|
||||
|
||||
auto const s = to_string(num);
|
||||
return s;
|
||||
}
|
||||
@@ -217,15 +152,17 @@ floatFromIntImpl(int64_t x, int32_t mode)
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 const num(x);
|
||||
return num.toBytes();
|
||||
detail::WasmNumber const num(x);
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); // LCOV_EXCL_LINE
|
||||
auto const r = num.toBytes();
|
||||
return r;
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
catch (...)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -238,8 +175,10 @@ floatFromUintImpl(uint64_t x, int32_t mode)
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 const num(x);
|
||||
auto r = num.toBytes();
|
||||
detail::WasmNumber const num(x);
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); // LCOV_EXCL_LINE
|
||||
auto const r = num.toBytes();
|
||||
return r;
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
@@ -247,7 +186,146 @@ floatFromUintImpl(uint64_t x, int32_t mode)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromSTAmountImpl(STAmount const& x, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::FloatState const rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::WasmNumber const num(static_cast<Number>(x));
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); // LCOV_EXCL_LINE
|
||||
auto const r = num.toBytes();
|
||||
return r;
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
catch (...)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromSTNumberImpl(STNumber const& x, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::FloatState const rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::WasmNumber const num(x.value());
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); // LCOV_EXCL_LINE
|
||||
auto const r = num.toBytes();
|
||||
return r;
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
catch (...)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
Expected<int64_t, HostFunctionError>
|
||||
floatToIntImpl(Slice const& x, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::FloatState const rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::WasmNumber const num(x);
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); // LCOV_EXCL_LINE
|
||||
int64_t const r(num);
|
||||
return r;
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
catch (...)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
Expected<FloatPair, HostFunctionError>
|
||||
floatToMantissaAndExponentImpl(Slice const& x)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::FloatState const rm(Number::rounding_mode::to_nearest);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::WasmNumber const num(x);
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); // LCOV_EXCL_LINE
|
||||
|
||||
return FloatPair(num.mantissa(), num.exponent());
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
catch (...)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatNegateImpl(Slice const& x)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::FloatState const rm(Number::rounding_mode::to_nearest);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::WasmNumber const num(x);
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::WasmNumber const res = -num;
|
||||
return res.toBytes();
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
catch (...)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatAbsImpl(Slice const& x)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::FloatState const rm(Number::rounding_mode::to_nearest);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::WasmNumber const num(x);
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::WasmNumber const res = abs(num);
|
||||
return res.toBytes();
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
catch (...)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -259,16 +337,15 @@ floatSetImpl(int64_t mantissa, int32_t exponent, int32_t mode)
|
||||
detail::FloatState const rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const num(mantissa, exponent);
|
||||
detail::WasmNumber const num(mantissa, exponent);
|
||||
if (!num)
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
return num.toBytes();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
@@ -278,10 +355,11 @@ floatCompareImpl(Slice const& x, Slice const& y)
|
||||
{
|
||||
// set default mode as we don't expect it will be used here
|
||||
detail::FloatState const rm(Number::rounding_mode::to_nearest);
|
||||
detail::Number2 const xx(x);
|
||||
|
||||
detail::WasmNumber const xx(x);
|
||||
if (!xx)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const yy(y);
|
||||
detail::WasmNumber const yy(y);
|
||||
if (!yy)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
if (xx < yy)
|
||||
@@ -295,7 +373,6 @@ floatCompareImpl(Slice const& x, Slice const& y)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -308,13 +385,13 @@ floatAddImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 const xx(x);
|
||||
detail::WasmNumber const xx(x);
|
||||
if (!xx)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const yy(y);
|
||||
detail::WasmNumber const yy(y);
|
||||
if (!yy)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const res = xx + yy;
|
||||
detail::WasmNumber const res = xx + yy;
|
||||
|
||||
return res.toBytes();
|
||||
}
|
||||
@@ -323,7 +400,6 @@ floatAddImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -335,13 +411,13 @@ floatSubtractImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
detail::FloatState const rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const xx(x);
|
||||
detail::WasmNumber const xx(x);
|
||||
if (!xx)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const yy(y);
|
||||
detail::WasmNumber const yy(y);
|
||||
if (!yy)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const res = xx - yy;
|
||||
detail::WasmNumber const res = xx - yy;
|
||||
|
||||
return res.toBytes();
|
||||
}
|
||||
@@ -350,7 +426,6 @@ floatSubtractImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -362,13 +437,13 @@ floatMultiplyImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
detail::FloatState const rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const xx(x);
|
||||
detail::WasmNumber const xx(x);
|
||||
if (!xx)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const yy(y);
|
||||
detail::WasmNumber const yy(y);
|
||||
if (!yy)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const res = xx * yy;
|
||||
detail::WasmNumber const res = xx * yy;
|
||||
|
||||
return res.toBytes();
|
||||
}
|
||||
@@ -377,7 +452,6 @@ floatMultiplyImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -389,13 +463,13 @@ floatDivideImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
detail::FloatState const rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const xx(x);
|
||||
detail::WasmNumber const xx(x);
|
||||
if (!xx)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const yy(y);
|
||||
detail::WasmNumber const yy(y);
|
||||
if (!yy)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 const res = xx / yy;
|
||||
detail::WasmNumber const res = xx / yy;
|
||||
|
||||
return res.toBytes();
|
||||
}
|
||||
@@ -403,7 +477,6 @@ floatDivideImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
@@ -418,11 +491,11 @@ floatRootImpl(Slice const& x, int32_t n, int32_t mode)
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 const xx(x);
|
||||
detail::WasmNumber const xx(x);
|
||||
if (!xx)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 const res(root(xx, n));
|
||||
detail::WasmNumber const res(root(xx, n));
|
||||
|
||||
return res.toBytes();
|
||||
}
|
||||
@@ -431,7 +504,6 @@ floatRootImpl(Slice const& x, int32_t n, int32_t mode)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -440,20 +512,20 @@ floatPowerImpl(Slice const& x, int32_t n, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((n < 0) || (n > wasmMaxExponent))
|
||||
if ((n < 0) || (n > Number::maxExponent))
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::FloatState const rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 const xx(x);
|
||||
detail::WasmNumber const xx(x);
|
||||
if (!xx)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
if (xx == Number() && (n == 0))
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
|
||||
detail::Number2 const res(power(xx, n, 1));
|
||||
detail::WasmNumber const res(power(xx, n, 1));
|
||||
|
||||
return res.toBytes();
|
||||
}
|
||||
@@ -462,7 +534,6 @@ floatPowerImpl(Slice const& x, int32_t n, int32_t mode)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -475,11 +546,11 @@ floatLogImpl(Slice const& x, int32_t mode)
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 const xx(x);
|
||||
detail::WasmNumber const xx(x);
|
||||
if (!xx)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 const res(log10(xx));
|
||||
detail::WasmNumber const res(log10(xx));
|
||||
|
||||
return res.toBytes();
|
||||
}
|
||||
@@ -488,7 +559,6 @@ floatLogImpl(Slice const& x, int32_t mode)
|
||||
{
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -510,6 +580,42 @@ WasmHostFunctionsImpl::floatFromUint(uint64_t x, int32_t mode) const
|
||||
return wasm_float::floatFromUintImpl(x, mode);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
WasmHostFunctionsImpl::floatFromSTAmount(STAmount const& x, int32_t mode) const
|
||||
{
|
||||
return wasm_float::floatFromSTAmountImpl(x, mode);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
WasmHostFunctionsImpl::floatFromSTNumber(STNumber const& x, int32_t mode) const
|
||||
{
|
||||
return wasm_float::floatFromSTNumberImpl(x, mode);
|
||||
}
|
||||
|
||||
Expected<int64_t, HostFunctionError>
|
||||
WasmHostFunctionsImpl::floatToInt(Slice const& x, int32_t mode) const
|
||||
{
|
||||
return wasm_float::floatToIntImpl(x, mode);
|
||||
}
|
||||
|
||||
Expected<FloatPair, HostFunctionError>
|
||||
WasmHostFunctionsImpl::floatToMantissaAndExponent(Slice const& x) const
|
||||
{
|
||||
return wasm_float::floatToMantissaAndExponentImpl(x);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
WasmHostFunctionsImpl::floatNegate(Slice const& x) const
|
||||
{
|
||||
return wasm_float::floatNegateImpl(x);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
WasmHostFunctionsImpl::floatAbs(Slice const& x) const
|
||||
{
|
||||
return wasm_float::floatAbsImpl(x);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
WasmHostFunctionsImpl::floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const
|
||||
{
|
||||
|
||||
@@ -90,6 +90,7 @@ getAnyFieldData(STBase const* obj)
|
||||
}
|
||||
|
||||
case STI_AMOUNT:
|
||||
case STI_NUMBER:
|
||||
default:
|
||||
break; // Use serializer
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ setData(
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<int32_t, HostFunctionError>
|
||||
static Expected<int32_t, HostFunctionError>
|
||||
getDataInt32(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
auto const result = params->data[i].of.i32;
|
||||
@@ -56,7 +56,7 @@ getDataInt32(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<int64_t, HostFunctionError>
|
||||
static Expected<int64_t, HostFunctionError>
|
||||
getDataInt64(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
auto const result = params->data[i].of.i64;
|
||||
@@ -65,7 +65,7 @@ getDataInt64(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
}
|
||||
|
||||
template <class T, class IW>
|
||||
Expected<T, HostFunctionError>
|
||||
static Expected<T, HostFunctionError>
|
||||
getDataUnsigned(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
static_assert(std::is_unsigned_v<T>);
|
||||
@@ -91,21 +91,21 @@ getDataUnsigned(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<uint32_t, HostFunctionError>
|
||||
static Expected<uint32_t, HostFunctionError>
|
||||
getDataUInt32(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
return getDataUnsigned<uint32_t>(runtime, params, i);
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<uint64_t, HostFunctionError>
|
||||
static Expected<uint64_t, HostFunctionError>
|
||||
getDataUInt64(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
return getDataUnsigned<uint64_t>(runtime, params, i);
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<SFieldCRef, HostFunctionError>
|
||||
static Expected<SFieldCRef, HostFunctionError>
|
||||
getDataSField(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
auto const& m = SField::getKnownCodeToField();
|
||||
@@ -119,7 +119,7 @@ getDataSField(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<Slice, HostFunctionError>
|
||||
static Expected<Slice, HostFunctionError>
|
||||
getDataSlice(IW const* runtime, wasm_val_vec_t const* params, int32_t& i, bool isUpdate = false)
|
||||
{
|
||||
int64_t const ptr = params->data[i].of.i32;
|
||||
@@ -148,7 +148,7 @@ getDataSlice(IW const* runtime, wasm_val_vec_t const* params, int32_t& i, bool i
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<uint256, HostFunctionError>
|
||||
static Expected<uint256, HostFunctionError>
|
||||
getDataUInt256(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
auto const slice = getDataSlice(runtime, params, i);
|
||||
@@ -165,7 +165,7 @@ getDataUInt256(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<AccountID, HostFunctionError>
|
||||
static Expected<AccountID, HostFunctionError>
|
||||
getDataAccountID(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
auto const slice = getDataSlice(runtime, params, i);
|
||||
@@ -240,7 +240,7 @@ getDataAsset(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
}
|
||||
|
||||
template <class IW>
|
||||
Expected<std::string_view, HostFunctionError>
|
||||
static Expected<std::string_view, HostFunctionError>
|
||||
getDataString(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
{
|
||||
auto const slice = getDataSlice(runtime, params, i);
|
||||
@@ -249,7 +249,7 @@ getDataString(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
return std::string_view(reinterpret_cast<char const*>(slice->data()), slice->size());
|
||||
}
|
||||
|
||||
std::nullptr_t
|
||||
static std::nullptr_t
|
||||
hfResult(wasm_val_vec_t* results, int32_t value)
|
||||
{
|
||||
results->data[0] = WASM_I32_VAL(value);
|
||||
@@ -257,7 +257,7 @@ hfResult(wasm_val_vec_t* results, int32_t value)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::nullptr_t
|
||||
static std::nullptr_t
|
||||
hfResult(wasm_val_vec_t* results, HostFunctionError value)
|
||||
{
|
||||
results->data[0] = WASM_I32_VAL(HfErrorToInt(value));
|
||||
@@ -266,7 +266,7 @@ hfResult(wasm_val_vec_t* results, HostFunctionError value)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::nullptr_t
|
||||
static std::nullptr_t
|
||||
returnResult(
|
||||
InstanceWrapper const* runtime,
|
||||
wasm_val_vec_t const* params,
|
||||
@@ -282,6 +282,9 @@ returnResult(
|
||||
using t = std::decay_t<decltype(*res)>;
|
||||
if constexpr (std::is_same_v<t, Bytes>)
|
||||
{
|
||||
if (index < 0 || index + 1 >= params->size)
|
||||
return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE
|
||||
|
||||
return hfResult(
|
||||
results,
|
||||
setData(
|
||||
@@ -293,6 +296,9 @@ returnResult(
|
||||
}
|
||||
else if constexpr (std::is_same_v<t, Hash>)
|
||||
{
|
||||
if (index < 0 || index + 1 >= params->size)
|
||||
return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE
|
||||
|
||||
return hfResult(
|
||||
results,
|
||||
setData(
|
||||
@@ -308,6 +314,9 @@ returnResult(
|
||||
}
|
||||
else if constexpr (std::is_same_v<t, std::uint32_t>)
|
||||
{
|
||||
if (index < 0 || index + 1 >= params->size)
|
||||
return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE
|
||||
|
||||
auto const resultValue = adjustWasmEndianess(res.value());
|
||||
return hfResult(
|
||||
results,
|
||||
@@ -318,6 +327,49 @@ returnResult(
|
||||
reinterpret_cast<uint8_t const*>(&resultValue),
|
||||
static_cast<int32_t>(sizeof(resultValue))));
|
||||
}
|
||||
else if constexpr (std::is_same_v<t, int64_t>)
|
||||
{
|
||||
if (index < 0 || index + 1 >= params->size)
|
||||
return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE
|
||||
|
||||
auto const resultValue = adjustWasmEndianess(res.value());
|
||||
return hfResult(
|
||||
results,
|
||||
setData(
|
||||
runtime,
|
||||
params->data[index].of.i32,
|
||||
params->data[index + 1].of.i32,
|
||||
reinterpret_cast<uint8_t const*>(&resultValue),
|
||||
static_cast<int32_t>(sizeof(resultValue))));
|
||||
}
|
||||
else if constexpr (std::is_same_v<t, FloatPair>)
|
||||
{
|
||||
if (index < 0 || index + 3 >= params->size)
|
||||
return hfResult(results, HostFunctionError::INTERNAL); // LCOV_EXCL_LINE
|
||||
|
||||
auto const mantissa = adjustWasmEndianess(res->first);
|
||||
auto const r1 = setData(
|
||||
runtime,
|
||||
params->data[index].of.i32,
|
||||
params->data[index + 1].of.i32,
|
||||
reinterpret_cast<uint8_t const*>(&mantissa),
|
||||
static_cast<int32_t>(sizeof(mantissa)));
|
||||
if (r1 < 0)
|
||||
return hfResult(results, r1);
|
||||
|
||||
index += 2;
|
||||
auto const exponent = adjustWasmEndianess(res->second);
|
||||
auto const r2 = setData(
|
||||
runtime,
|
||||
params->data[index].of.i32,
|
||||
params->data[index + 1].of.i32,
|
||||
reinterpret_cast<uint8_t const*>(&exponent),
|
||||
static_cast<int32_t>(sizeof(exponent)));
|
||||
if (r2 < 0)
|
||||
return hfResult(results, r2);
|
||||
|
||||
return hfResult(results, r1 + r2); // 12
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert([] { return false; }(), "Unhandled return type in returnResult");
|
||||
@@ -1568,6 +1620,149 @@ floatFromUint_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resu
|
||||
return returnResult(runtime, params, results, hf->floatFromUint(*x, *rounding), i);
|
||||
}
|
||||
|
||||
wasm_trap_t*
|
||||
floatFromSTAmount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
if (auto g = checkGas(env); !g)
|
||||
return g.error(); // LCOV_EXCL_LINE
|
||||
auto* hf = getHF(env);
|
||||
auto const* runtime = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
|
||||
int i = 0;
|
||||
auto const x = getDataSlice(runtime, params, i);
|
||||
if (!x)
|
||||
return hfResult(results, x.error());
|
||||
|
||||
auto serialIter = SerialIter(*x);
|
||||
std::optional<STAmount> amount;
|
||||
try
|
||||
{
|
||||
amount = STAmount(serialIter, sfGeneric);
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
amount = std::nullopt;
|
||||
}
|
||||
if (!amount)
|
||||
return hfResult(results, HostFunctionError::INVALID_PARAMS);
|
||||
|
||||
i = 4;
|
||||
auto const rounding = getDataInt32(runtime, params, i);
|
||||
if (!rounding)
|
||||
return hfResult(results, rounding.error()); // LCOV_EXCL_LINE
|
||||
|
||||
i = 2;
|
||||
return returnResult(runtime, params, results, hf->floatFromSTAmount(*amount, *rounding), i);
|
||||
}
|
||||
|
||||
wasm_trap_t*
|
||||
floatFromSTNumber_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
if (auto g = checkGas(env); !g)
|
||||
return g.error(); // LCOV_EXCL_LINE
|
||||
auto* hf = getHF(env);
|
||||
auto const* runtime = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
|
||||
int i = 0;
|
||||
auto const x = getDataSlice(runtime, params, i);
|
||||
if (!x)
|
||||
return hfResult(results, x.error());
|
||||
|
||||
auto serialIter = SerialIter(*x);
|
||||
std::optional<STNumber> num;
|
||||
try
|
||||
{
|
||||
num = STNumber(serialIter, sfGeneric);
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
num = std::nullopt;
|
||||
}
|
||||
if (!num)
|
||||
return hfResult(results, HostFunctionError::INVALID_PARAMS);
|
||||
|
||||
i = 4;
|
||||
auto const rounding = getDataInt32(runtime, params, i);
|
||||
if (!rounding)
|
||||
return hfResult(results, rounding.error()); // LCOV_EXCL_LINE
|
||||
|
||||
i = 2;
|
||||
return returnResult(runtime, params, results, hf->floatFromSTNumber(*num, *rounding), i);
|
||||
}
|
||||
|
||||
wasm_trap_t*
|
||||
floatToInt_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
if (auto g = checkGas(env); !g)
|
||||
return g.error(); // LCOV_EXCL_LINE
|
||||
auto* hf = getHF(env);
|
||||
auto const* runtime = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
|
||||
int i = 0;
|
||||
auto const x = getDataSlice(runtime, params, i);
|
||||
if (!x)
|
||||
return hfResult(results, x.error());
|
||||
|
||||
i = 4;
|
||||
auto const rounding = getDataInt32(runtime, params, i);
|
||||
if (!rounding)
|
||||
return hfResult(results, rounding.error()); // LCOV_EXCL_LINE
|
||||
|
||||
i = 2;
|
||||
return returnResult(runtime, params, results, hf->floatToInt(*x, *rounding), i);
|
||||
}
|
||||
|
||||
wasm_trap_t*
|
||||
floatToMantissaAndExponent_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
if (auto g = checkGas(env); !g)
|
||||
return g.error(); // LCOV_EXCL_LINE
|
||||
auto* hf = getHF(env);
|
||||
auto const* runtime = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
|
||||
int i = 0;
|
||||
auto const x = getDataSlice(runtime, params, i);
|
||||
if (!x)
|
||||
return hfResult(results, x.error());
|
||||
|
||||
i = 2;
|
||||
return returnResult(runtime, params, results, hf->floatToMantissaAndExponent(*x), i);
|
||||
}
|
||||
|
||||
wasm_trap_t*
|
||||
floatNegate_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
if (auto g = checkGas(env); !g)
|
||||
return g.error(); // LCOV_EXCL_LINE
|
||||
auto* hf = getHF(env);
|
||||
auto const* runtime = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
|
||||
int i = 0;
|
||||
auto const x = getDataSlice(runtime, params, i);
|
||||
if (!x)
|
||||
return hfResult(results, x.error());
|
||||
|
||||
i = 2;
|
||||
return returnResult(runtime, params, results, hf->floatNegate(*x), i);
|
||||
}
|
||||
|
||||
wasm_trap_t*
|
||||
floatAbs_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
if (auto g = checkGas(env); !g)
|
||||
return g.error(); // LCOV_EXCL_LINE
|
||||
auto* hf = getHF(env);
|
||||
auto const* runtime = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
|
||||
int i = 0;
|
||||
auto const x = getDataSlice(runtime, params, i);
|
||||
if (!x)
|
||||
return hfResult(results, x.error());
|
||||
|
||||
i = 2;
|
||||
return returnResult(runtime, params, results, hf->floatAbs(*x), i);
|
||||
}
|
||||
|
||||
wasm_trap_t*
|
||||
floatSet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
|
||||
@@ -76,6 +76,12 @@ setCommonHostFunctions(HostFunctions* hfs, ImportVec& i)
|
||||
|
||||
WASM_IMPORT_FUNC2(i, floatFromInt, "float_from_int", hfs, 100);
|
||||
WASM_IMPORT_FUNC2(i, floatFromUint, "float_from_uint", hfs, 130);
|
||||
WASM_IMPORT_FUNC2(i, floatFromSTAmount, "float_from_stamount", hfs, 150);
|
||||
WASM_IMPORT_FUNC2(i, floatFromSTNumber, "float_from_stnumber", hfs, 150);
|
||||
WASM_IMPORT_FUNC2(i, floatToInt, "float_to_int", hfs, 130);
|
||||
WASM_IMPORT_FUNC2(i, floatToMantissaAndExponent, "float_to_mantissa_and_exponent", hfs, 130);
|
||||
WASM_IMPORT_FUNC2(i, floatNegate, "float_negate", hfs, 150);
|
||||
WASM_IMPORT_FUNC2(i, floatAbs, "float_abs", hfs, 150);
|
||||
WASM_IMPORT_FUNC2(i, floatSet, "float_set", hfs, 100);
|
||||
WASM_IMPORT_FUNC2(i, floatCompare, "float_compare", hfs, 80);
|
||||
WASM_IMPORT_FUNC2(i, floatAdd, "float_add", hfs, 160);
|
||||
|
||||
@@ -2065,29 +2065,90 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
// clang-format off
|
||||
|
||||
int const normalExp = 15;
|
||||
int const normalExp = 18;
|
||||
|
||||
Bytes const floatIntMin = {0x99, 0x20, 0xc4, 0x9b, 0xa5, 0xe3, 0x53, 0xf8}; // -2^63
|
||||
Bytes const floatIntZero = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 0
|
||||
Bytes const floatIntMax = {0xd9, 0x20, 0xc4, 0x9b, 0xa5, 0xe3, 0x53, 0xf8}; // 2^63-1
|
||||
Bytes const floatUIntMax = {0xd9, 0x46, 0x8d, 0xb8, 0xba, 0xc7, 0x10, 0xcb}; // 2^64-1
|
||||
Bytes const floatMaxExp = {0xEC, 0x43, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1e(80+15)
|
||||
Bytes const floatPreMaxExp = {0xEC, 0x03, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1e(79+15)
|
||||
Bytes const floatMinusMaxExp = {0xAC, 0x43, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // -1e(80+15)
|
||||
Bytes const floatMaxIOU = {0xEC, 0x63, 0x86, 0xF2, 0x6F, 0xC0, 0xFF, 0xFF}; // 1e(81+15)-1
|
||||
Bytes const floatMinExp = {0xC0, 0x43, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1e-96
|
||||
Bytes const float1 = {0xD4, 0x83, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1
|
||||
Bytes const floatMinus1 = {0x94, 0x83, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // -1
|
||||
Bytes const float1More = {0xD4, 0x83, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x01}; // 1.000 000 000 000 001
|
||||
Bytes const float2 = {0xD4, 0x87, 0x1A, 0xFD, 0x49, 0x8D, 0x00, 0x00}; // 2
|
||||
Bytes const float10 = {0xD4, 0xC3, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 10
|
||||
Bytes const floatInvalidZero = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // INVALID
|
||||
Bytes const floatPi = {0xD4, 0x8B, 0x29, 0x43, 0x0A, 0x25, 0x6D, 0x21}; // 3.141592653589793
|
||||
Bytes const floatIntMin = {0xF3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x01}; // -2^63
|
||||
Bytes const floatIntZero = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00}; // 0
|
||||
Bytes const floatIntMax = {0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}; // 2^63-1
|
||||
Bytes const floatUIntMax = {0x19, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9A, 0x00, 0x00, 0x00, 0x01}; // 2^64-1
|
||||
|
||||
Bytes const floatMaxExp = {0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x64, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00}; // 1e(Number::maxExponent + normalExp)
|
||||
Bytes const floatPreMaxExp = {0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x64, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF}; // 1e(Number::maxExponent + normalExp - 1)
|
||||
Bytes const floatMinusMaxExp = {0xF2, 0x1F, 0x49, 0x4C, 0x58, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00}; // -1e(Number::maxExponent + normalExp)
|
||||
Bytes const floatMinExp = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00}; // 1e(Number::minExponent - normalExp)
|
||||
Bytes const floatMax = {0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x80, 0x00}; // Number::maxRep e(Number::maxExponent - normalExp)
|
||||
|
||||
Bytes const floatMaxIOU = {0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x63, 0xFF, 0x9C, 0x00, 0x00, 0x00, 0x4E}; // 9999999999999999e(96)
|
||||
Bytes const floatMinIOU = {0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x64, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x9D}; // 1e(-96 - 3 + normalExp = -81)
|
||||
|
||||
Bytes const float1 = {0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x64, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEE}; // 1
|
||||
Bytes const floatMinus1 = {0xF2, 0x1F, 0x49, 0x4C, 0x58, 0x9C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEE}; // -1
|
||||
Bytes const float1More = {0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x64, 0x03, 0xE8, 0xFF, 0xFF, 0xFF, 0xEE}; // 1.000 000 000 000 001
|
||||
Bytes const float2 = {0x1B, 0xC1, 0x6D, 0x67, 0x4E, 0xC8, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEE}; // 2
|
||||
Bytes const float10 = {0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x64, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEF}; // 10
|
||||
Bytes const floatPi = {0x2B, 0x99, 0x2D, 0xDF, 0xA2, 0x32, 0x48, 0xE8, 0xFF, 0xFF, 0xFF, 0xEE}; // 3.141592653589793
|
||||
Bytes const floatInvalidZero = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00}; // INVALID
|
||||
Bytes const floatMinus3 = {0xD6, 0x5D, 0xDB, 0xE5, 0x09, 0xD4, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEE}; // -3
|
||||
|
||||
std::string const invalid = "invalid_data";
|
||||
|
||||
// clang-format on
|
||||
|
||||
template <class T>
|
||||
void
|
||||
printFloats(std::string_view descr, T m, int e)
|
||||
{
|
||||
Serializer msg;
|
||||
Number n;
|
||||
|
||||
if constexpr (std::is_signed_v<T>)
|
||||
{
|
||||
n = Number(static_cast<int64_t>(m), e);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = Number(static_cast<uint64_t>(m), e, Number::normalized());
|
||||
}
|
||||
|
||||
STNumber(sfNumber, n).add(msg);
|
||||
auto const& data = msg.modData();
|
||||
std::cout << std::setw(24) << descr << " m: " << std::setw(20) << n.mantissa()
|
||||
<< ", e: " << std::setw(8) << n.exponent() << ", hex: ";
|
||||
std::cout << std::hex << std::uppercase << std::setfill('0');
|
||||
for (auto const& c : data)
|
||||
std::cout << std::setw(2) << (unsigned)c << " ";
|
||||
std::cout << std::dec << std::setfill(' ') << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
printNumbersBin()
|
||||
{
|
||||
printFloats("int64.min", std::numeric_limits<int64_t>::min(), 0);
|
||||
printFloats("zero", 0, 0);
|
||||
printFloats("int64.max", std::numeric_limits<int64_t>::max(), 0);
|
||||
printFloats("uint64.max", std::numeric_limits<uint64_t>::max(), 0);
|
||||
|
||||
printFloats("Number 1 max exp", 1, Number::maxExponent + normalExp);
|
||||
printFloats("Number (max exp - 1)", 1, Number::maxExponent + normalExp - 1);
|
||||
printFloats("Number -1 max exp", -1, Number::maxExponent + normalExp);
|
||||
|
||||
printFloats("Number.max", Number::maxRep, Number::maxExponent);
|
||||
printFloats("Number min positive", 1, Number::minExponent + normalExp);
|
||||
printFloats(
|
||||
"Number.min", std::numeric_limits<int64_t>::min(), Number::maxExponent - normalExp);
|
||||
printFloats("STAmount.max", STAmount::cMaxValue, STAmount::cMaxOffset);
|
||||
printFloats("STAmount min positive", STAmount::cMinValue, STAmount::cMinOffset);
|
||||
|
||||
printFloats("one", 1, 0);
|
||||
printFloats("-one", -1, 0);
|
||||
printFloats("1,00...01", 1'000'000'000'000'001, -15);
|
||||
printFloats("two", 2, 0);
|
||||
printFloats("ten", 10, 0);
|
||||
printFloats("pi", 3141592653589793, -15);
|
||||
printFloats("-three", -3, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
testTraceFloat()
|
||||
{
|
||||
@@ -2236,38 +2297,38 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(1, wasmMaxExponent + normalExp + 1, 0);
|
||||
auto const result = hfs.floatSet(1, Number::maxExponent + normalExp + 1, 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(1, wasmMinExponent + normalExp - 1, 0);
|
||||
auto const result = hfs.floatSet(1, Number::minExponent + normalExp - 1, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(1, wasmMaxExponent + normalExp, 0);
|
||||
auto const result = hfs.floatSet(1, Number::maxExponent + normalExp, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxExp);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(-1, wasmMaxExponent + normalExp, 0);
|
||||
auto const result = hfs.floatSet(-1, Number::maxExponent + normalExp, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinusMaxExp);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(1, wasmMaxExponent + normalExp - 1, 0);
|
||||
auto const result = hfs.floatSet(1, Number::maxExponent + normalExp - 1, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatPreMaxExp);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(STAmount::cMaxValue, wasmMaxExponent, 0);
|
||||
auto const result = hfs.floatSet(STAmount::cMaxValue, STAmount::cMaxOffset, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxIOU);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(1, wasmMinExponent + normalExp, 0);
|
||||
auto const result = hfs.floatSet(1, Number::minExponent - normalExp, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinExp);
|
||||
}
|
||||
|
||||
@@ -2275,12 +2336,6 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
auto const result = hfs.floatSet(10, -1, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == float1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(1, Number::maxExponent + normalExp + 1, 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2312,15 +2367,6 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(!result && result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto x = floatMaxExp;
|
||||
// exp = 81 + 97 = 178
|
||||
x[1] |= 0x80;
|
||||
x[1] &= 0xBF;
|
||||
auto const result = hfs.floatCompare(makeSlice(x), makeSlice(floatMaxExp));
|
||||
BEAST_EXPECT(!result && result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatCompare(makeSlice(floatIntMin), makeSlice(floatIntZero));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == 2);
|
||||
@@ -2368,9 +2414,9 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
{
|
||||
// max IOU is too small to make any change
|
||||
auto const result = hfs.floatAdd(makeSlice(floatMaxIOU), makeSlice(floatMaxExp), 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxExp);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -2379,8 +2425,9 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
{
|
||||
// Number can't hold int64.min, it is rounded and we get -3, not -1
|
||||
auto const result = hfs.floatAdd(makeSlice(floatIntMax), makeSlice(floatIntMin), 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinus3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2416,9 +2463,8 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
auto const result =
|
||||
hfs.floatSubtract(makeSlice(floatMaxIOU), makeSlice(floatMinusMaxExp), 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
hfs.floatSubtract(makeSlice(floatMinusMaxExp), makeSlice(floatMaxIOU), 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinusMaxExp);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -2464,7 +2510,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatMultiply(makeSlice(floatMaxIOU), makeSlice(float1More), 0);
|
||||
auto const result = hfs.floatMultiply(makeSlice(floatMax), makeSlice(float1More), 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
@@ -2526,7 +2572,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
auto const y = hfs.floatSet(STAmount::cMaxValue, -normalExp - 1, 0); // 0.9999999...
|
||||
if (BEAST_EXPECT(y))
|
||||
{
|
||||
auto const result = hfs.floatDivide(makeSlice(floatMaxIOU), makeSlice(*y), 0);
|
||||
auto const result = hfs.floatDivide(makeSlice(floatMax), makeSlice(*y), 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
@@ -2643,23 +2689,17 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 2, 0);
|
||||
auto const result = hfs.floatPower(makeSlice(floatMax), 2, 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 81, 0);
|
||||
auto const result = hfs.floatPower(makeSlice(floatMax), Number::maxExponent + 1, 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 2, 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 0, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == float1);
|
||||
@@ -2714,48 +2754,8 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
// perf test logs
|
||||
// {
|
||||
// auto const result = hfs.floatLog(makeSlice(floatPi), 0);
|
||||
// if (BEAST_EXPECT(result))
|
||||
// {
|
||||
// std::cout << "lg(" << floatToString(makeSlice(floatPi))
|
||||
// << ") = " << floatToString(makeSlice(*result))
|
||||
// << std::endl;
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// auto const result = hfs.floatLog(makeSlice(floatIntMax), 0);
|
||||
// if (BEAST_EXPECT(result))
|
||||
// {
|
||||
// std::cout << "lg(" << floatToString(makeSlice(floatIntMax))
|
||||
// << ") = " << floatToString(makeSlice(*result))
|
||||
// << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
// {
|
||||
// auto const result = hfs.floatLog(makeSlice(floatMaxExp), 0);
|
||||
// if (BEAST_EXPECT(result))
|
||||
// {
|
||||
// std::cout << "lg(" << floatToString(makeSlice(floatMaxExp))
|
||||
// << ") = " << floatToString(makeSlice(*result))
|
||||
// << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
// {
|
||||
// auto const result = hfs.floatLog(makeSlice(floatMaxIOU), 0);
|
||||
// if (BEAST_EXPECT(result))
|
||||
// {
|
||||
// std::cout << "lg(" << floatToString(makeSlice(floatMaxIOU))
|
||||
// << ") = " << floatToString(makeSlice(*result))
|
||||
// << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
{
|
||||
auto const x = hfs.floatSet(9'500'000'000'000'001, -14, 0); // almost 80+15
|
||||
auto const x = hfs.floatSet(32'786, 0, 0);
|
||||
if (BEAST_EXPECT(x))
|
||||
{
|
||||
auto const result = hfs.floatLog(makeSlice(floatMaxExp), 0);
|
||||
@@ -2774,7 +2774,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
auto const x = hfs.floatSet(1000, 0, 0); // 1000
|
||||
auto const y = hfs.floatSet(3, 0, 0); // 0.1
|
||||
auto const y = hfs.floatSet(3, 0, 0); // 3
|
||||
if (BEAST_EXPECT(x && y))
|
||||
{
|
||||
auto const result = hfs.floatLog(makeSlice(*x), 0);
|
||||
@@ -2783,8 +2783,8 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
{
|
||||
auto const x = hfs.floatSet(1, -2, 0); // 0.01
|
||||
auto const y = hfs.floatSet(-2'000'000'000'000'000ll, -15, 0); // -2
|
||||
auto const x = hfs.floatSet(1, -2, 0); // 0.01
|
||||
auto const y = hfs.floatSet(-1'999'999'999'999'999'999, -normalExp, 0); // -2
|
||||
if (BEAST_EXPECT(x && y))
|
||||
{
|
||||
auto const result = hfs.floatLog(makeSlice(*x), 0);
|
||||
@@ -2796,7 +2796,6 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
void
|
||||
testFloatSpecialCases()
|
||||
{
|
||||
testcase("float Xrp+Mpt");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
@@ -2805,60 +2804,472 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
auto const dummyEscrow = keylet::escrow(env.master, env.seq(env.master));
|
||||
WasmHostFunctionsImpl const hfs(ac, dummyEscrow);
|
||||
|
||||
auto const y = hfs.floatSet(20, 0, 0);
|
||||
if (!BEAST_EXPECT(y))
|
||||
return;
|
||||
|
||||
Bytes x(8);
|
||||
|
||||
// XRP
|
||||
memset(x.data(), 0, x.size());
|
||||
x[0] = 0x40;
|
||||
x[7] = 10;
|
||||
|
||||
{
|
||||
auto const result = hfs.floatCompare(makeSlice(x), makeSlice(float10));
|
||||
BEAST_EXPECT(!result && result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAdd(makeSlice(float10), makeSlice(x), 0);
|
||||
BEAST_EXPECT(!result && result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
// MPT
|
||||
memset(x.data(), 0, x.size());
|
||||
x[0] = 0x60;
|
||||
x[7] = 10;
|
||||
|
||||
{
|
||||
auto const result = hfs.floatCompare(makeSlice(x), makeSlice(float10));
|
||||
BEAST_EXPECT(!result && result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAdd(makeSlice(float10), makeSlice(x), 0);
|
||||
BEAST_EXPECT(!result && result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
testcase("float non-canonical");
|
||||
|
||||
{ // non-canonical mantissa 10 000 000 000 000 000
|
||||
Bytes x = float1;
|
||||
*reinterpret_cast<uint64_t*>(x.data()) = 0x0000C16FF286A3D4ull;
|
||||
{ // non-canonical mantissa 100000e-4
|
||||
Bytes const y = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0xA0, 0xFF, 0xFF, 0xFF, 0xFC};
|
||||
auto const result = hfs.floatCompare(makeSlice(y), makeSlice(float10));
|
||||
BEAST_EXPECT(result && *result == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testFloatFromSTAmount()
|
||||
{
|
||||
testcase("floatFromSTAmount");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
ApplyContext ac = createApplyContext(env, ov);
|
||||
auto const dummyEscrow = keylet::escrow(env.master, env.seq(env.master));
|
||||
WasmHostFunctionsImpl const hfs(ac, dummyEscrow);
|
||||
|
||||
{
|
||||
STAmount const amount = XRP(100);
|
||||
auto const result = hfs.floatFromSTAmount(amount, -1);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
STAmount const amount = XRP(100);
|
||||
auto const result = hfs.floatFromSTAmount(amount, 4);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
STAmount const amount = XRP(0);
|
||||
auto const result = hfs.floatFromSTAmount(amount, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero);
|
||||
}
|
||||
|
||||
{
|
||||
STAmount const amount = XRP(-1);
|
||||
auto const y = hfs.floatSet(-1 * 1'000'000, 0, 0);
|
||||
if (BEAST_EXPECT(y))
|
||||
{
|
||||
auto const result = hfs.floatCompare(makeSlice(x), makeSlice(float1));
|
||||
BEAST_EXPECT(!result && result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
auto const result = hfs.floatFromSTAmount(amount, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == *y);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto const y = hfs.floatSet(9223372036854776, 3, 0);
|
||||
STAmount const amount(noIssue(), std::numeric_limits<int64_t>::max());
|
||||
auto const result = hfs.floatFromSTAmount(amount, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == *y);
|
||||
}
|
||||
|
||||
{
|
||||
bool ex = false;
|
||||
try
|
||||
{
|
||||
STAmount const amount(noIssue(), -1, Number::maxExponent + normalExp);
|
||||
[[maybe_unused]] auto const r = hfs.floatFromSTAmount(amount, 0);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ex = true;
|
||||
}
|
||||
|
||||
BEAST_EXPECT(ex);
|
||||
}
|
||||
|
||||
auto const USD = env.master["USD"];
|
||||
{
|
||||
STAmount const amount(
|
||||
IOUAmount(STAmount::cMinValue, STAmount::cMinOffset), USD.issue());
|
||||
auto const result = hfs.floatFromSTAmount(amount, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinIOU);
|
||||
}
|
||||
|
||||
{
|
||||
STAmount const amount(
|
||||
IOUAmount(STAmount::cMaxValue, STAmount::cMaxOffset), USD.issue());
|
||||
auto const result = hfs.floatFromSTAmount(amount, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxIOU);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testFloatFromSTNumber()
|
||||
{
|
||||
testcase("floatFromSTNumber");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
ApplyContext ac = createApplyContext(env, ov);
|
||||
auto const dummyEscrow = keylet::escrow(env.master, env.seq(env.master));
|
||||
WasmHostFunctionsImpl const hfs(ac, dummyEscrow);
|
||||
|
||||
// Test with invalid rounding mode
|
||||
{
|
||||
STNumber const num(sfNumber, Number(123, 0));
|
||||
auto const result = hfs.floatFromSTNumber(num, -1);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
STNumber const num(sfNumber, Number(123, 0));
|
||||
auto const result = hfs.floatFromSTNumber(num, 4);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
STNumber const num(
|
||||
sfNumber, Number(std::numeric_limits<uint64_t>::max(), 0, Number::normalized()));
|
||||
auto const result = hfs.floatFromSTNumber(num, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatUIntMax);
|
||||
}
|
||||
|
||||
{
|
||||
STNumber const num(sfNumber, Number(-1, Number::maxExponent + normalExp));
|
||||
auto const result = hfs.floatFromSTNumber(num, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinusMaxExp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testFloatToInt()
|
||||
{
|
||||
testcase("floatToInt");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
ApplyContext ac = createApplyContext(env, ov);
|
||||
auto const dummyEscrow = keylet::escrow(env.master, env.seq(env.master));
|
||||
WasmHostFunctionsImpl const hfs(ac, dummyEscrow);
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(makeSlice(float1), -1);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(makeSlice(float1), 4);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(Slice(), 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(makeSlice(invalid), 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(makeSlice(floatIntZero), 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == 0);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatFromInt(*result, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatIntZero);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(makeSlice(float1), 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == 1);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatFromInt(*result, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == float1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(makeSlice(floatMinus1), 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == -1);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatFromInt(*result, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatMinus1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(makeSlice(floatIntMax), 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == std::numeric_limits<int64_t>::max());
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatFromInt(*result, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatIntMax);
|
||||
}
|
||||
|
||||
{
|
||||
// Number can't hold int64.min, it is rounded and we get int64_t.min - 3, which doesn't
|
||||
// fit into int64
|
||||
auto const result = hfs.floatToInt(makeSlice(floatIntMin), 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToInt(makeSlice(floatUIntMax), 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
}
|
||||
|
||||
// Test rounding modes with pi (3.141592653589793)
|
||||
{
|
||||
// to_nearest (mode 0): should round to 3
|
||||
auto const result = hfs.floatToInt(makeSlice(floatPi), 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == 3);
|
||||
}
|
||||
|
||||
{
|
||||
// towards_zero (mode 1): should truncate to 3
|
||||
auto const result = hfs.floatToInt(makeSlice(floatPi), 1);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == 3);
|
||||
}
|
||||
|
||||
{
|
||||
// downward (mode 2): should round down to 3
|
||||
auto const result = hfs.floatToInt(makeSlice(floatPi), 2);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == 3);
|
||||
}
|
||||
|
||||
{
|
||||
// upward (mode 3): should round up to 4
|
||||
auto const result = hfs.floatToInt(makeSlice(floatPi), 3);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == 4);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testFloatToMantissaAndExponent()
|
||||
{
|
||||
testcase("floatToMantissaAndExponent");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
ApplyContext ac = createApplyContext(env, ov);
|
||||
auto const dummyEscrow = keylet::escrow(env.master, env.seq(env.master));
|
||||
WasmHostFunctionsImpl const hfs(ac, dummyEscrow);
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(invalid));
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(floatIntZero));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(result->first == 0) &&
|
||||
BEAST_EXPECT(result->second == std::numeric_limits<int32_t>::min());
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatSet(result->first, result->second, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatIntZero);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(float1));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(result->first == 1000000000000000000) &&
|
||||
BEAST_EXPECT(result->second == -normalExp);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatSet(result->first, result->second, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == float1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(floatMinus1));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(result->first == -1000000000000000000) &&
|
||||
BEAST_EXPECT(result->second == -normalExp);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatSet(result->first, result->second, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatMinus1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(float10));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(result->first == 1000000000000000000) &&
|
||||
BEAST_EXPECT(result->second == -normalExp + 1);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatSet(result->first, result->second, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == float10);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(floatPi));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(result->first == 3141592653589793000) &&
|
||||
BEAST_EXPECT(result->second == -normalExp);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatSet(result->first, result->second, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatPi);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(floatIntMax));
|
||||
BEAST_EXPECT(result) &&
|
||||
BEAST_EXPECT(result->first == std::numeric_limits<int64_t>::max()) &&
|
||||
BEAST_EXPECT(result->second == 0);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatSet(result->first, result->second, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatIntMax);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(floatIntMin));
|
||||
BEAST_EXPECT(result) &&
|
||||
BEAST_EXPECT(result->first == (std::numeric_limits<int64_t>::min() / 10) - 1) &&
|
||||
BEAST_EXPECT(result->second == 1);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatSet(result->first, result->second, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatIntMin);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatToMantissaAndExponent(makeSlice(floatMax));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(result->first == Number::maxRep) &&
|
||||
BEAST_EXPECT(result->second == Number::maxExponent);
|
||||
|
||||
// roundtrip
|
||||
auto const result2 = hfs.floatSet(result->first, result->second, 0);
|
||||
BEAST_EXPECT(result2) && BEAST_EXPECT(*result2 == floatMax);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testFloatNegate()
|
||||
{
|
||||
testcase("floatNegate");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
ApplyContext ac = createApplyContext(env, ov);
|
||||
auto const dummyEscrow = keylet::escrow(env.master, env.seq(env.master));
|
||||
WasmHostFunctionsImpl const hfs(ac, dummyEscrow);
|
||||
|
||||
{
|
||||
auto const result = hfs.floatNegate(makeSlice(invalid));
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatNegate(makeSlice(floatIntZero));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatNegate(makeSlice(float1));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinus1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatNegate(makeSlice(floatMinus1));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == float1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatNegate(makeSlice(floatIntMax));
|
||||
auto const expected = hfs.floatFromInt(std::numeric_limits<int64_t>::min() + 1, 0);
|
||||
BEAST_EXPECT(result && expected) && BEAST_EXPECT(*result == *expected);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatNegate(makeSlice(floatMaxExp));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinusMaxExp);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatNegate(makeSlice(floatPi));
|
||||
auto const negPi = hfs.floatNegate(makeSlice(*result));
|
||||
BEAST_EXPECT(result && negPi) && BEAST_EXPECT(*negPi == floatPi);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testFloatAbs()
|
||||
{
|
||||
testcase("floatAbs");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
ApplyContext ac = createApplyContext(env, ov);
|
||||
auto const dummyEscrow = keylet::escrow(env.master, env.seq(env.master));
|
||||
WasmHostFunctionsImpl const hfs(ac, dummyEscrow);
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAbs(makeSlice(invalid));
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAbs(makeSlice(floatIntZero));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAbs(makeSlice(float1));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == float1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAbs(makeSlice(floatMinus1));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == float1);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAbs(makeSlice(floatIntMax));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntMax);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAbs(makeSlice(floatIntMin));
|
||||
auto const negated = hfs.floatNegate(makeSlice(floatIntMin));
|
||||
BEAST_EXPECT(result && negated) && BEAST_EXPECT(*result == *negated);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAbs(makeSlice(floatMinusMaxExp));
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxExp);
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatAbs(makeSlice(floatMinus3));
|
||||
auto const expected = hfs.floatFromInt(3, 0);
|
||||
BEAST_EXPECT(result && expected) && BEAST_EXPECT(*result == *expected);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testFloats()
|
||||
{
|
||||
// for checking binary formats manually
|
||||
// printNumbersBin();
|
||||
|
||||
testTraceFloat();
|
||||
testFloatFromInt();
|
||||
testFloatFromUint();
|
||||
testFloatFromSTAmount();
|
||||
testFloatFromSTNumber();
|
||||
testFloatToInt();
|
||||
testFloatToMantissaAndExponent();
|
||||
testFloatNegate();
|
||||
testFloatAbs();
|
||||
testFloatSet();
|
||||
testFloatCompare();
|
||||
testFloatAdd();
|
||||
|
||||
@@ -458,6 +458,42 @@ public:
|
||||
return wasm_float::floatFromUintImpl(x, mode);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromSTAmount(STAmount const& x, int32_t mode) const override
|
||||
{
|
||||
return wasm_float::floatFromSTAmountImpl(x, mode);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromSTNumber(STNumber const& x, int32_t mode) const override
|
||||
{
|
||||
return wasm_float::floatFromSTNumberImpl(x, mode);
|
||||
}
|
||||
|
||||
Expected<int64_t, HostFunctionError>
|
||||
floatToInt(Slice const& x, int32_t mode) const override
|
||||
{
|
||||
return wasm_float::floatToIntImpl(x, mode);
|
||||
}
|
||||
|
||||
virtual Expected<FloatPair, HostFunctionError>
|
||||
floatToMantissaAndExponent(Slice const& x) const override
|
||||
{
|
||||
return wasm_float::floatToMantissaAndExponentImpl(x);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatNegate(Slice const& x) const override
|
||||
{
|
||||
return wasm_float::floatNegateImpl(x);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatAbs(Slice const& x) const override
|
||||
{
|
||||
return wasm_float::floatAbsImpl(x);
|
||||
}
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const override
|
||||
{
|
||||
|
||||
@@ -599,7 +599,7 @@ struct Wasm_test : public beast::unit_test::suite
|
||||
|
||||
TestHostFunctions hfs(env, 0);
|
||||
auto re = runEscrowWasm(floatTestWasm, hfs, 200'000, funcName, {});
|
||||
checkResult(re, 1, 110'699);
|
||||
checkResult(re, 1, 167'965);
|
||||
env.close();
|
||||
}
|
||||
|
||||
@@ -608,7 +608,7 @@ struct Wasm_test : public beast::unit_test::suite
|
||||
|
||||
TestHostFunctions hfs(env, 0);
|
||||
auto re = runEscrowWasm(float0Wasm, hfs, 100'000, funcName, {});
|
||||
checkResult(re, 1, 4'259);
|
||||
checkResult(re, 1, 4'309);
|
||||
env.close();
|
||||
}
|
||||
}
|
||||
@@ -787,7 +787,7 @@ struct Wasm_test : public beast::unit_test::suite
|
||||
auto re = engine.run(badAlignWasm, hfs, 1'000'000, "test", {}, imports, env.journal);
|
||||
if (BEAST_EXPECTS(re, transToken(re.error())))
|
||||
{
|
||||
BEAST_EXPECTS(re->result == 0x684f7941, std::to_string(re->result));
|
||||
BEAST_EXPECTS(re->result == 0x47308594, std::to_string(re->result));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -653,119 +653,267 @@ extern std::string const codecovTestsWasmHex =
|
||||
"2d657874";
|
||||
|
||||
extern std::string const floatTestsWasmHex =
|
||||
"0061736d0100000001430860077f7f7f7f7f7f7f017f60057f7f7f7f7f017f60047f7f7f7f017f60067f7f7f7f7f7f"
|
||||
"017f60047e7f7f7f017f60057f7e7f7f7f017f60037f7f7e017f6000017f02c9020e08686f73745f6c696205747261"
|
||||
"6365000108686f73745f6c69620e666c6f61745f66726f6d5f696e74000408686f73745f6c69621274726163655f6f"
|
||||
"70617175655f666c6f6174000208686f73745f6c69620f666c6f61745f66726f6d5f75696e74000108686f73745f6c"
|
||||
"696209666c6f61745f736574000508686f73745f6c69620d666c6f61745f636f6d70617265000208686f73745f6c69"
|
||||
"6209666c6f61745f616464000008686f73745f6c69620e666c6f61745f7375627472616374000008686f73745f6c69"
|
||||
"620e666c6f61745f6d756c7469706c79000008686f73745f6c69620c666c6f61745f646976696465000008686f7374"
|
||||
"5f6c696209666c6f61745f706f77000308686f73745f6c69620974726163655f6e756d000608686f73745f6c69620a"
|
||||
"666c6f61745f726f6f74000308686f73745f6c696209666c6f61745f6c6f6700010302010705030100110619037f01"
|
||||
"418080c0000b7f0041d28ac0000b7f0041e08ac0000b072e04066d656d6f727902000666696e697368000e0a5f5f64"
|
||||
"6174615f656e6403010b5f5f686561705f6261736503020af20e01ef0e01047f230041206b22012400418080c00041"
|
||||
"1d41014100410010001a200142003703100240428ce000200141106a22004108410010014108460440419d80c00041"
|
||||
"172000410810021a41b480c000411e20004108410110001a0c010b41d280c000411e41014100410010001a0b200142"
|
||||
"8ce0003703180240200141186a4108200141106a2200410841001003410846044041f080c00041172000410810021a"
|
||||
"0c010b418781c000411e41014100410010001a0b0240410242fb00200141106a2200410841001004410846044041a5"
|
||||
"81c00041212000410810021a0c010b41c681c000412641014100410010001a0b41ec81c0004115418182c000410810"
|
||||
"021a419182c0004116418982c000410810021a41a782c000411b41014100410010001a200142003703180240420120"
|
||||
"0141186a2200410841001001410846044041c282c000410f2000410810021a0c010b41d182c0004116410141004100"
|
||||
"10001a0b0240200141186a4108418182c0004108100545044041e782c000411b41014100410010001a0c010b418283"
|
||||
"c000411b41014100410010001a0b0240200141186a4108418982c000410810054101460440419d83c0004123410141"
|
||||
"00410010001a0c010b41c083c000412441014100410010001a0b0240418982c0004108200141186a41081005410246"
|
||||
"044041e483c000412341014100410010001a0c010b418784c000412441014100410010001a0b41ab84c00041204101"
|
||||
"4100410010001a200142d487b6f4c7d4b1c000370310410921000340200141106a22024108418182c0004108200241"
|
||||
"08410010061a200041016b22000d000b20014200370318420a200141186a22004108410010011a0240200041082002"
|
||||
"4108100545044041cb84c000411441014100410010001a0c010b41df84c000411341014100410010001a0b410b2100"
|
||||
"0340200141106a22024108418182c000410820024108410010071a200041016b22000d000b024020024108418982c0"
|
||||
"004108100545044041f284c000411941014100410010001a0c010b418b85c000411841014100410010001a0b41a385"
|
||||
"c000412341014100410010001a20014200370300420a20014108410010011a200142d487b6f4c7d4b1c00037030841"
|
||||
"0621000340200141086a220241082001410820024108410010081a200041016b22000d000b2001420037031042c084"
|
||||
"3d200141106a22004108410010011a02402000410820024108100545044041c685c000411941014100410010001a0c"
|
||||
"010b41df85c000411841014100410010001a0b410721000340200141086a220241082001410820024108410010091a"
|
||||
"200041016b22000d000b20014200370318417f4201200141186a22004108410010041a024020024108200041081005"
|
||||
"45044041f785c000411741014100410010001a0c010b418e86c000411641014100410010001a0b41a486c000411741"
|
||||
"014100410010001a20014200370308418182c00041084103200141086a220041084100100a1a41bb86c00041122000"
|
||||
"410810021a418982c00041084106200041084100100a1a41cd86c00041182000410810021a20014200370310420920"
|
||||
"0141106a22024108410010011a200241084102200041084100100a1a41e586c00041142000410810021a2002410841"
|
||||
"00200041084100100a1a41f986c00041172000410810021a200142003703184200200141186a22034108410010011a"
|
||||
"200341084102200041084100100a1a419087c00041142000410810021a41a487c00041382003410841002000410841"
|
||||
"00100aac100b1a41dc87c000411841014100410010001a20014200370308420920004108410010011a200142003703"
|
||||
"10200041084102200241084100100c1a41f487c00041122002410810021a200041084103200241084100100c1a4186"
|
||||
"88c00041122002410810021a2001420037031842c0843d20034108410010011a200341084103200241084100100c1a"
|
||||
"419888c00041182002410810021a200341084106200241084100100c1a41b088c000411c2002410810021a41cc88c0"
|
||||
"00411741014100410010001a2001420037031042c0843d20024108410010011a200142003703182002410820034108"
|
||||
"4100100d1a41e388c00041142003410810021a41f788c000411a41014100410010001a20014200370318418182c000"
|
||||
"4108418982c000410820034108410010081a0240418982c0004108200341081005450440419189c000411641014100"
|
||||
"410010001a0c010b41a789c000411541014100410010001a0b418982c0004108418982c0004108200141186a220041"
|
||||
"08410010081a0240418182c000410820004108100545044041bc89c000411741014100410010001a0c010b41d389c0"
|
||||
"00411641014100410010001a0b41e989c000411a41014100410010001a2001420037031020014200370318420a2001"
|
||||
"41186a22024108410010011a418182c000410820024108200141106a22004108410010091a41838ac0004119200041"
|
||||
"0810021a418182c00041082000410820004108410010091a419c8ac000410f2000410810021a024020024108200041"
|
||||
"08100545044041ab8ac000411441014100410010001a0c010b41bf8ac000411341014100410010001a0b200141206a"
|
||||
"240041010b0bdc0a0100418080c0000bd20a0a24242420746573745f666c6f61745f66726f6d5f7761736d20242424"
|
||||
"2020666c6f61742066726f6d206936342031323330303a2020666c6f61742066726f6d206936342031323330302061"
|
||||
"73204845583a2020666c6f61742066726f6d206936342031323330303a206661696c65642020666c6f61742066726f"
|
||||
"6d207536342031323330303a2020666c6f61742066726f6d207536342031323330303a206661696c65642020666c6f"
|
||||
"61742066726f6d2065787020322c206d616e7469737361203132333a2020666c6f61742066726f6d2065787020322c"
|
||||
"206d616e746973736120333a206661696c65642020666c6f61742066726f6d20636f6e737420313ad4838d7ea4c680"
|
||||
"0094838d7ea4c680002020666c6f61742066726f6d20636f6e7374202d313a0a24242420746573745f666c6f61745f"
|
||||
"636f6d70617265202424242020666c6f61742066726f6d20313a2020666c6f61742066726f6d20313a206661696c65"
|
||||
"642020666c6f61742066726f6d2031203d3d20464c4f41545f4f4e452020666c6f61742066726f6d203120213d2046"
|
||||
"4c4f41545f4f4e452020666c6f61742066726f6d2031203e20464c4f41545f4e454741544956455f4f4e452020666c"
|
||||
"6f61742066726f6d203120213e20464c4f41545f4e454741544956455f4f4e452020464c4f41545f4e454741544956"
|
||||
"455f4f4e45203c20666c6f61742066726f6d20312020464c4f41545f4e454741544956455f4f4e4520213c20666c6f"
|
||||
"61742066726f6d20310a24242420746573745f666c6f61745f6164645f737562747261637420242424202072657065"
|
||||
"61746564206164643a20676f6f6420207265706561746564206164643a206261642020726570656174656420737562"
|
||||
"74726163743a20676f6f64202072657065617465642073756274726163743a206261640a24242420746573745f666c"
|
||||
"6f61745f6d756c7469706c795f6469766964652024242420207265706561746564206d756c7469706c793a20676f6f"
|
||||
"6420207265706561746564206d756c7469706c793a2062616420207265706561746564206469766964653a20676f6f"
|
||||
"6420207265706561746564206469766964653a206261640a24242420746573745f666c6f61745f706f772024242420"
|
||||
"20666c6f61742063756265206f6620313a2020666c6f61742036746820706f776572206f66202d313a2020666c6f61"
|
||||
"7420737175617265206f6620393a2020666c6f61742030746820706f776572206f6620393a2020666c6f6174207371"
|
||||
"75617265206f6620303a2020666c6f61742030746820706f776572206f6620302028657870656374696e6720494e56"
|
||||
"414c49445f504152414d53206572726f72293a0a24242420746573745f666c6f61745f726f6f74202424242020666c"
|
||||
"6f61742073717274206f6620393a2020666c6f61742063627274206f6620393a2020666c6f61742063627274206f66"
|
||||
"20313030303030303a2020666c6f61742036746820726f6f74206f6620313030303030303a0a24242420746573745f"
|
||||
"666c6f61745f6c6f672024242420206c6f675f3130206f6620313030303030303a0a24242420746573745f666c6f61"
|
||||
"745f6e65676174652024242420206e656761746520636f6e737420313a20676f6f6420206e656761746520636f6e73"
|
||||
"7420313a2062616420206e656761746520636f6e7374202d313a20676f6f6420206e656761746520636f6e7374202d"
|
||||
"313a206261640a24242420746573745f666c6f61745f696e76657274202424242020696e76657274206120666c6f61"
|
||||
"742066726f6d2031303a2020696e7665727420616761696e3a2020696e766572742074776963653a20676f6f642020"
|
||||
"696e766572742074776963653a20626164004d0970726f64756365727302086c616e6775616765010452757374000c"
|
||||
"70726f6365737365642d6279010572757374631d312e38372e30202831373036376539616320323032352d30352d30"
|
||||
"3929002c0f7461726765745f6665617475726573022b0f6d757461626c652d676c6f62616c732b087369676e2d6578"
|
||||
"74";
|
||||
"0061736d01000000014f0a60057f7f7f7f7f017f60077f7f7f7f7f7f7f017f60047f7f7f7f017f60067f7f7f7f7f7f"
|
||||
"017f60047e7f7f7f017f60057f7e7f7f7f017f60037f7f7e017f60037f7f7f006000017f60027f7f017f02ba031308"
|
||||
"686f73745f6c6962057472616365000008686f73745f6c69620e666c6f61745f66726f6d5f696e74000408686f7374"
|
||||
"5f6c69620f666c6f61745f66726f6d5f75696e74000008686f73745f6c696209666c6f61745f736574000508686f73"
|
||||
"745f6c69620d666c6f61745f636f6d70617265000208686f73745f6c696209666c6f61745f616464000108686f7374"
|
||||
"5f6c69620e666c6f61745f7375627472616374000108686f73745f6c69620e666c6f61745f6d756c7469706c790001"
|
||||
"08686f73745f6c69620c666c6f61745f646976696465000108686f73745f6c696209666c6f61745f706f7700030868"
|
||||
"6f73745f6c69620974726163655f6e756d000608686f73745f6c69620a666c6f61745f726f6f74000308686f73745f"
|
||||
"6c696209666c6f61745f6c6f67000003656e760c666c6f61745f746f5f696e74000003656e761e666c6f61745f746f"
|
||||
"5f6d616e74697373615f616e645f6578706f6e656e74000303656e760c666c6f61745f6e6567617465000203656e76"
|
||||
"09666c6f61745f616273000203656e7613666c6f61745f66726f6d5f7374616d6f756e74000003656e7613666c6f61"
|
||||
"745f66726f6d5f73746e756d626572000003040307080905030100110619037f01418080c0000b7f0041a0a1c0000b"
|
||||
"7f0041a0a1c0000b072e04066d656d6f727902000666696e69736800140a5f5f646174615f656e6403010b5f5f6865"
|
||||
"61705f6261736503020ae52c031f002000200141014100410010001a418080c00041022002410c410110001a0bff2b"
|
||||
"020f7f017e23004180016b22002400418280c000411d41014100410010001a200041f8006a41003602002000420037"
|
||||
"03700240428ce000200041f0006a2202410c410010012201410c460440419f80c00041172002101341b680c000411e"
|
||||
"2002410c410110001a0c010b41d480c000411e41014100410010001a0b2000428ce0003703600240200041e0006a41"
|
||||
"08200041f0006a2202410c41001002410c4604402001410c46210841f280c0004117200210130c010b418981c00041"
|
||||
"1e41014100410010001a0b0240410242fb00200041f0006a2201410c41001003410c46044041a781c0004121200110"
|
||||
"130c010b41c881c000412641014100410010001a410021080b41ee81c0004115418382c0001013418f82c000411641"
|
||||
"a582c000101341b182c000411b41014100410010001a200041f8006a41003602002000420037037002404201200041"
|
||||
"f0006a2202410c410010012201410c46044041cc82c000410f200210130c010b41db82c00041164101410041001000"
|
||||
"1a0b027f200041f0006a410c418382c000410c100445044041f182c000411b41014100410010001a2001410c460c01"
|
||||
"0b418c83c000412341014100410010001a41000b21090240200041f0006a410c41a582c000410c1004410146044041"
|
||||
"af83c000412341014100410010001a0c010b4100210941d283c000412c41014100410010001a0b024041a582c00041"
|
||||
"0c200041f0006a410c1004410246044041fe83c000412341014100410010001a0c010b4100210941a184c000412c41"
|
||||
"014100410010001a0b41cd84c000412041014100410010001a200041e8006a418b82c0002800003602002000418382"
|
||||
"c000290000370360410921040340200041e0006a2201410c418382c000410c2001410c410010051a200441016b2204"
|
||||
"0d000b200041f8006a410036020020004200370370420a200041f0006a410c41001001410c46220a45044041ed84c0"
|
||||
"00411741014100410010001a0b0240200041f0006a410c200041e0006a410c1004450440418485c000411441014100"
|
||||
"410010001a0c010b4100210a419885c000411641014100410010001a0b410b21040340200041e0006a2201410c4183"
|
||||
"82c000410c2001410c410010061a200441016b22040d000b02402001410c41a582c000410c100445044041ae85c000"
|
||||
"411941014100410010001a0c010b4100210a41c785c000411b41014100410010001a0b41e285c00041234101410041"
|
||||
"0010001a200041c8006a410036020020004200370340420a200041406b410c410010011a200041d8006a418b82c000"
|
||||
"2800003602002000418382c000290000370350410621040340200041d0006a2201410c200041406b410c2001410c41"
|
||||
"0010071a200441016b22040d000b200041e8006a41003602002000420037036042c0843d200041e0006a2202410c41"
|
||||
"0010011a02402002410c2001410c10042201450440418586c000411941014100410010001a0c010b419e86c000411b"
|
||||
"41014100410010001a0b200145210c410721040340200041d0006a2201410c200041406b410c2001410c410010081a"
|
||||
"200441016b22040d000b200041f8006a410036020020004200370370417f4201200041f0006a2202410c410010031a"
|
||||
"02402001410c2002410c100445044041b986c000411741014100410010001a0c010b41d086c0004119410141004100"
|
||||
"10001a4100210c0b41e986c000411741014100410010001a200041d8006a2202410036020020004200370350418382"
|
||||
"c000410c4103200041d0006a2204410c410010091a418087c00041122004101341a582c000410c41062004410c4100"
|
||||
"10091a419287c000411820041013200041e8006a22064100360200200042003703604209200041e0006a2203410c41"
|
||||
"0010011a2003410c41022004410c410010091a41aa87c0004114200410132003410c41002004410c410010091a41be"
|
||||
"87c000411720041013200041f8006a22014100360200200042003703704200200041f0006a2205410c410010011a20"
|
||||
"05410c41022004410c410010091a41d587c00041142004101341e987c00041382005410c41002004410c41001009ac"
|
||||
"100a1a41a188c000411841014100410010001a200241003602002000420037035042092004410c410010011a200641"
|
||||
"00360200200042003703602004410c41022003410c4100100b1a41b988c0004112200310132004410c41032003410c"
|
||||
"4100100b1a41cb88c000411220031013200141003602002000420037037042c0843d2005410c410010011a2005410c"
|
||||
"41032003410c4100100b1a41dd88c0004118200310132005410c41062003410c4100100b1a41f588c000411c200310"
|
||||
"13419189c000411741014100410010001a200641003602002000420037036042c0843d2003410c410010011a200141"
|
||||
"00360200200042003703702003410c2005410c4100100c1a41a889c00041142005101341bc89c000411a4101410041"
|
||||
"0010001a2001410036020020004200370370418382c000410c41a582c000410c2005410c410010071a024041a582c0"
|
||||
"00410c2005410c1004220145044041d689c000411641014100410010001a0c010b41ec89c000411841014100410010"
|
||||
"001a0b41a582c000410c41a582c000410c200041f0006a2202410c410010071a0240418382c000410c2002410c1004"
|
||||
"450440200145210d41848ac000411741014100410010001a0c010b419b8ac000411941014100410010001a0b41b48a"
|
||||
"c000411a41014100410010001a200041e8006a410036020020004200370360200041f8006a41003602002000420037"
|
||||
"0370420a200041f0006a2202410c410010011a418382c000410c2002410c200041e0006a2201410c410010081a41ce"
|
||||
"8ac000411920011013418382c000410c2001410c2001410c410010081a41e78ac000410f2001101302402002410c20"
|
||||
"01410c1004220e45044041f68ac000411441014100410010001a0c010b418a8bc000411641014100410010001a0b41"
|
||||
"00210141a08bc000411a41014100410010001a200042003703400240418382c000410c200041406b41084100100d22"
|
||||
"0641084604402000290340220f42015104404101210141ba8bc000411741014100410010001a0c020b41d18bc00041"
|
||||
"1941014100410010001a41ea8bc0004108200f100a1a0c010b41f28bc000412441014100410010001a41968cc00041"
|
||||
"0f2006ac100a1a0b41002104024041a582c000410c200041406b41084100100d220641084604402000290340220f42"
|
||||
"7f51044041a58cc000411841014100410010001a200121040c020b41bd8cc000411a41014100410010001a41ea8bc0"
|
||||
"004108200f100a1a0c010b41d78cc000412541014100410010001a41968cc000410f2006ac100a1a0b410021012000"
|
||||
"41d8006a41003602002000420037035042ffffffffffffffffff00200041d0006a2202410c410010011a0240200241"
|
||||
"0c200041406b41084100100d220641084604402000290340220f42ffffffffffffffffff0051044041fc8cc000411e"
|
||||
"41014100410010001a200421010c020b419a8dc000412041014100410010001a41ba8dc000410d42ffffffffffffff"
|
||||
"ffff00100a1a41ea8bc0004108200f100a1a0c010b41c78dc000412b41014100410010001a41968cc000410f2006ac"
|
||||
"100a1a0b41002106200041e8006a4100360200200042003703604200200041e0006a2202410c410010011a02402002"
|
||||
"410c200041406b41084100100d220241084604402000290340220f50044041f28dc000411741014100410010001a20"
|
||||
"0121060c020b41898ec000411941014100410010001a41ea8bc0004108200f100a1a0c010b41a28ec0004124410141"
|
||||
"00410010001a41968cc000410f2002ac100a1a0b41002104200041f8006a410036020020004200370370417f420120"
|
||||
"0041f0006a2201410c410010031a02402001410c200041406b41084100100d220141084604402000290340220f5004"
|
||||
"4041c68ec000412541014100410010001a200621040c020b41eb8ec000412741014100410010001a41ea8bc0004108"
|
||||
"200f100a1a0c010b41928fc000413241014100410010001a41968cc000410f2001ac100a1a0b0240200041f0006a41"
|
||||
"0c200041406b41084101100d220141084604402000290340220f50044041c48fc000412741014100410010001a0c02"
|
||||
"0b4100210441eb8fc000412941014100410010001a41ea8bc0004108200f100a1a0c010b41002104419490c0004134"
|
||||
"41014100410010001a41968cc000410f2001ac100a1a0b4100210141c890c000412c41014100410010001a20004200"
|
||||
"370320200041003602040240418382c000410c200041206a4108200041046a4104100e2206410c4604402000280204"
|
||||
"2206416e462000290320220f42808090bbbad6adf00d5171450440419d91c000412b41014100410010001a41c891c0"
|
||||
"00412f200f100a1a41f791c000411f2006ac100a1a0c020b4101210141f490c000412941014100410010001a0c010b"
|
||||
"419692c000413641014100410010001a41968cc000410f2006ac100a1a0b2000420037033041002106200041003602"
|
||||
"08024041a582c000410c200041306a4108200041086a4104100e2202410c46044020002802082202416e4620002903"
|
||||
"30220f428080f0c4c5a9d28f72517145044041f692c000412c41014100410010001a41a293c0004130200f100a1a41"
|
||||
"f791c000411f2002ac100a1a0c020b41cc92c000412a41014100410010001a200121060c010b41d293c00041374101"
|
||||
"4100410010001a41968cc000410f2002ac100a1a0b41002101200041e8006a410036020020004200370360420a2000"
|
||||
"41e0006a2202410c410010011a200042003703402000410036020c02402002410c200041406b41082000410c6a4104"
|
||||
"100e2202410c460440200028020c2202416f462000290340220f42808090bbbad6adf00d517145044041b394c00041"
|
||||
"2c41014100410010001a41c891c000412f200f100a1a41df94c000411f2002ac100a1a0c020b418994c000412a4101"
|
||||
"4100410010001a200621010c010b41fe94c000413741014100410010001a41968cc000410f2002ac100a1a0b410021"
|
||||
"06200041f8006a4100360200200042003703704200200041f0006a2202410c410010011a2000420037035020004100"
|
||||
"36021002402002410c200041d0006a4108200041106a4104100e2202410c4604402000290350220f50200028021022"
|
||||
"02418080808078467145044041de95c000412b41014100410010001a418996c000411d200f100a1a41a696c0004127"
|
||||
"2002ac100a1a0c020b41b595c000412941014100410010001a200121060c010b41cd96c00041364101410041001000"
|
||||
"1a41968cc000410f2002ac100a1a0b4100210141bc89c000411a41014100410010001a200041c8006a410036020020"
|
||||
"0042003703400240418382c000410c200041406b2203410c100f2202410c460440200341a582c00010150440418397"
|
||||
"c000412b41014100410010001a0c020b4101210141ae97c000411741014100410010001a0c010b41c597c000412441"
|
||||
"014100410010001a41968cc000410f2002ac100a1a0b41002102200041d8006a410036020020004200370350024041"
|
||||
"a582c000410c200041d0006a2205410c100f2203410c4604402005418382c0001015044041e997c000412c41014100"
|
||||
"410010001a0c020b419598c000411841014100410010001a200121020c010b41ad98c000412541014100410010001a"
|
||||
"41968cc000410f2003ac100a1a0b200041e8006a4100360200200042003703604200200041e0006a2203410c410010"
|
||||
"011a200041f8006a41003602002000420037037002402003410c200041f0006a2205410c100f2201410c4604402005"
|
||||
"20031015044041d298c000412b41014100410010001a0c020b41fd98c000411741014100410010001a2002210b0c01"
|
||||
"0b419499c000412441014100410010001a41968cc000410f2001ac100a1a0b4100210141b899c00041174101410041"
|
||||
"0010001a200041186a4100360200200042003703100240418382c000410c200041106a2203410c10102202410c4604"
|
||||
"402003418382c0001015044041cf99c000412841014100410010001a0c020b4101210141f799c00041144101410041"
|
||||
"0010001a0c010b418b9ac000412141014100410010001a41968cc000410f2002ac100a1a0b41002102200041286a41"
|
||||
"0036020020004200370320024041a582c000410c200041206a2205410c10102203410c4604402005418382c0001015"
|
||||
"044041ac9ac000412941014100410010001a0c020b41d59ac000411541014100410010001a200121020c010b41ea9a"
|
||||
"c000412241014100410010001a41968cc000410f2003ac100a1a0b41002101200041386a4100360200200042003703"
|
||||
"304200200041306a2205410c410010011a200041c8006a41003602002000420037034002402005410c200041406b22"
|
||||
"07410c10102203410c4604402007200510150440418c9bc000412841014100410010001a0c020b41b49bc000411441"
|
||||
"014100410010001a200221010c010b41c89bc000412141014100410010001a41968cc000410f2003ac100a1a0b4100"
|
||||
"2102200041d8006a4100360200200042003703504276200041d0006a2203410c410010011a200041e8006a41003602"
|
||||
"0020004200370360420a200041e0006a2205410c410010011a200041f8006a41003602002000420037037002402003"
|
||||
"410c200041f0006a2207410c10102203410c460440200720051015044041e99bc000412a41014100410010001a0c02"
|
||||
"0b41939cc000411641014100410010001a200121020c010b41a99cc000412341014100410010001a41968cc000410f"
|
||||
"2003ac100a1a0b4100210141cc9cc000412141014100410010001a200042c0808080d0a0fdf000370050200041f800"
|
||||
"6a41003602002000420037037002400240200041d0006a4108200041f0006a2205410c410010112203410c46044041"
|
||||
"ed9cc000412220051013200042003703602005410c200041e0006a41084100100d22034108470d012000290360220f"
|
||||
"4280c2d72f51044041012101418f9dc000411d41014100410010001a0c030b41ac9dc000411f41014100410010001a"
|
||||
"41cb9dc000411c200f100a1a0c020b419b9ec000411f41014100410010001a41ba9ec00041102003ac100a1a0c010b"
|
||||
"41e79dc000413441014100410010001a41968cc000410f2003ac100a1a0b4100210341ca9ec0004121410141004100"
|
||||
"10001a200041ffffff8f7f36006820004281eceedce494ccf9c000370060200041f8006a4100360200200042003703"
|
||||
"7002400240200041e0006a410c200041f0006a2207410c410010122205410c46044041eb9ec000411c200710132000"
|
||||
"42003703502007410c200041d0006a41084100100d22054108470d012000290350220f42fb00510440410121034187"
|
||||
"9fc000411b41014100410010001a0c030b41a29fc000411d41014100410010001a41bf9fc0004116200f100a1a0c02"
|
||||
"0b4187a0c000411d41014100410010001a41ba9ec00041102005ac100a1a0c010b41d59fc000413241014100410010"
|
||||
"001a41968cc000410f2005ac100a1a0b410021050240418382c000410c200041f0006a2207410c41001012410c4604"
|
||||
"4041a4a0c000411a200710132007410c418382c000410c100445044041bea0c000412041014100410010001a200321"
|
||||
"050c020b41dea0c000412241014100410010001a0c010b4180a1c000412041014100410010001a0b20004180016a24"
|
||||
"00200e452008200971200a71200c71200d71200471200671200b71200271200171200571710b4201047f410c210202"
|
||||
"40034020002d0000220320012d00002204460440200041016a2100200141016a2101200241016b22020d010c020b0b"
|
||||
"200320046b21050b20050b0baa210100418080c0000ba02120200a24242420746573745f666c6f61745f66726f6d5f"
|
||||
"7761736d202424242020666c6f61742066726f6d206936342031323330303a2020666c6f61742066726f6d20693634"
|
||||
"203132333030206173204845583a2020666c6f61742066726f6d206936342031323330303a206661696c6564202066"
|
||||
"6c6f61742066726f6d207536342031323330303a2020666c6f61742066726f6d207536342031323330303a20666169"
|
||||
"6c65642020666c6f61742066726f6d2065787020322c206d616e7469737361203132333a2020666c6f61742066726f"
|
||||
"6d2065787020322c206d616e746973736120333a206661696c65642020666c6f61742066726f6d20636f6e73742031"
|
||||
"3a0de0b6b3a7640000ffffffee2020666c6f61742066726f6d20636f6e7374202d313af21f494c589c0000ffffffee"
|
||||
"0a24242420746573745f666c6f61745f636f6d70617265202424242020666c6f61742066726f6d20313a2020666c6f"
|
||||
"61742066726f6d20313a206661696c65642020666c6f61742066726f6d2031203d3d20464c4f41545f4f4e45202066"
|
||||
"6c6f61742066726f6d203120213d20464c4f41545f4f4e452c206661696c65642020666c6f61742066726f6d203120"
|
||||
"3e20464c4f41545f4e454741544956455f4f4e452020666c6f61742066726f6d203120213e20464c4f41545f4e4547"
|
||||
"41544956455f4f4e452c206661696c65642020464c4f41545f4e454741544956455f4f4e45203c20666c6f61742066"
|
||||
"726f6d20312020464c4f41545f4e454741544956455f4f4e4520213c20666c6f61742066726f6d20312c206661696c"
|
||||
"65640a24242420746573745f666c6f61745f6164645f7375627472616374202424242020666c6f61742066726f6d20"
|
||||
"31303a206661696c656420207265706561746564206164643a20676f6f6420207265706561746564206164643a2066"
|
||||
"61696c6564202072657065617465642073756274726163743a20676f6f642020726570656174656420737562747261"
|
||||
"63743a206661696c65640a24242420746573745f666c6f61745f6d756c7469706c795f646976696465202424242020"
|
||||
"7265706561746564206d756c7469706c793a20676f6f6420207265706561746564206d756c7469706c793a20666169"
|
||||
"6c656420207265706561746564206469766964653a20676f6f6420207265706561746564206469766964653a206661"
|
||||
"696c65640a24242420746573745f666c6f61745f706f77202424242020666c6f61742063756265206f6620313a2020"
|
||||
"666c6f61742036746820706f776572206f66202d313a2020666c6f617420737175617265206f6620393a2020666c6f"
|
||||
"61742030746820706f776572206f6620393a2020666c6f617420737175617265206f6620303a2020666c6f61742030"
|
||||
"746820706f776572206f6620302028657870656374696e6720494e56414c49445f504152414d53206572726f72293a"
|
||||
"0a24242420746573745f666c6f61745f726f6f74202424242020666c6f61742073717274206f6620393a2020666c6f"
|
||||
"61742063627274206f6620393a2020666c6f61742063627274206f6620313030303030303a2020666c6f6174203674"
|
||||
"6820726f6f74206f6620313030303030303a0a24242420746573745f666c6f61745f6c6f672024242420206c6f675f"
|
||||
"3130206f6620313030303030303a0a24242420746573745f666c6f61745f6e65676174652024242420206e65676174"
|
||||
"6520636f6e737420313a20676f6f6420206e656761746520636f6e737420313a206661696c656420206e6567617465"
|
||||
"20636f6e7374202d313a20676f6f6420206e656761746520636f6e7374202d313a206661696c65640a242424207465"
|
||||
"73745f666c6f61745f696e76657274202424242020696e76657274206120666c6f61742066726f6d2031303a202069"
|
||||
"6e7665727420616761696e3a2020696e766572742074776963653a20676f6f642020696e766572742074776963653a"
|
||||
"206661696c65640a24242420746573745f666c6f61745f746f5f696e74202424242020666c6f61745f746f5f696e74"
|
||||
"2831293a20676f6f642020666c6f61745f746f5f696e742831293a206661696c656420202020676f743a2020666c6f"
|
||||
"61745f746f5f696e742831293a206661696c65642077697468206572726f72202020206572726f7220636f64653a20"
|
||||
"20666c6f61745f746f5f696e74282d31293a20676f6f642020666c6f61745f746f5f696e74282d31293a206661696c"
|
||||
"65642020666c6f61745f746f5f696e74282d31293a206661696c65642077697468206572726f722020666c6f61745f"
|
||||
"746f5f696e74286936343a3a4d4158293a20676f6f642020666c6f61745f746f5f696e74286936343a3a4d4158293a"
|
||||
"206661696c65642020202065787065637465643a2020666c6f61745f746f5f696e74286936343a3a4d4158293a2066"
|
||||
"61696c65642077697468206572726f722020666c6f61745f746f5f696e742830293a20676f6f642020666c6f61745f"
|
||||
"746f5f696e742830293a206661696c65642020666c6f61745f746f5f696e742830293a206661696c65642077697468"
|
||||
"206572726f722020666c6f61745f746f5f696e7428302e312c20746f5f6e656172657374293a20676f6f642020666c"
|
||||
"6f61745f746f5f696e7428302e312c20746f5f6e656172657374293a206661696c65642020666c6f61745f746f5f69"
|
||||
"6e7428302e312c20746f5f6e656172657374293a206661696c65642077697468206572726f722020666c6f61745f74"
|
||||
"6f5f696e7428302e312c20746f77617264735f7a65726f293a20676f6f642020666c6f61745f746f5f696e7428302e"
|
||||
"312c20746f77617264735f7a65726f293a206661696c65642020666c6f61745f746f5f696e7428302e312c20746f77"
|
||||
"617264735f7a65726f293a206661696c65642077697468206572726f720a24242420746573745f666c6f61745f746f"
|
||||
"5f6d616e74697373615f616e645f6578706f6e656e74202424242020666c6f61745f746f5f6d616e74697373615f61"
|
||||
"6e645f6578706f6e656e742831293a20676f6f642020666c6f61745f746f5f6d616e74697373615f616e645f657870"
|
||||
"6f6e656e742831293a206661696c6564202020206578706563746564206d616e746973736120313030303030303030"
|
||||
"303030303030303030302c20676f743a202020206578706563746564206578706f6e656e74202d31382c20676f743a"
|
||||
"2020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e742831293a206661696c656420776974"
|
||||
"68206572726f722020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74282d31293a20676f"
|
||||
"6f642020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74282d31293a206661696c656420"
|
||||
"2020206578706563746564206d616e7469737361202d313030303030303030303030303030303030302c20676f743a"
|
||||
"2020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74282d31293a206661696c6564207769"
|
||||
"7468206572726f722020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74283130293a2067"
|
||||
"6f6f642020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74283130293a206661696c6564"
|
||||
"202020206578706563746564206578706f6e656e74202d31372c20676f743a2020666c6f61745f746f5f6d616e7469"
|
||||
"7373615f616e645f6578706f6e656e74283130293a206661696c65642077697468206572726f722020666c6f61745f"
|
||||
"746f5f6d616e74697373615f616e645f6578706f6e656e742830293a20676f6f642020666c6f61745f746f5f6d616e"
|
||||
"74697373615f616e645f6578706f6e656e742830293a206661696c6564202020206578706563746564206d616e7469"
|
||||
"73736120302c20676f743a202020206578706563746564206578706f6e656e74202d323134373438333634382c2067"
|
||||
"6f743a2020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e742830293a206661696c656420"
|
||||
"77697468206572726f722020666c6f61745f6e65676174652831293a206661696c6564202d20726573756c74206d69"
|
||||
"736d617463682020666c6f61745f6e65676174652831293a20676f6f642020666c6f61745f6e65676174652831293a"
|
||||
"206661696c65642077697468206572726f722020666c6f61745f6e6567617465282d31293a206661696c6564202d20"
|
||||
"726573756c74206d69736d617463682020666c6f61745f6e6567617465282d31293a20676f6f642020666c6f61745f"
|
||||
"6e6567617465282d31293a206661696c65642077697468206572726f722020666c6f61745f6e65676174652830293a"
|
||||
"206661696c6564202d20726573756c74206d69736d617463682020666c6f61745f6e65676174652830293a20676f6f"
|
||||
"642020666c6f61745f6e65676174652830293a206661696c65642077697468206572726f720a24242420746573745f"
|
||||
"666c6f61745f616273202424242020666c6f61745f6162732831293a206661696c6564202d20726573756c74206d69"
|
||||
"736d617463682020666c6f61745f6162732831293a20676f6f642020666c6f61745f6162732831293a206661696c65"
|
||||
"642077697468206572726f722020666c6f61745f616273282d31293a206661696c6564202d20726573756c74206d69"
|
||||
"736d617463682020666c6f61745f616273282d31293a20676f6f642020666c6f61745f616273282d31293a20666169"
|
||||
"6c65642077697468206572726f722020666c6f61745f6162732830293a206661696c6564202d20726573756c74206d"
|
||||
"69736d617463682020666c6f61745f6162732830293a20676f6f642020666c6f61745f6162732830293a206661696c"
|
||||
"65642077697468206572726f722020666c6f61745f616273282d3130293a206661696c6564202d20726573756c7420"
|
||||
"6d69736d617463682020666c6f61745f616273282d3130293a20676f6f642020666c6f61745f616273282d3130293a"
|
||||
"206661696c65642077697468206572726f720a24242420746573745f666c6f61745f66726f6d5f7374616d6f756e74"
|
||||
"202424242020666c6f61742066726f6d2058525020616d6f756e74202831303020585250293a202058525020616d6f"
|
||||
"756e7420636f6e76657273696f6e3a20676f6f64202058525020616d6f756e7420636f6e76657273696f6e3a206661"
|
||||
"696c6564202020206578706563746564203130303030303030302c20676f743a202058525020616d6f756e7420636f"
|
||||
"6e76657273696f6e3a206661696c6564202d20666c6f61745f746f5f696e74206572726f722020666c6f6174206672"
|
||||
"6f6d2058525020616d6f756e743a206661696c656420202020726573756c745f73697a653a0a24242420746573745f"
|
||||
"666c6f61745f66726f6d5f73746e756d626572202424242020666c6f61742066726f6d2053544e756d626572202831"
|
||||
"3233293a202053544e756d62657220636f6e76657273696f6e3a20676f6f64202053544e756d62657220636f6e7665"
|
||||
"7273696f6e3a206661696c6564202020206578706563746564203132332c20676f743a202053544e756d6265722063"
|
||||
"6f6e76657273696f6e3a206661696c6564202d20666c6f61745f746f5f696e74206572726f722020666c6f61742066"
|
||||
"726f6d2053544e756d6265723a206661696c65642020666c6f61742066726f6d2053544e756d626572202831293a20"
|
||||
"2053544e756d626572283129203d3d20464c4f41545f4f4e453a20676f6f64202053544e756d626572283129203d3d"
|
||||
"20464c4f41545f4f4e453a206661696c65642020666c6f61742066726f6d2053544e756d6265722831293a20666169"
|
||||
"6c6564004d0970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105"
|
||||
"72757374631d312e38392e30202832393438333838336520323032352d30382d303429002c0f7461726765745f6665"
|
||||
"617475726573022b0f6d757461626c652d676c6f62616c732b087369676e2d657874";
|
||||
|
||||
extern std::string const float0Hex =
|
||||
"0061736d0100000001290560057f7f7f7f7f017f60047e7f7f7f017f60077f7f7f7f7f7f7f017f60047f7f7f7f017f"
|
||||
"6000017f025f0408686f73745f6c6962057472616365000008686f73745f6c69620e666c6f61745f66726f6d5f696e"
|
||||
"74000108686f73745f6c69620e666c6f61745f7375627472616374000208686f73745f6c69620d666c6f61745f636f"
|
||||
"6d7061726500030302010405030100110619037f01418080c0000b7f00419281c0000b7f0041a081c0000b072e0406"
|
||||
"6d656d6f727902000666696e69736800040a5f5f646174615f656e6403010b5f5f686561705f6261736503020abe02"
|
||||
"01bb0201017f23808080800041206b2200248080808000418080c0800041154100410041001080808080001a200042"
|
||||
"003703084200200041086a410841001081808080001a20004200370310420a200041106a410841001081808080001a"
|
||||
"200042003703180240200041106a4108200041106a4108200041186a410841001082808080004108460d00419580c0"
|
||||
"800041154100410041001080808080001a0b02400240200041086a4108200041186a41081083808080000d0041aa80"
|
||||
"c0800041174100410041001080808080001a0c010b41c180c0800041164100410041001080808080001a0b02400240"
|
||||
"200041086a410841d780c0800041081083808080000d0041df80c08000411a4100410041001080808080001a0c010b"
|
||||
"41f980c0800041194100410041001080808080001a0b200041206a24808080800041010b0b9c010100418080c0000b"
|
||||
"92010a24242420746573745f666c6f61745f30202424242020666c6f61742031302d31303a206661696c6564202066"
|
||||
"6c6f6174203020636f6d706172653a20676f6f642020666c6f6174203020636f6d706172653a206261648000000000"
|
||||
"0000002020464c4f41545f5a45524f20636f6d706172653a20676f6f642020464c4f41545f5a45524f20636f6d7061"
|
||||
"72653a20626164009502046e616d65001110666c6f61745f74657374732e7761736d01da0105002b5f5a4e38787270"
|
||||
"6c5f73746434686f7374357472616365313768616338383262323664656162656436364501355f5a4e387872706c5f"
|
||||
"73746434686f73743134666c6f61745f66726f6d5f696e74313768303234306638653361383964313939654502355f"
|
||||
"5a4e387872706c5f73746434686f73743134666c6f61745f7375627472616374313768643634306331353233343534"
|
||||
"323935634503345f5a4e387872706c5f73746434686f73743133666c6f61745f636f6d706172653137683663386465"
|
||||
"656231323864393638386645040666696e697368071201000f5f5f737461636b5f706f696e746572090a0100072e72"
|
||||
"6f64617461004d0970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d6279"
|
||||
"010572757374631d312e38392e30202832393438333838336520323032352d30382d3034290094010f746172676574"
|
||||
"5f6665617475726573082b0b62756c6b2d6d656d6f72792b0f62756c6b2d6d656d6f72792d6f70742b1663616c6c2d"
|
||||
"696e6469726563742d6f7665726c6f6e672b0a6d756c746976616c75652b0f6d757461626c652d676c6f62616c732"
|
||||
"b136e6f6e7472617070696e672d6670746f696e742b0f7265666572656e63652d74797065732b087369676e2d65787"
|
||||
"4";
|
||||
"6d7061726500030302010405030100110619037f01418080c0000b7f00419681c0000b7f0041a081c0000b072e0406"
|
||||
"6d656d6f727902000666696e69736800040a5f5f646174615f656e6403010b5f5f686561705f6261736503020ad302"
|
||||
"01d00201017f23808080800041206b2200248080808000418080c0800041154101410041001080808080001a200041"
|
||||
"086a410036020020004200370300200041106a41086a410036020020004200370310024002400240420a2000410c41"
|
||||
"00108180808000410c470d002000410c2000410c200041106a410c4100108280808000410c470d0102400240200041"
|
||||
"106a410c200041106a410c1083808080000d00419580c0800041174101410041001080808080001a0c010b41ac80c0"
|
||||
"800041164101410041001080808080001a0b0240200041106a410c41c280c08000410c1083808080000d0041ce80c0"
|
||||
"8000411a4101410041001080808080001a0c030b41e880c0800041194101410041001080808080001a0c020b418181"
|
||||
"c0800041154101410041001080808080001a0c010b418181c0800041154101410041001080808080001a0b20004120"
|
||||
"6a24808080800041010b0ba0010100418080c0000b96010a24242420746573745f666c6f61745f3020242424202066"
|
||||
"6c6f6174203020636f6d706172653a20676f6f642020666c6f6174203020636f6d706172653a206261640000000000"
|
||||
"000000800000002020464c4f41545f5a45524f20636f6d706172653a20676f6f642020464c4f41745f5a45524f2063"
|
||||
"6f6d706172653a206261642020666c6f61742031302d31303a206661696c6564009503046e616d65000d0c666c6f61"
|
||||
"745f302e7761736d01de0205004c5f5a4e31367872706c5f7761736d5f7374646c696234686f73743232686f73745f"
|
||||
"646566696e65645f66756e6374696f6e73357472616365313768653738323066313637383330383338364501565f5a"
|
||||
"4e31367872706c5f7761736d5f7374646c696234686f73743232686f73745f646566696e65645f66756e6374696f6e"
|
||||
"733134666c6f61745f66726f6d5f696e74313768646463636262643266613366663431634502565f5a4e3136787270"
|
||||
"6c5f7761736d5f7374646c696234686f73743232686f73745f646566696e65645f66756e6374696f6e733134666c6f"
|
||||
"61745f7375627472616374313768313765643838343131303333663437624503555f5a4e31367872706c5f7761736d"
|
||||
"5f7374646c696234686f73743232686f73745f646566696e65645f66756e6374696f6e733133666c6f61745f636f6d"
|
||||
"706172653137683835393637633834333363613334623045040666696e697368071201000f5f5f737461636b5f706f"
|
||||
"696e746572090a0100072e726f64617461004d0970726f64756365727302086c616e6775616765010452757374000c"
|
||||
"70726f6365737365642d6279010572757374631d312e38392e30202832393438333838336520323032352d30382d30"
|
||||
"34290094010f7461726765745f6665617475726573082b0b62756c6b2d6d656d6f72792b0f62756c6b2d6d656d6f72"
|
||||
"792d6f70742b1663616c6c2d696e6469726563742d6f7665726c6f6e672b0a6d756c746976616c75652b0f6d757461"
|
||||
"626c652d676c6f62616c732b136e6f6e7472617070696e672d6670746f696e742b0f7265666572656e63652d747970"
|
||||
"65732b087369676e2d657874";
|
||||
|
||||
extern std::string const disabledFloatHex =
|
||||
"0061736d010000000108026000006000017f03030200010503010002063e0a7f004180080b7f004180080b7f004180"
|
||||
|
||||
171
src/test/app/wasm_fixtures/float_0/Cargo.lock
generated
Normal file
171
src/test/app/wasm_fixtures/float_0/Cargo.lock
generated
Normal file
@@ -0,0 +1,171 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float_0"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"xrpl-wasm-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.183"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "xrpl-address-macro"
|
||||
version = "0.7.1"
|
||||
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?rev=1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8#1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"quote",
|
||||
"sha2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xrpl-wasm-stdlib"
|
||||
version = "0.7.1"
|
||||
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?rev=1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8#1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8"
|
||||
dependencies = [
|
||||
"xrpl-address-macro",
|
||||
]
|
||||
21
src/test/app/wasm_fixtures/float_0/Cargo.toml
Normal file
21
src/test/app/wasm_fixtures/float_0/Cargo.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "float_0"
|
||||
version = "0.0.1"
|
||||
edition = "2024"
|
||||
|
||||
# This empty workspace definition keeps this project independent of the parent workspace
|
||||
[workspace]
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
opt-level = 's'
|
||||
panic = "abort"
|
||||
|
||||
[dependencies]
|
||||
xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib", rev = "1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8" }
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
57
src/test/app/wasm_fixtures/float_0/src/lib.rs
Normal file
57
src/test/app/wasm_fixtures/float_0/src/lib.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
#![cfg_attr(target_arch = "wasm32", no_std)]
|
||||
|
||||
use xrpl_std::host::trace::trace;
|
||||
use xrpl_std::host::{float_compare, float_from_int, float_subtract, FLOAT_ROUNDING_MODES_TO_NEAREST};
|
||||
|
||||
// Float size constant (8 bytes mantissa + 4 bytes exponent)
|
||||
const FLOAT_SIZE: usize = 12;
|
||||
|
||||
// FLOAT_ZERO constant
|
||||
const FLOAT_ZERO: [u8; FLOAT_SIZE] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00];
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn finish() -> i32 {
|
||||
let _ = trace("\n$$$ test_float_0 $$$");
|
||||
|
||||
// Test: 10 - 10 should equal 0
|
||||
let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
|
||||
let mut f_result: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
|
||||
|
||||
// Create float from 10
|
||||
if FLOAT_SIZE as i32 != unsafe { float_from_int(10, f10.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
|
||||
let _ = trace(" float 10-10: failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Subtract: 10 - 10 = 0
|
||||
if FLOAT_SIZE as i32 != unsafe {
|
||||
float_subtract(
|
||||
f10.as_ptr(),
|
||||
FLOAT_SIZE,
|
||||
f10.as_ptr(),
|
||||
FLOAT_SIZE,
|
||||
f_result.as_mut_ptr(),
|
||||
FLOAT_SIZE,
|
||||
FLOAT_ROUNDING_MODES_TO_NEAREST,
|
||||
)
|
||||
} {
|
||||
let _ = trace(" float 10-10: failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Compare result with zero
|
||||
if 0 == unsafe { float_compare(f_result.as_ptr(), FLOAT_SIZE, f_result.as_ptr(), FLOAT_SIZE) } {
|
||||
let _ = trace(" float 0 compare: good");
|
||||
} else {
|
||||
let _ = trace(" float 0 compare: bad");
|
||||
}
|
||||
|
||||
// Compare result with FLOAT_ZERO constant
|
||||
if 0 == unsafe { float_compare(f_result.as_ptr(), FLOAT_SIZE, FLOAT_ZERO.as_ptr(), FLOAT_SIZE) } {
|
||||
let _ = trace(" FLOAT_ZERO compare: good");
|
||||
} else {
|
||||
let _ = trace(" FLOAT_ZERO compare: bad");
|
||||
}
|
||||
|
||||
1
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1568,13 +1568,15 @@ public:
|
||||
{Number{1'000'000'000'000'000ll}, Number{15}},
|
||||
{Number{5625, -4}, Number{-2'498'774'732'165'998, -16}}});
|
||||
|
||||
auto const cLarge = std::to_array<Case>(
|
||||
{{Number{false, Number::maxMantissa() - 9, -1, Number::normalized{}},
|
||||
Number{false, 1'746'901'684'478'673'451ll, -17, Number::normalized{}}},
|
||||
{Number{false, Number::maxMantissa() - 9, 0, Number::normalized{}},
|
||||
Number{false, 1'846'901'684'478'673'451ll, -17, Number::normalized{}}},
|
||||
{Number{Number::maxRep},
|
||||
Number{false, 1'861'728'612'932'620'011ll, -17, Number::normalized{}}}});
|
||||
auto const cLarge = std::to_array<Case>({
|
||||
{Number{Number::maxMantissa() - 9, -1, Number::normalized{}},
|
||||
Number{1'799'999'999'999'999'999ll, -17}},
|
||||
{Number{Number::maxMantissa() - 9, 0, Number::normalized{}},
|
||||
Number{1'899'999'999'999'999'999ll, -17}},
|
||||
{Number{Number::maxRep, 0, Number::normalized{}},
|
||||
Number{1'896'488'972'683'081'529ll, -17}},
|
||||
{Number{999'999'999'999'999'999ll}, Number{1'799'999'999'999'999'999, -17}},
|
||||
});
|
||||
|
||||
if (Number::getMantissaScale() == MantissaRange::small)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user