Merge branch 'ripple/se/wasmi-tests' into ripple/se/fees

This commit is contained in:
Mayukha Vadari
2026-06-09 17:11:35 -04:00
committed by GitHub
24 changed files with 1911 additions and 3587 deletions

View File

@@ -252,10 +252,7 @@ constexpr std::uint8_t kVaultMaximumIouScale = 18;
constexpr std::uint8_t kMaxAssetCheckDepth = 5;
/** Maximum length of a Data field in Escrow object that can be updated by WASM code. */
std::size_t constexpr maxWasmDataLength = 4 * 1024; // 4KB
/** Maximum length of parameters passed from WASM code to host functions. */
std::size_t constexpr maxWasmParamLength = 1024; // 1KB
constexpr std::size_t kMaxWasmDataLength = 1 * 1024; // 1KB
/** A ledger index. */
using LedgerIndex = std::uint32_t;

View File

@@ -8,43 +8,13 @@
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <stdexcept>
#include <string>
namespace xrpl {
enum class HostFunctionError : int32_t {
INTERNAL = -1,
FieldNotFound = -2,
BufferTooSmall = -3,
NoArray = -4,
NotLeafField = -5,
LocatorMalformed = -6,
SlotOutRange = -7,
SlotsFull = -8,
EmptySlot = -9,
LedgerObjNotFound = -10,
DECODING = -11,
DataFieldTooLarge = -12,
PointerOutOfBounds = -13,
NoMemExported = -14,
InvalidParams = -15,
InvalidAccount = -16,
InvalidField = -17,
IndexOutOfBounds = -18,
FloatInputMalformed = -19,
FloatComputationError = -20,
NoRuntime = -21,
OutOfGas = -22,
};
using FloatPair = std::pair<int64_t, int32_t>;
inline int32_t
HfErrorToInt(HostFunctionError e)
{
return static_cast<int32_t>(e);
}
namespace wasm_float {
std::string
@@ -95,32 +65,45 @@ floatPowerImpl(Slice const& x, int32_t n, int32_t mode);
} // namespace wasm_float
// Intended to work only through wasm runtime. Don't call them directly, except with unit tests
struct HostFunctions
class HostFunctions
{
beast::Journal j;
protected:
RTOptRef rt_;
beast::Journal j_;
HostFunctions(beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : j(j)
public:
HostFunctions(beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : j_(j)
{
}
// LCOV_EXCL_START
virtual void
setRT(void*)
void
setRT(WasmRuntimeWrapper& rt)
{
rt_ = rt;
}
[[nodiscard]] virtual void*
void
resetRT()
{
rt_ = std::nullopt;
}
[[nodiscard]] WasmRuntimeWrapper&
getRT() const
{
return nullptr;
if (!rt_)
Throw<std::logic_error>("Wasm runtime not set");
return rt_->get();
}
[[nodiscard]] beast::Journal
getJournal() const
{
return j;
return j_;
}
// LCOV_EXCL_START
[[nodiscard]] virtual bool
checkSelf() const
{
@@ -130,402 +113,404 @@ struct HostFunctions
virtual Expected<std::uint32_t, HostFunctionError>
getLedgerSqn() const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<std::uint32_t, HostFunctionError>
getParentLedgerTime() const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Hash, HostFunctionError>
getParentLedgerHash() const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<uint32_t, HostFunctionError>
getBaseFee() const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
isAmendmentEnabled(uint256 const& amendmentId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
isAmendmentEnabled(std::string_view const& amendmentName) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
cacheLedgerObj(uint256 const& objId, int32_t cacheIdx)
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getCurrentLedgerObjField(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getLedgerObjField(int32_t cacheIdx, SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getTxNestedField(Slice const& locator) const
getTxNestedField(FieldLocator const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(Slice const& locator) const
getCurrentLedgerObjNestedField(FieldLocator const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const
getLedgerObjNestedField(int32_t cacheIdx, FieldLocator const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getTxArrayLen(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getCurrentLedgerObjArrayLen(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getTxNestedArrayLen(Slice const& locator) const
getTxNestedArrayLen(FieldLocator const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const
getCurrentLedgerObjNestedArrayLen(FieldLocator const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const
getLedgerObjNestedArrayLen(int32_t cacheIdx, FieldLocator const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
updateData(Slice const& data)
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
accountKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
ammKeylet(Asset const& issue1, Asset const& issue2) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
checkKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType)
const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
didKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
delegateKeylet(AccountID const& account, AccountID const& authorize) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
escrowKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
nftOfferKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
offerKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
oracleKeylet(AccountID const& account, std::uint32_t docId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
signersKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
ticketKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
vaultKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getNFT(AccountID const& account, uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<std::uint32_t, HostFunctionError>
getNFTTaxon(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getNFTFlags(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
getNFTTransferFee(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<std::uint32_t, HostFunctionError>
getNFTSerial(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
trace(std::string_view const& msg, Slice const& data, bool asHex) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
traceNum(std::string_view const& msg, int64_t data) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
traceAccount(std::string_view const& msg, AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
traceFloat(std::string_view const& msg, Slice const& data) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
traceAmount(std::string_view const& msg, STAmount const& amount) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromInt(int64_t x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromUint(uint64_t x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromSTAmount(STAmount const& x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromSTNumber(STNumber const& x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int64_t, HostFunctionError>
floatToInt(Slice const& x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<FloatPair, HostFunctionError>
floatToMantExp(Slice const& x) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatFromMantExp(int64_t mantissa, int32_t exponent, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<int32_t, HostFunctionError>
floatCompare(Slice const& x, Slice const& y) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatAdd(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatDivide(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatRoot(Slice const& x, int32_t n, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual Expected<Bytes, HostFunctionError>
floatPower(Slice const& x, int32_t n, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
virtual ~HostFunctions() = default;
// LCOV_EXCL_STOP
};
using HFRef = std::reference_wrapper<HostFunctions>;
} // namespace xrpl

View File

@@ -18,8 +18,7 @@ class WasmHostFunctionsImpl : public HostFunctions
std::optional<Bytes> data_;
void* rt_ = nullptr;
public:
Expected<std::shared_ptr<SLE const>, HostFunctionError>
getCurrentLedgerObj() const
{
@@ -65,18 +64,6 @@ public:
{
}
void
setRT(void* rt) override
{
rt_ = rt;
}
void*
getRT() const override
{
return rt_;
}
bool
checkSelf() const override
{
@@ -121,13 +108,13 @@ public:
getLedgerObjField(int32_t cacheIdx, SField const& fname) const override;
Expected<Bytes, HostFunctionError>
getTxNestedField(Slice const& locator) const override;
getTxNestedField(FieldLocator const& locator) const override;
Expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(Slice const& locator) const override;
getCurrentLedgerObjNestedField(FieldLocator const& locator) const override;
Expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const override;
getLedgerObjNestedField(int32_t cacheIdx, FieldLocator const& locator) const override;
Expected<int32_t, HostFunctionError>
getTxArrayLen(SField const& fname) const override;
@@ -139,13 +126,13 @@ public:
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const override;
Expected<int32_t, HostFunctionError>
getTxNestedArrayLen(Slice const& locator) const override;
getTxNestedArrayLen(FieldLocator const& locator) const override;
Expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const override;
getCurrentLedgerObjNestedArrayLen(FieldLocator const& locator) const override;
Expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const override;
getLedgerObjNestedArrayLen(int32_t cacheIdx, FieldLocator const& locator) const override;
Expected<int32_t, HostFunctionError>
updateData(Slice const& data) override;

View File

@@ -1,6 +1,6 @@
#pragma once
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <wasm.h>
@@ -8,110 +8,86 @@
namespace xrpl {
#define WASM_CB_PARAMS_LIST void *env, wasm_val_vec_t const *params, wasm_val_vec_t *results
#define WASM_SECONDARY_CB_PARAMS_LIST \
HostFunctions &hf, wasm_val_vec_t const *params, wasm_val_vec_t *results
wasm_trap_t* HostFuncMain_wrap(WASM_CB_PARAMS_LIST);
using getLedgerSqn_proto = int32_t(uint8_t*, int32_t);
wasm_trap_t*
getLedgerSqn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getLedgerSqn_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getParentLedgerTime_proto = int32_t(uint8_t*, int32_t);
wasm_trap_t*
getParentLedgerTime_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getParentLedgerTime_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getParentLedgerHash_proto = int32_t(uint8_t*, int32_t);
wasm_trap_t*
getParentLedgerHash_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getParentLedgerHash_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getBaseFee_proto = int32_t(uint8_t*, int32_t);
wasm_trap_t*
getBaseFee_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getBaseFee_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using isAmendmentEnabled_proto = int32_t(uint8_t const*, int32_t);
wasm_trap_t*
isAmendmentEnabled_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* isAmendmentEnabled_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using cacheLedgerObj_proto = int32_t(uint8_t const*, int32_t, int32_t);
wasm_trap_t*
cacheLedgerObj_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* cacheLedgerObj_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getTxField_proto = int32_t(int32_t, uint8_t*, int32_t);
wasm_trap_t*
getTxField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getTxField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getCurrentLedgerObjField_proto = int32_t(int32_t, uint8_t*, int32_t);
wasm_trap_t*
getCurrentLedgerObjField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getCurrentLedgerObjField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getLedgerObjField_proto = int32_t(int32_t, int32_t, uint8_t*, int32_t);
wasm_trap_t*
getLedgerObjField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getLedgerObjField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getTxNestedField_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
getTxNestedField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getTxNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getCurrentLedgerObjNestedField_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
getCurrentLedgerObjNestedField_wrap(
void* env,
wasm_val_vec_t const* params,
wasm_val_vec_t* results);
wasm_trap_t* getCurrentLedgerObjNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getLedgerObjNestedField_proto = int32_t(int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
getLedgerObjNestedField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getLedgerObjNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getTxArrayLen_proto = int32_t(int32_t);
wasm_trap_t*
getTxArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getTxArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getCurrentLedgerObjArrayLen_proto = int32_t(int32_t);
wasm_trap_t*
getCurrentLedgerObjArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getCurrentLedgerObjArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getLedgerObjArrayLen_proto = int32_t(int32_t, int32_t);
wasm_trap_t*
getLedgerObjArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getLedgerObjArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getTxNestedArrayLen_proto = int32_t(uint8_t const*, int32_t);
wasm_trap_t*
getTxNestedArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getTxNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getCurrentLedgerObjNestedArrayLen_proto = int32_t(uint8_t const*, int32_t);
wasm_trap_t*
getCurrentLedgerObjNestedArrayLen_wrap(
void* env,
wasm_val_vec_t const* params,
wasm_val_vec_t* results);
wasm_trap_t* getCurrentLedgerObjNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getLedgerObjNestedArrayLen_proto = int32_t(int32_t, uint8_t const*, int32_t);
wasm_trap_t*
getLedgerObjNestedArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getLedgerObjNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using updateData_proto = int32_t(uint8_t const*, int32_t);
wasm_trap_t*
updateData_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* updateData_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using checkSignature_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t const*, int32_t);
wasm_trap_t*
checkSignature_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* checkSignature_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using computeSha512HalfHash_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
computeSha512HalfHash_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* computeSha512HalfHash_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using accountKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
accountKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* accountKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using ammKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
ammKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* ammKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using checkKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
checkKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* checkKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using credentialKeylet_proto = int32_t(
uint8_t const*,
@@ -122,27 +98,22 @@ using credentialKeylet_proto = int32_t(
int32_t,
uint8_t*,
int32_t);
wasm_trap_t*
credentialKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* credentialKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using delegateKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
delegateKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* delegateKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using depositPreauthKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
depositPreauthKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* depositPreauthKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using didKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
didKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* didKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using escrowKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
escrowKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* escrowKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using lineKeylet_proto = int32_t(
uint8_t const*,
@@ -153,33 +124,27 @@ using lineKeylet_proto = int32_t(
int32_t,
uint8_t*,
int32_t);
wasm_trap_t*
lineKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* lineKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using mptIssuanceKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
mptIssuanceKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* mptIssuanceKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using mptokenKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
mptokenKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* mptokenKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using nftOfferKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
nftOfferKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* nftOfferKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using offerKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
offerKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* offerKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using oracleKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
oracleKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* oracleKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using paychanKeylet_proto = int32_t(
uint8_t const*,
@@ -190,130 +155,100 @@ using paychanKeylet_proto = int32_t(
int32_t,
uint8_t*,
int32_t);
wasm_trap_t*
paychanKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* paychanKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using permissionedDomainKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
permissionedDomainKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* permissionedDomainKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using signersKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
signersKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* signersKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using ticketKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
ticketKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* ticketKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using vaultKeylet_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
vaultKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* vaultKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getNFT_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getNFT_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getNFTIssuer_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
getNFTIssuer_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getNFTIssuer_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getNFTTaxon_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
getNFTTaxon_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getNFTTaxon_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getNFTFlags_proto = int32_t(uint8_t const*, int32_t);
wasm_trap_t*
getNFTFlags_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getNFTFlags_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getNFTTransferFee_proto = int32_t(uint8_t const*, int32_t);
wasm_trap_t*
getNFTTransferFee_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getNFTTransferFee_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using getNFTSerial_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
getNFTSerial_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* getNFTSerial_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using trace_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, int32_t);
wasm_trap_t*
trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* trace_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using traceNum_proto = int32_t(uint8_t const*, int32_t, int64_t);
wasm_trap_t*
traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* traceNum_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using traceAccount_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
wasm_trap_t*
traceAccount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* traceAccount_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using traceFloat_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
wasm_trap_t*
traceFloat_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* traceFloat_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using traceAmount_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
wasm_trap_t*
traceAmount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* traceAmount_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatFromInt_proto = int32_t(int64_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatFromInt_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatFromInt_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatFromUint_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatFromUint_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatFromUint_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
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);
wasm_trap_t* floatFromSTAmount_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
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);
wasm_trap_t* floatFromSTNumber_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
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);
wasm_trap_t* floatToInt_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatToMantExp_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, uint8_t*, int32_t);
wasm_trap_t*
floatToMantExp_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatToMantExp_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatFromMantExp_proto = int32_t(int64_t, int32_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatFromMantExp_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatFromMantExp_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatCompare_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
wasm_trap_t*
floatCompare_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatCompare_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatAdd_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatAdd_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatAdd_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatSubtract_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatSubtract_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatSubtract_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatMultiply_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatMultiply_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatMultiply_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatDivide_proto =
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatDivide_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatDivide_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatRoot_proto = int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatRoot_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatRoot_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
using floatPower_proto = int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t, int32_t);
wasm_trap_t*
floatPower_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
wasm_trap_t* floatPower_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
} // namespace xrpl

View File

@@ -1,245 +0,0 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/mpl/vector.hpp>
#include <bit>
#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
namespace bft = boost::function_types;
namespace xrpl {
template <typename>
inline constexpr bool wasmDependentFalse = false;
using Bytes = std::vector<std::uint8_t>;
using Hash = xrpl::uint256;
struct Wmem
{
std::uint8_t* p = nullptr;
std::size_t s = 0;
};
template <typename T>
struct WasmResult
{
T result;
int64_t cost;
};
using EscrowResult = WasmResult<int32_t>;
struct WasmRuntimeWrapper
{
virtual ~WasmRuntimeWrapper() = default;
virtual Wmem
getMem() = 0;
virtual std::int64_t
getGas() = 0;
virtual std::int64_t
setGas(std::int64_t gas) = 0;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum class WasmTypes { WtI32, WtI64 };
struct WasmImportFunc
{
std::string_view name;
std::optional<WasmTypes> result;
std::vector<WasmTypes> params;
// void* udata = nullptr;
// wasm_func_callback_with_env_t
void* wrap = nullptr;
uint32_t gas = 0;
};
using WasmUserData = std::pair<void*, WasmImportFunc>;
using ImportVec = std::unordered_map<std::string_view, WasmUserData>;
#define WASM_IMPORT_FUNC(v, f, ...) \
WasmImpFunc<f##_proto>(v, #f, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
// n - string literal name, must have static lifetime
#define WASM_IMPORT_FUNC2(v, f, n, ...) \
WasmImpFunc<f##_proto>(v, n, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
template <int N, int C, typename Mpl>
void
WasmImpArgs(WasmImportFunc& e)
{
if constexpr (N < C)
{
using at = typename boost::mpl::at_c<Mpl, N>::type;
if constexpr (std::is_pointer_v<at>)
{
e.params.push_back(WasmTypes::WtI32);
}
else if constexpr (std::is_same_v<at, std::int32_t>)
{
e.params.push_back(WasmTypes::WtI32);
}
else if constexpr (std::is_same_v<at, std::int64_t>)
{
e.params.push_back(WasmTypes::WtI64);
}
else
{
static_assert(std::is_pointer_v<at>, "Unsupported argument type");
}
return WasmImpArgs<N + 1, C, Mpl>(e);
}
return;
}
template <typename Rt>
void
WasmImpRet(WasmImportFunc& e)
{
if constexpr (std::is_pointer_v<Rt>)
{
e.result = WasmTypes::WtI32;
}
else if constexpr (std::is_same_v<Rt, std::int32_t>)
{
e.result = WasmTypes::WtI32;
}
else if constexpr (std::is_same_v<Rt, std::int64_t>)
{
e.result = WasmTypes::WtI64;
}
else if constexpr (std::is_void_v<Rt>)
{
e.result.reset();
}
else
{
static_assert(wasmDependentFalse<Rt>, "Unsupported return type");
}
}
template <typename F>
void
WasmImpFuncHelper(WasmImportFunc& e)
{
using rt = typename bft::result_type<F>::type;
using pt = typename bft::parameter_types<F>::type;
// typename boost::mpl::at_c<mpl, N>::type
WasmImpRet<rt>(e);
WasmImpArgs<0, bft::function_arity<F>::value, pt>(e);
// WasmImpWrap(e, std::forward<F>(f));
}
// imp_name - string literal, must have static lifetime
template <typename F>
void
WasmImpFunc(
ImportVec& v,
std::string_view impName,
void* fWrap,
void* data = nullptr,
uint32_t gas = 0)
{
WasmImportFunc e;
e.name = impName;
e.wrap = fWrap;
e.gas = gas;
WasmImpFuncHelper<F>(e);
v.emplace(impName, std::make_pair(data, std::move(e)));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct WasmParam
{
// We are not supporting float/double
WasmTypes type = WasmTypes::WtI32;
union
{
std::int32_t i32;
std::int64_t i64 = 0;
} of;
};
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int32_t p, Types&&... args)
{
v.push_back({.type = WasmTypes::WtI32, .of = {.i32 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
{
v.push_back({.type = WasmTypes::WtI64, .of = {.i64 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
inline void
wasmParamsHlp(std::vector<WasmParam>& v)
{
return;
}
template <class... Types>
inline std::vector<WasmParam>
wasmParams(Types&&... args)
{
std::vector<WasmParam> v;
v.reserve(sizeof...(args));
wasmParamsHlp(v, std::forward<Types>(args)...);
return v;
}
template <typename T, size_t Size = sizeof(T)>
constexpr T
adjustWasmEndianessHlp(T x)
{
static_assert(std::is_integral_v<T>, "Only integral types");
if constexpr (Size > 1)
{
using U = std::make_unsigned_t<T>;
U u = static_cast<U>(x);
U const low = (u & 0xFF) << ((Size - 1) << 3);
u = adjustWasmEndianessHlp<U, Size - 1>(u >> 8);
return static_cast<T>(low | u);
}
return x;
}
template <typename T, size_t Size = sizeof(T)>
constexpr T
adjustWasmEndianess(T x)
{
// LCOV_EXCL_START
static_assert(std::is_integral_v<T>, "Only integral types");
if constexpr (std::endian::native == std::endian::big)
{
return adjustWasmEndianessHlp(x);
}
return x;
// LCOV_EXCL_STOP
}
} // namespace xrpl

View File

@@ -0,0 +1,211 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <functional>
#include <optional>
#include <stdexcept>
#include <vector>
namespace xrpl {
using Bytes = std::vector<std::uint8_t>;
using Hash = xrpl::uint256;
using FloatPair = std::pair<int64_t, int32_t>;
enum class HostFunctionError : int32_t {
Internal = -1,
FieldNotFound = -2,
BufferTooSmall = -3,
NoArray = -4,
NotLeafField = -5,
LocatorMalformed = -6,
SlotOutRange = -7,
SlotsFull = -8,
EmptySlot = -9,
LedgerObjNotFound = -10,
Decoding = -11,
DataFieldTooLarge = -12,
PointerOutOfBounds = -13,
NoMemExported = -14,
InvalidParams = -15,
InvalidAccount = -16,
InvalidField = -17,
IndexOutOfBounds = -18,
FloatInputMalformed = -19,
FloatComputationError = -20,
NoRuntime = -21,
OutOfGas = -22,
OutOfTransferLimit = -23,
};
enum class WasmTypes { WtI32, WtI64 };
struct Wmem
{
std::uint8_t* p = nullptr;
std::size_t s = 0;
Wmem() = default;
Wmem(void* ptr, std::size_t size) : p(reinterpret_cast<std::uint8_t*>(ptr)), s(size)
{
}
};
template <typename T>
struct WasmResult
{
T result;
int64_t cost;
};
using EscrowResult = WasmResult<int32_t>;
class FieldLocator
{
int32_t const* ptr_ = nullptr;
uint32_t size_ = 0;
std::vector<int32_t> buf_;
public:
FieldLocator(std::vector<int32_t>&& buf)
: ptr_(&buf[0]), size_(buf.size()), buf_(std::move(buf))
{
}
FieldLocator(int32_t const* ptr, uint32_t const size) : ptr_(ptr), size_(size)
{
}
FieldLocator(FieldLocator const&) = delete;
FieldLocator&
operator=(FieldLocator const&) = delete;
FieldLocator(FieldLocator&&) = default;
FieldLocator&
operator=(FieldLocator&&) = default;
int32_t
operator[](unsigned i) const
{
if (i >= size_)
Throw<std::runtime_error>("index out of bounds");
return ptr_[i];
}
[[nodiscard]] uint32_t
size() const
{
return size_;
}
[[nodiscard]] int32_t const*
data() const
{
return ptr_;
}
[[nodiscard]] bool
empty() const
{
return size_ == 0;
}
};
class WasmRuntimeWrapper
{
public:
virtual ~WasmRuntimeWrapper() = default;
virtual Wmem
getMem() = 0;
virtual std::int64_t
getGas() = 0;
virtual std::int64_t
setGas(std::int64_t gas) = 0;
};
using RTOptRef = std::optional<std::reference_wrapper<WasmRuntimeWrapper>>;
struct WasmParam
{
// We are not supporting float/double
WasmTypes type = WasmTypes::WtI32;
union
{
std::int32_t i32;
std::int64_t i64 = 0;
} of;
};
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int32_t p, Types&&... args)
{
v.push_back({.type = WasmTypes::WtI32, .of = {.i32 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
{
v.push_back({.type = WasmTypes::WtI64, .of = {.i64 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
inline void
wasmParamsHlp(std::vector<WasmParam>& v)
{
return;
}
template <class... Types>
inline std::vector<WasmParam>
wasmParams(Types&&... args)
{
std::vector<WasmParam> v;
v.reserve(sizeof...(args));
wasmParamsHlp(v, std::forward<Types>(args)...);
return v;
}
template <typename T, size_t Size = sizeof(T)>
constexpr T
adjustWasmEndianessHlp(T x)
{
static_assert(std::is_integral_v<T>, "Only integral types");
if constexpr (Size > 1)
{
using U = std::make_unsigned_t<T>;
U u = static_cast<U>(x);
U const low = (u & 0xFF) << ((Size - 1) << 3);
u = adjustWasmEndianessHlp<U, Size - 1>(u >> 8);
return static_cast<T>(low | u);
}
return x;
}
template <typename T, size_t Size = sizeof(T)>
constexpr T
adjustWasmEndianess(T x)
{
// LCOV_EXCL_START
static_assert(std::is_integral_v<T>, "Only integral types");
if constexpr (std::endian::native == std::endian::big)
{
return adjustWasmEndianessHlp(x);
}
return x;
// LCOV_EXCL_STOP
}
constexpr int32_t
hfErrorToInt(HostFunctionError e)
{
return static_cast<int32_t>(e);
}
} // namespace xrpl

View File

@@ -0,0 +1,128 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/mpl/vector.hpp>
#include <wasm.h>
namespace bft = boost::function_types;
namespace xrpl {
using wasmSecondaryCbFuncType =
wasm_trap_t*(HostFunctions&, wasm_val_vec_t const*, wasm_val_vec_t*);
struct WasmImportFunc
{
std::string_view name;
std::optional<WasmTypes> result;
std::vector<WasmTypes> params;
wasmSecondaryCbFuncType* wrap = nullptr;
uint32_t gas = 0;
};
using WasmUserData = std::pair<HFRef, WasmImportFunc>;
// string - import function name
using ImportVec = std::unordered_map<std::string_view, WasmUserData>;
template <int N, int C, typename Mpl>
void
WasmImpArgs(WasmImportFunc& e)
{
if constexpr (N < C)
{
using at = typename boost::mpl::at_c<Mpl, N>::type;
if constexpr (std::is_pointer_v<at>)
{
e.params.push_back(WasmTypes::WtI32);
}
else if constexpr (std::is_same_v<at, std::int32_t>)
{
e.params.push_back(WasmTypes::WtI32);
}
else if constexpr (std::is_same_v<at, std::int64_t>)
{
e.params.push_back(WasmTypes::WtI64);
}
else
{
static_assert(std::is_pointer_v<at>, "Unsupported argument type");
}
return WasmImpArgs<N + 1, C, Mpl>(e);
}
return;
}
template <typename>
inline constexpr bool wasmDependentFalse = false;
template <typename Rt>
void
WasmImpRet(WasmImportFunc& e)
{
if constexpr (std::is_pointer_v<Rt>)
{
e.result = WasmTypes::WtI32;
}
else if constexpr (std::is_same_v<Rt, std::int32_t>)
{
e.result = WasmTypes::WtI32;
}
else if constexpr (std::is_same_v<Rt, std::int64_t>)
{
e.result = WasmTypes::WtI64;
}
else if constexpr (std::is_void_v<Rt>)
{
e.result.reset();
}
else
{
static_assert(wasmDependentFalse<Rt>, "Unsupported return type");
}
}
template <typename F>
void
WasmImpFuncHelper(WasmImportFunc& e)
{
using rt = typename bft::result_type<F>::type;
using pt = typename bft::parameter_types<F>::type;
// typename boost::mpl::at_c<mpl, N>::type
WasmImpRet<rt>(e);
WasmImpArgs<0, bft::function_arity<F>::value, pt>(e);
// WasmImpWrap(e, std::forward<F>(f));
}
// imp_name - string literal, must have static lifetime
template <typename F>
void
WasmImpFunc(
ImportVec& v,
std::string_view impName,
wasmSecondaryCbFuncType* fWrap,
HostFunctions& hf,
uint32_t gas = 0)
{
WasmImportFunc e;
e.name = impName;
e.wrap = fWrap;
e.gas = gas;
WasmImpFuncHelper<F>(e);
v.emplace(impName, std::make_pair(HFRef(hf), std::move(e)));
}
#define WASM_IMPORT_FUNC(v, f, ...) WasmImpFunc<f##_proto>(v, #f, &f##_wrap, ##__VA_ARGS__)
// n - string literal name, must have static lifetime
#define WASM_IMPORT_FUNC2(v, f, n, ...) WasmImpFunc<f##_proto>(v, n, &f##_wrap, ##__VA_ARGS__)
} // namespace xrpl

View File

@@ -1,6 +1,7 @@
#pragma once
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <string_view>

View File

@@ -1,5 +1,6 @@
#pragma once
#include <xrpl/protocol/Protocol.h>
#include <xrpl/tx/wasm/WasmVM.h>
#include <wasm.h>
@@ -139,13 +140,13 @@ using StorePtr = std::unique_ptr<wasm_store_t, decltype(&wasm_store_delete)>;
using FuncInfo = std::pair<wasm_func_t const*, wasm_functype_t const*>;
struct InstanceWrapper
class InstanceWrapper
{
wasm_store_t* store = nullptr;
WasmExternVec exports;
mutable int memIdx = -1;
InstancePtr instance;
beast::Journal j = beast::Journal(beast::Journal::getNullSink());
wasm_store_t* store_ = nullptr;
WasmExternVec exports_;
mutable int memIdx_ = -1;
InstancePtr instance_;
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
private:
static InstancePtr
@@ -157,13 +158,19 @@ private:
beast::Journal j);
public:
InstanceWrapper();
InstanceWrapper() : instance_(nullptr, &wasm_instance_delete) {};
InstanceWrapper(InstanceWrapper const&) = delete;
InstanceWrapper(InstanceWrapper&& o);
InstanceWrapper(InstanceWrapper&& o) : instance_(nullptr, &wasm_instance_delete)
{
*this = std::move(o); // LCOV_EXCL_LINE
}
InstanceWrapper(StorePtr& s, ModulePtr& m, WasmExternVec const& imports, beast::Journal j);
InstanceWrapper(StorePtr& s, ModulePtr& m, WasmExternVec const& imports, beast::Journal j)
: store_(s.get()), instance_(init(s, m, exports_, imports, j)), j_(j)
{
}
InstanceWrapper&
operator=(InstanceWrapper&& o);
@@ -171,7 +178,10 @@ public:
InstanceWrapper&
operator=(InstanceWrapper const&) = delete;
operator bool() const;
operator bool() const
{
return static_cast<bool>(instance_);
}
FuncInfo
getFunc(std::string_view funcName, WasmExporttypeVec const& exportTypes) const;
@@ -186,20 +196,25 @@ public:
setGas(std::int64_t) const;
};
struct ModuleWrapper
class ModuleWrapper
{
ModulePtr module;
InstanceWrapper instanceWrap;
WasmExporttypeVec exportTypes;
beast::Journal j = beast::Journal(beast::Journal::getNullSink());
private:
static ModulePtr
init(StorePtr& s, Bytes const& wasmBin, beast::Journal j);
ModulePtr module_;
InstanceWrapper instanceWrap_;
WasmExporttypeVec exportTypes_;
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
public:
ModuleWrapper();
ModuleWrapper(ModuleWrapper&& o);
// LCOV_EXCL_START
ModuleWrapper() : module_(nullptr, &wasm_module_delete)
{
}
ModuleWrapper(ModuleWrapper&& o) : module_(nullptr, &wasm_module_delete)
{
*this = std::move(o);
}
// LCOV_EXCL_STOP
ModuleWrapper&
operator=(ModuleWrapper&& o);
ModuleWrapper(
@@ -210,27 +225,55 @@ public:
beast::Journal j);
~ModuleWrapper() = default;
operator bool() const;
operator bool() const
{
return instanceWrap_;
}
FuncInfo
getFunc(std::string_view funcName) const;
getFunc(std::string_view funcName) const
{
return instanceWrap_.getFunc(funcName, exportTypes_);
}
wasm_functype_t*
getFuncType(std::string_view funcName) const;
Wmem
getMem() const;
getMem() const
{
return instanceWrap_.getMem();
}
InstanceWrapper&
getInstance(int i = 0);
getInstance(int i = 0)
{
return instanceWrap_;
}
InstanceWrapper const&
getInstance(int i = 0) const
{
return instanceWrap_;
}
int
addInstance(StorePtr& s, WasmExternVec const& imports);
addInstance(StorePtr& s, WasmExternVec const& imports)
{
instanceWrap_ = {s, module_, imports, j_};
return 0;
}
std::int64_t
getGas() const;
getGas() const
{
return instanceWrap_ ? instanceWrap_.getGas() : -1;
}
private:
static ModulePtr
init(StorePtr& s, Bytes const& wasmBin, beast::Journal j);
WasmExternVec
buildImports(StorePtr& s, ImportVec const& imports) const;
};
@@ -245,7 +288,10 @@ class WasmiEngine
std::mutex m_; // 1 instance mutex
public:
WasmiEngine();
WasmiEngine() : engine_(init()), store_(nullptr, &wasm_store_delete)
{
}
~WasmiEngine() = default;
static EnginePtr
@@ -270,21 +316,37 @@ public:
beast::Journal j);
[[nodiscard]] std::int64_t
getGas() const;
getGas() const
{
return moduleWrap_ ? moduleWrap_->getGas() : -1; // LCOV_EXCL_LINE
}
// Host functions helper functionality
wasm_trap_t*
newTrap(std::string const& msg);
// LCOV_EXCL_START
[[nodiscard]] beast::Journal
getJournal() const;
getJournal() const
{
return j_;
}
// LCOV_EXCL_STOP
private:
[[nodiscard]] InstanceWrapper&
getRT(int m = 0, int i = 0) const;
getRT(int m = 0, int i = 0) const
{
if (!moduleWrap_)
Throw<std::runtime_error>("no module");
return moduleWrap_->getInstance(i);
}
[[nodiscard]] Wmem
getMem() const;
getMem() const
{
return moduleWrap_ ? moduleWrap_->getMem() : Wmem();
}
Expected<WasmResult<int32_t>, TER>
runHlp(
@@ -319,7 +381,10 @@ private:
makeModule(Bytes const& wasmCode, WasmExternVec const& imports = {});
[[nodiscard]] FuncInfo
getFunc(std::string_view funcName) const;
getFunc(std::string_view funcName) const
{
return moduleWrap_->getFunc(funcName);
}
static std::vector<wasm_val_t>
convertParams(std::vector<WasmParam> const& params);

View File

@@ -5,8 +5,7 @@
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>
@@ -19,10 +18,9 @@ namespace xrpl {
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::updateData(Slice const& data)
{
if (data.size() > maxWasmDataLength)
{
if (data.size() > kMaxWasmDataLength)
return Unexpected(HostFunctionError::DataFieldTooLarge);
}
data_ = Bytes(data.begin(), data.end());
return data_->size();
}

View File

@@ -6,7 +6,7 @@
#include <xrpl/protocol/Serializer.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <boost/algorithm/hex.hpp>

View File

@@ -4,18 +4,15 @@
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/STBitString.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>
#include <cstring>
#include <utility>
#include <variant>
@@ -119,16 +116,12 @@ static Expected<Bytes, HostFunctionError>
getAnyFieldData(FieldValue const& variantObj)
{
if (STBase const* const* obj = std::get_if<STBase const*>(&variantObj))
{
return getAnyFieldData(*obj);
}
if (uint256 const* const* u = std::get_if<uint256 const*>(&variantObj))
{
return Bytes((*u)->begin(), (*u)->end());
}
return Unexpected(HostFunctionError::INTERNAL); // LCOV_EXCL_LINE
return Unexpected(HostFunctionError::Internal); // LCOV_EXCL_LINE
}
static inline bool
@@ -139,33 +132,13 @@ noField(STBase const* field)
}
static Expected<FieldValue, HostFunctionError>
locateField(STObject const& obj, Slice const& locator)
locateField(STObject const& obj, FieldLocator const& locator)
{
if (locator.empty() || ((locator.size() & 3) != 0u)) // must be multiple of 4
return Unexpected(HostFunctionError::LocatorMalformed);
static_assert(maxWasmParamLength % sizeof(int32_t) == 0);
int32_t locBuf[maxWasmParamLength / sizeof(int32_t)];
int32_t const* locPtr = &locBuf[0];
int32_t const locSize = locator.size() / sizeof(int32_t);
{
uintptr_t const p = reinterpret_cast<uintptr_t>(locator.data());
if ((p & (alignof(int32_t) - 1)) != 0u)
{ // unaligned
memcpy(&locBuf[0], locator.data(), locator.size());
}
else
{
locPtr = reinterpret_cast<int32_t const*>(locator.data());
}
}
STBase const* field = nullptr;
auto const& knownSFields = SField::getKnownCodeToField();
{
int32_t const sfieldCode = adjustWasmEndianess(locPtr[0]);
int32_t const sfieldCode = adjustWasmEndianess(locator[0]);
auto const it = knownSFields.find(sfieldCode);
if (it == knownSFields.end())
return Unexpected(HostFunctionError::InvalidField);
@@ -176,9 +149,9 @@ locateField(STObject const& obj, Slice const& locator)
return Unexpected(HostFunctionError::FieldNotFound);
}
for (int i = 1; i < locSize; ++i)
for (unsigned i = 1; i < locator.size(); ++i)
{
int32_t const sfieldCode = adjustWasmEndianess(locPtr[i]);
int32_t const sfieldCode = adjustWasmEndianess(locator[i]);
if (STI_ARRAY == field->getSType())
{
@@ -290,7 +263,7 @@ WasmHostFunctionsImpl::getLedgerObjField(int32_t cacheIdx, SField const& fname)
// Subsection: nested getters
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getTxNestedField(Slice const& locator) const
WasmHostFunctionsImpl::getTxNestedField(FieldLocator const& locator) const
{
auto const r = locateField(ctx_.tx, locator);
if (!r)
@@ -300,7 +273,7 @@ WasmHostFunctionsImpl::getTxNestedField(Slice const& locator) const
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator) const
WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(FieldLocator const& locator) const
{
auto const sle = getCurrentLedgerObj();
if (!sle.has_value())
@@ -314,7 +287,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator) cons
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const
WasmHostFunctionsImpl::getLedgerObjNestedField(int32_t cacheIdx, FieldLocator const& locator) const
{
auto const normalizedIdx = normalizeCacheIndex(cacheIdx);
if (!normalizedIdx.has_value())
@@ -379,7 +352,7 @@ WasmHostFunctionsImpl::getLedgerObjArrayLen(int32_t cacheIdx, SField const& fnam
// Subsection: nested array length getters
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator) const
WasmHostFunctionsImpl::getTxNestedArrayLen(FieldLocator const& locator) const
{
auto const r = locateField(ctx_.tx, locator);
if (!r)
@@ -390,7 +363,7 @@ WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator) const
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator) const
WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(FieldLocator const& locator) const
{
auto const sle = getCurrentLedgerObj();
if (!sle.has_value())
@@ -404,7 +377,8 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator) c
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const
WasmHostFunctionsImpl::getLedgerObjNestedArrayLen(int32_t cacheIdx, FieldLocator const& locator)
const
{
auto const normalizedIdx = normalizeCacheIndex(cacheIdx);
if (!normalizedIdx.has_value())

View File

@@ -6,9 +6,8 @@
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>

View File

@@ -1,9 +1,8 @@
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/ledger/AmendmentTable.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>
#include <string>

View File

@@ -5,9 +5,8 @@
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/nft.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,8 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/tx/wasm/HostFuncWrapper.h> // IWYU pragma: keep
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <cstdint>
#include <string>
@@ -27,7 +28,7 @@ namespace xrpl {
// See XLS-0102 §6.5 (Future-Proofing):
// https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0102-wasm-vm#65-future-proofing
static void
setCommonHostFunctions(HostFunctions* hfs, ImportVec& i)
setCommonHostFunctions(HostFunctions& hfs, ImportVec& i)
{
// clang-format off
WASM_IMPORT_FUNC2(i, getLedgerSqn, "get_ledger_sqn", hfs, 60);
@@ -108,8 +109,8 @@ createWasmImport(HostFunctions& hfs)
{
ImportVec i;
setCommonHostFunctions(&hfs, i);
WASM_IMPORT_FUNC2(i, updateData, "update_data", &hfs, 1000);
setCommonHostFunctions(hfs, i);
WASM_IMPORT_FUNC2(i, updateData, "update_data", hfs, 1000);
return i;
}
@@ -140,7 +141,7 @@ runEscrowWasm(
#ifdef DEBUG_OUTPUT
std::cout << ", ret: " << ret->result << ", gas spent: " << ret->cost << std::endl;
#endif
return EscrowResult{ret->result, ret->cost};
return EscrowResult{.result = ret->result, .cost = ret->cost};
}
NotTEC

View File

@@ -5,7 +5,8 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <xrpl/tx/wasm/WasmVM.h>
#include <wasmi/config.h>
@@ -34,6 +35,9 @@
namespace xrpl {
wasm_trap_t*
HostFuncMain_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
namespace {
void
@@ -76,30 +80,31 @@ printWasmError(std::string_view msg, wasm_trap_t* trap, beast::Journal jlog)
} // namespace
struct WasmiRuntimeWrapper : public WasmRuntimeWrapper
class WasmiRuntimeWrapper : public WasmRuntimeWrapper
{
InstanceWrapper& iw;
InstanceWrapper& iw_;
WasmiRuntimeWrapper(InstanceWrapper& iw) : iw(iw)
public:
WasmiRuntimeWrapper(InstanceWrapper& iw) : iw_(iw)
{
}
Wmem
getMem() override
{
return iw.getMem();
return iw_.getMem();
}
std::int64_t
getGas() override
{
return iw.getGas();
return iw_.getGas();
}
std::int64_t
setGas(std::int64_t gas) override
{
return iw.setGas(gas);
return iw_.setGas(gas);
}
};
@@ -118,69 +123,43 @@ InstanceWrapper::init(
if (!mi || (trap != nullptr))
{
printWasmError("can't create instance", trap, j);
throw std::runtime_error("can't create instance");
Throw<std::runtime_error>("can't create instance");
}
wasm_instance_exports(mi.get(), expt.get());
return mi;
}
InstanceWrapper::InstanceWrapper() : instance(nullptr, &wasm_instance_delete)
{
}
// LCOV_EXCL_START
InstanceWrapper::InstanceWrapper(InstanceWrapper&& o) : instance(nullptr, &wasm_instance_delete)
{
*this = std::move(o);
}
// LCOV_EXCL_STOP
InstanceWrapper::InstanceWrapper(
StorePtr& s,
ModulePtr& m,
WasmExternVec const& imports,
beast::Journal j)
: store(s.get()), instance(init(s, m, exports, imports, j)), j(j)
{
}
InstanceWrapper&
InstanceWrapper::operator=(InstanceWrapper&& o)
{
if (this == &o)
return *this; // LCOV_EXCL_LINE
store = o.store;
o.store = nullptr;
exports = std::move(o.exports);
memIdx = o.memIdx;
o.memIdx = -1;
instance = std::move(o.instance);
store_ = o.store_;
o.store_ = nullptr;
exports_ = std::move(o.exports_);
memIdx_ = o.memIdx_;
o.memIdx_ = -1;
instance_ = std::move(o.instance_);
j = o.j;
j_ = o.j_;
return *this;
}
InstanceWrapper::
operator bool() const
{
return static_cast<bool>(instance);
}
FuncInfo
InstanceWrapper::getFunc(std::string_view funcName, WasmExporttypeVec const& exportTypes) const
{
wasm_func_t const* f = nullptr;
wasm_functype_t const* ft = nullptr;
if (!instance)
throw std::runtime_error("no instance"); // LCOV_EXCL_LINE
if (!instance_)
Throw<std::runtime_error>("no instance"); // LCOV_EXCL_LINE
if (exportTypes.empty())
throw std::runtime_error("no export"); // LCOV_EXCL_LINE
if (exportTypes.size() != exports.size())
throw std::runtime_error("invalid export"); // LCOV_EXCL_LINE
Throw<std::runtime_error>("no export"); // LCOV_EXCL_LINE
if (exportTypes.size() != exports_.size())
Throw<std::runtime_error>("invalid export"); // LCOV_EXCL_LINE
for (unsigned i = 0; i < exportTypes.size(); ++i)
{
@@ -193,9 +172,9 @@ InstanceWrapper::getFunc(std::string_view funcName, WasmExporttypeVec const& exp
if (funcName != std::string_view(name->data, name->size))
continue;
auto const* exn(exports[i]);
auto const* exn(exports_[i]);
if (wasm_extern_kind(exn) != WASM_EXTERN_FUNC)
throw std::runtime_error("invalid export"); // LCOV_EXCL_LINE
Throw<std::runtime_error>("invalid export"); // LCOV_EXCL_LINE
ft = wasm_externtype_as_functype_const(exnType);
f = wasm_extern_as_func_const(exn);
@@ -204,7 +183,7 @@ InstanceWrapper::getFunc(std::string_view funcName, WasmExporttypeVec const& exp
}
if ((f == nullptr) || (ft == nullptr))
throw std::runtime_error("can't find function <" + std::string(funcName) + ">");
Throw<std::runtime_error>("can't find function <" + std::string(funcName) + ">");
return {f, ft};
}
@@ -212,22 +191,20 @@ InstanceWrapper::getFunc(std::string_view funcName, WasmExporttypeVec const& exp
Wmem
InstanceWrapper::getMem() const
{
if (memIdx >= 0)
if (memIdx_ >= 0)
{
auto* e(exports[memIdx]);
auto* e(exports_[memIdx_]);
wasm_memory_t* mem = wasm_extern_as_memory(e);
return {
.p = reinterpret_cast<std::uint8_t*>(wasm_memory_data(mem)),
.s = wasm_memory_data_size(mem)};
return Wmem(wasm_memory_data(mem), wasm_memory_data_size(mem));
}
wasm_memory_t* mem = nullptr;
for (int i = 0; i < exports.size(); ++i)
for (int i = 0; i < exports_.size(); ++i)
{
auto* e(exports[i]);
auto* e(exports_[i]);
if (wasm_extern_kind(e) == WASM_EXTERN_MEMORY)
{
memIdx = i;
memIdx_ = i;
mem = wasm_extern_as_memory(e);
break;
}
@@ -236,34 +213,32 @@ InstanceWrapper::getMem() const
if (mem == nullptr)
return {}; // LCOV_EXCL_LINE
return {
.p = reinterpret_cast<std::uint8_t*>(wasm_memory_data(mem)),
.s = wasm_memory_data_size(mem)};
return Wmem(wasm_memory_data(mem), wasm_memory_data_size(mem));
}
std::int64_t
InstanceWrapper::getGas() const
{
if (store == nullptr)
if (store_ == nullptr)
return -1; // LCOV_EXCL_LINE
std::uint64_t gas = 0;
wasm_store_get_fuel(store, &gas);
wasm_store_get_fuel(store_, &gas);
return static_cast<std::int64_t>(gas);
}
std::int64_t
InstanceWrapper::setGas(std::int64_t gas) const
{
if (store == nullptr)
if (store_ == nullptr)
return -1; // LCOV_EXCL_LINE
if (gas < 0)
gas = std::numeric_limits<decltype(gas)>::max();
wasmi_error_t* err = wasm_store_set_fuel(store, static_cast<std::uint64_t>(gas));
wasmi_error_t* err = wasm_store_set_fuel(store_, static_cast<std::uint64_t>(gas));
if (err != nullptr)
{
// LCOV_EXCL_START
printWasmError("Can't set instance gas", nullptr, j);
printWasmError("Can't set instance gas", nullptr, j_);
wasmi_error_delete(err);
return -1;
// LCOV_EXCL_STOP
@@ -277,7 +252,7 @@ InstanceWrapper::setGas(std::int64_t gas) const
ModulePtr
ModuleWrapper::init(StorePtr& s, Bytes const& wasmBin, beast::Journal j)
{
wasm_byte_vec_t const code{wasmBin.size(), (char*)(wasmBin.data())};
wasm_byte_vec_t const code{.size = wasmBin.size(), .data = (char*)(wasmBin.data())};
ModulePtr m = ModulePtr(wasm_module_new(s.get(), &code), &wasm_module_delete);
if (!m)
throw std::runtime_error("can't create module");
@@ -285,26 +260,15 @@ ModuleWrapper::init(StorePtr& s, Bytes const& wasmBin, beast::Journal j)
return m;
}
// LCOV_EXCL_START
ModuleWrapper::ModuleWrapper() : module(nullptr, &wasm_module_delete)
{
}
ModuleWrapper::ModuleWrapper(ModuleWrapper&& o) : module(nullptr, &wasm_module_delete)
{
*this = std::move(o);
}
// LCOV_EXCL_STOP
ModuleWrapper::ModuleWrapper(
StorePtr& s,
Bytes const& wasmBin,
bool instantiate,
ImportVec const& imports,
beast::Journal j)
: module(init(s, wasmBin, j)), j(j)
: module_(init(s, wasmBin, j)), j_(j)
{
wasm_module_exports(module.get(), exportTypes.get());
wasm_module_exports(module_.get(), exportTypes_.get());
auto wimports = buildImports(s, imports);
if (instantiate)
{
@@ -319,20 +283,14 @@ ModuleWrapper::operator=(ModuleWrapper&& o)
if (this == &o)
return *this;
module = std::move(o.module);
instanceWrap = std::move(o.instanceWrap);
exportTypes = std::move(o.exportTypes);
j = o.j;
module_ = std::move(o.module_);
instanceWrap_ = std::move(o.instanceWrap_);
exportTypes_ = std::move(o.exportTypes_);
j_ = o.j_;
return *this;
}
ModuleWrapper::
operator bool() const
{
return instanceWrap;
}
// LCOV_EXCL_STOP
static WasmValtypeVec
@@ -391,7 +349,7 @@ WasmExternVec
ModuleWrapper::buildImports(StorePtr& s, ImportVec const& imports) const
{
WasmImporttypeVec importTypes;
wasm_module_imports(module.get(), importTypes.get());
wasm_module_imports(module_.get(), importTypes.get());
if (importTypes.empty())
return {};
@@ -424,12 +382,12 @@ ModuleWrapper::buildImports(StorePtr& s, ImportVec const& imports) const
auto const it = imports.find(fieldName);
if (it == imports.end())
{
printWasmError("Import not found: " + std::string(fieldName), nullptr, j);
printWasmError("Import not found: " + std::string(fieldName), nullptr, j_);
continue; // print all missed import
}
auto const& obj = it->second;
auto const& imp = obj.second;
WasmUserData const& obj = it->second;
WasmImportFunc const& imp = obj.second;
WasmValtypeVec params(makeImpParams(imp));
WasmValtypeVec results(makeImpReturn(imp));
@@ -440,12 +398,8 @@ ModuleWrapper::buildImports(StorePtr& s, ImportVec const& imports) const
params.release();
results.release();
wasm_func_t* func = wasm_func_new_with_env(
s.get(),
ftype.get(),
reinterpret_cast<wasm_func_callback_with_env_t>(imp.wrap),
(void*)&obj,
nullptr);
wasm_func_t* func =
wasm_func_new_with_env(s.get(), ftype.get(), HostFuncMain_wrap, (void*)&obj, nullptr);
if (func == nullptr)
{
Throw<std::runtime_error>(
@@ -462,25 +416,19 @@ ModuleWrapper::buildImports(StorePtr& s, ImportVec const& imports) const
std::string("Imports not finished: ") + std::to_string(impCnt) + "/" +
std::to_string(importTypes.size()),
nullptr,
j);
j_);
Throw<std::runtime_error>("Missing imports");
}
return wimports;
}
FuncInfo
ModuleWrapper::getFunc(std::string_view funcName) const
{
return instanceWrap.getFunc(funcName, exportTypes);
}
wasm_functype_t*
ModuleWrapper::getFuncType(std::string_view funcName) const
{
for (size_t i = 0; i < exportTypes.size(); i++)
for (size_t i = 0; i < exportTypes_.size(); i++)
{
auto const* expType(exportTypes[i]);
auto const* expType(exportTypes_[i]);
wasm_name_t const* name = wasm_exporttype_name(expType);
wasm_externtype_t const* exnType = wasm_exporttype_type(expType);
if (wasm_externtype_kind(exnType) == WASM_EXTERN_FUNC &&
@@ -493,25 +441,6 @@ ModuleWrapper::getFuncType(std::string_view funcName) const
throw std::runtime_error("can't find function <" + std::string(funcName) + ">");
}
Wmem
ModuleWrapper::getMem() const
{
return instanceWrap.getMem();
}
InstanceWrapper&
ModuleWrapper::getInstance(int)
{
return instanceWrap;
}
int
ModuleWrapper::addInstance(StorePtr& s, WasmExternVec const& imports)
{
instanceWrap = {s, module, imports, j};
return 0;
}
// int
// my_module_t::delInstance(int i)
// {
@@ -522,12 +451,6 @@ ModuleWrapper::addInstance(StorePtr& s, WasmExternVec const& imports)
// return i;
// }
std::int64_t
ModuleWrapper::getGas() const
{
return instanceWrap ? instanceWrap.getGas() : -1;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// void
@@ -567,10 +490,6 @@ WasmiEngine::init()
wasm_engine_new_with_config(config), &wasm_engine_delete);
}
WasmiEngine::WasmiEngine() : engine_(init()), store_(nullptr, &wasm_store_delete)
{
}
int
WasmiEngine::addModule(
Bytes const& wasmCode,
@@ -608,12 +527,6 @@ WasmiEngine::addModule(
// return module->addInstance(store.get());
// }
FuncInfo
WasmiEngine::getFunc(std::string_view funcName) const
{
return moduleWrap_->getFunc(funcName);
}
std::vector<wasm_val_t>
WasmiEngine::convertParams(std::vector<WasmParam> const& params)
{
@@ -711,8 +624,8 @@ WasmiResult
WasmiEngine::call(FuncInfo const& f, std::vector<wasm_val_t>& in)
{
WasmiResult ret(NR);
wasm_val_vec_t const inv =
in.empty() ? wasm_val_vec_t WASM_EMPTY_VEC : wasm_val_vec_t{in.size(), in.data()};
wasm_val_vec_t const inv = in.empty() ? wasm_val_vec_t WASM_EMPTY_VEC
: wasm_val_vec_t{.size = in.size(), .data = in.data()};
#ifdef SHOW_CALL_TIME
auto const start = usecs();
@@ -763,7 +676,7 @@ checkImports(ImportVec const& imports, HostFunctions* hfs)
{
for (auto const& obj : imports)
{
if (hfs != obj.second.first)
if (hfs != &obj.second.first.get())
Throw<std::runtime_error>("Imports hf unsync");
}
}
@@ -821,13 +734,13 @@ WasmiEngine::runHlp(
// Create and instantiate the module.
[[maybe_unused]] int const m = addModule(wasmCode, true, imports, gas);
if (!moduleWrap_ || !moduleWrap_->instanceWrap)
if (!moduleWrap_ || !moduleWrap_->getInstance())
throw std::runtime_error("no instance"); // LCOV_EXCL_LINE
auto clear = [](HostFunctions* p) { p->setRT(nullptr); };
std::unique_ptr<HostFunctions, decltype(clear)> const clearGuard(&hfs, clear);
auto clearRT = [](HostFunctions* p) { p->resetRT(); };
std::unique_ptr<HostFunctions, decltype(clearRT)> const clearGuard(&hfs, clearRT);
WasmiRuntimeWrapper iw(getRT());
hfs.setRT(&iw);
hfs.setRT(iw);
// Call main
auto const f = getFunc(!funcName.empty() ? funcName : "_start");
@@ -843,19 +756,17 @@ WasmiEngine::runHlp(
auto const res = call<1>(f, p);
if (res.f)
{
throw std::runtime_error("<" + std::string(funcName) + "> failure");
}
Throw<std::runtime_error>("<" + std::string(funcName) + "> failure");
if (res.r.empty())
{
throw std::runtime_error(
Throw<std::runtime_error>(
"<" + std::string(funcName) + "> return nothing"); // LCOV_EXCL_LINE
}
if (res.r[0].kind != WASM_I32)
{
throw std::runtime_error(
Throw<std::runtime_error>(
"<" + std::string(funcName) +
"> return type mismatch, ret: " + std::to_string(static_cast<int>(res.r[0].kind)));
}
@@ -934,33 +845,11 @@ WasmiEngine::checkHlp(
return tesSUCCESS;
}
// LCOV_EXCL_START
std::int64_t
WasmiEngine::getGas() const
{
return moduleWrap_ ? moduleWrap_->getGas() : -1;
}
// LCOV_EXCL_STOP
Wmem
WasmiEngine::getMem() const
{
return moduleWrap_ ? moduleWrap_->getMem() : Wmem();
}
InstanceWrapper&
WasmiEngine::getRT(int m, int i) const
{
if (!moduleWrap_)
throw std::runtime_error("no module");
return moduleWrap_->getInstance(i);
}
wasm_trap_t*
WasmiEngine::newTrap(std::string const& txt)
{
static char empty[1] = {0};
wasm_message_t msg = {1, empty};
wasm_message_t msg = {.size = 1, .data = empty};
if (!txt.empty())
wasm_name_new(&msg, txt.size() + 1, txt.c_str()); // include 0
@@ -973,12 +862,4 @@ WasmiEngine::newTrap(std::string const& txt)
return trap;
}
// LCOV_EXCL_START
beast::Journal
WasmiEngine::getJournal() const
{
return j_;
}
// LCOV_EXCL_STOP
} // namespace xrpl

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,5 @@
#pragma once
#include <test/app/wasm_fixtures/fixtures.h>
#include <test/jtx/Env.h>
#include <test/unit_test/SuiteJournal.h>
@@ -18,62 +20,35 @@
namespace xrpl::test {
struct TestLedgerDataProvider : public HostFunctions
class TestLedgerDataProvider : public HostFunctions
{
jtx::Env& env;
void* rt = nullptr;
jtx::Env& env_;
public:
TestLedgerDataProvider(jtx::Env& env) : HostFunctions(env.journal), env(env)
TestLedgerDataProvider(jtx::Env& env) : HostFunctions(env.journal), env_(env)
{
}
void
setRT(void* rt) override
{
this->rt = rt;
}
[[nodiscard]] void*
getRT() const override
{
return rt;
}
Expected<std::uint32_t, HostFunctionError>
getLedgerSqn() const override
{
return env.current()->seq();
return env_.current()->seq();
}
};
struct TestHostFunctions : public HostFunctions
class TestHostFunctions : public HostFunctions
{
test::jtx::Env& env;
AccountID accountID;
Bytes data;
int clock_drift = 0;
void* rt = nullptr;
protected:
test::jtx::Env& env_;
AccountID accountID_;
Bytes data_;
public:
TestHostFunctions(test::jtx::Env& env, int cd = 0)
: HostFunctions(env.journal), env(env), clock_drift(cd)
TestHostFunctions(test::jtx::Env& env) : HostFunctions(env.journal), env_(env)
{
accountID = env.master.id();
accountID_ = env.master.id();
std::string t = "10000";
data = Bytes{t.begin(), t.end()};
}
void
setRT(void* rt) override
{
this->rt = rt;
}
[[nodiscard]] void*
getRT() const override
{
return rt;
data_ = Bytes{t.begin(), t.end()};
}
Expected<std::uint32_t, HostFunctionError>
@@ -91,7 +66,7 @@ public:
Expected<Hash, HostFunctionError>
getParentLedgerHash() const override
{
return env.current()->header().parentHash;
return env_.current()->header().parentHash;
}
Expected<std::uint32_t, HostFunctionError>
@@ -122,15 +97,15 @@ public:
getTxField(SField const& fname) const override
{
if (fname == sfAccount)
{
return Bytes(accountID.begin(), accountID.end());
}
return Bytes(accountID_.begin(), accountID_.end());
if (fname == sfFee)
{
int64_t x = 235;
uint8_t const* p = reinterpret_cast<uint8_t const*>(&x);
return Bytes{p, p + sizeof(x)};
}
if (fname == sfSequence)
{
auto const x = getLedgerSqn();
@@ -141,6 +116,7 @@ public:
auto const* e = reinterpret_cast<uint8_t const*>(&data + 1);
return Bytes{b, e};
}
return Bytes();
}
@@ -149,25 +125,21 @@ public:
{
auto const& sn = fname.getName();
if (sn == "Destination" || sn == "Account")
{
return Bytes(accountID.begin(), accountID.end());
}
return Bytes(accountID_.begin(), accountID_.end());
if (sn == "Data")
{
return data;
}
return data_;
if (sn == "FinishAfter")
{
auto t = env.current()->parentCloseTime().time_since_epoch().count();
auto t = env_.current()->parentCloseTime().time_since_epoch().count();
std::string s = std::to_string(t);
return Bytes{s.begin(), s.end()};
}
return Unexpected(HostFunctionError::INTERNAL);
return Unexpected(HostFunctionError::Internal);
}
Expected<Bytes, HostFunctionError>
getLedgerObjField(int32_t cacheIdx, SField const& fname) const override
getLedgerObjField(int32_t, SField const& fname) const override
{
if (fname == sfBalance)
{
@@ -175,25 +147,24 @@ public:
uint8_t const* p = reinterpret_cast<uint8_t const*>(&x);
return Bytes{p, p + sizeof(x)};
}
if (fname == sfAccount)
{
return Bytes(accountID.begin(), accountID.end());
}
return data;
return Bytes(accountID_.begin(), accountID_.end());
return data_;
}
Expected<Bytes, HostFunctionError>
getTxNestedField(Slice const& locator) const override
getTxNestedField(FieldLocator const& locator) const override
{
if (locator.size() == 4)
if (locator.size() == 1)
{
int32_t const* l = reinterpret_cast<int32_t const*>(locator.data());
int32_t const* l = locator.data();
int32_t const sfield = l[0];
if (sfield == sfAccount.getCode())
{
return Bytes(accountID.begin(), accountID.end());
}
return Bytes(accountID_.begin(), accountID_.end());
}
uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2,
0x45, 0x9f, 0xa4, 0xa0, 0x34, 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92,
0xfc, 0xee, 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00};
@@ -201,17 +172,16 @@ public:
}
Expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(Slice const& locator) const override
getCurrentLedgerObjNestedField(FieldLocator const& locator) const override
{
if (locator.size() == 4)
if (locator.size() == 1)
{
int32_t const* l = reinterpret_cast<int32_t const*>(locator.data());
int32_t const* l = locator.data();
int32_t const sfield = l[0];
if (sfield == sfAccount.getCode())
{
return Bytes(accountID.begin(), accountID.end());
}
return Bytes(accountID_.begin(), accountID_.end());
}
uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2,
0x45, 0x9f, 0xa4, 0xa0, 0x34, 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92,
0xfc, 0xee, 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00};
@@ -219,17 +189,16 @@ public:
}
Expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const override
getLedgerObjNestedField(int32_t cacheIdx, FieldLocator const& locator) const override
{
if (locator.size() == 4)
if (locator.size() == 1)
{
int32_t const* l = reinterpret_cast<int32_t const*>(locator.data());
int32_t const* l = locator.data();
int32_t const sfield = l[0];
if (sfield == sfAccount.getCode())
{
return Bytes(accountID.begin(), accountID.end());
}
return Bytes(accountID_.begin(), accountID_.end());
}
uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2,
0x45, 0x9f, 0xa4, 0xa0, 0x34, 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92,
0xfc, 0xee, 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00};
@@ -255,19 +224,19 @@ public:
}
Expected<int32_t, HostFunctionError>
getTxNestedArrayLen(Slice const& locator) const override
getTxNestedArrayLen(FieldLocator const& locator) const override
{
return 32;
}
Expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const override
getCurrentLedgerObjNestedArrayLen(FieldLocator const& locator) const override
{
return 32;
}
Expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const override
getLedgerObjNestedArrayLen(int32_t cacheIdx, FieldLocator const& locator) const override
{
return 32;
}
@@ -287,7 +256,7 @@ public:
Expected<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data) const override
{
return env.current()->header().parentHash;
return env_.current()->header().parentHash;
}
Expected<Bytes, HostFunctionError>
@@ -352,9 +321,7 @@ public:
getNFT(AccountID const& account, uint256 const& nftId) const override
{
if (!account || !nftId)
{
return Unexpected(HostFunctionError::InvalidParams);
}
std::string s = "https://ripple.com";
return Bytes(s.begin(), s.end());
@@ -363,7 +330,7 @@ public:
Expected<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId) const override
{
return Bytes(accountID.begin(), accountID.end());
return Bytes(accountID_.begin(), accountID_.end());
}
Expected<std::uint32_t, HostFunctionError>
@@ -543,22 +510,21 @@ public:
}
};
struct TestHostFunctionsSink : public TestHostFunctions
class TestHostFunctionsSink : public TestHostFunctions
{
test::StreamSink sink;
void const* rt = nullptr;
test::StreamSink sink_;
public:
explicit TestHostFunctionsSink(test::jtx::Env& env, int cd = 0)
: TestHostFunctions(env, cd), sink(beast::Severity::Debug)
explicit TestHostFunctionsSink(test::jtx::Env& env)
: TestHostFunctions(env), sink_(beast::Severity::Debug)
{
j = beast::Journal(sink);
j_ = beast::Journal(sink_);
}
test::StreamSink&
getSink()
{
return sink;
return sink_;
}
};

View File

@@ -1,3 +1,8 @@
#ifdef _DEBUG
// #define DEBUG_OUTPUT 1
#endif
#include <test/app/TestHostFunctions.h>
#include <test/app/wasm_fixtures/fixtures.h>
#include <test/jtx/Env.h>
@@ -7,7 +12,8 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncWrapper.h> // IWYU pragma: keep
#include <xrpl/tx/wasm/ParamsHelper.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <xrpl/tx/wasm/WasmImportsHelper.h>
#include <xrpl/tx/wasm/WasmVM.h>
#include <boost/algorithm/hex.hpp>
@@ -16,21 +22,14 @@
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <limits>
#include <optional>
#include <source_location>
#include <string>
#include <utility>
#include <vector>
#ifdef _DEBUG
// #define DEBUG_OUTPUT 1
#endif
#include <test/app/TestHostFunctions.h>
#include <source_location>
namespace xrpl::test {
@@ -39,7 +38,7 @@ testGetDataIncrement();
using Add_proto = int32_t(int32_t, int32_t);
static wasm_trap_t*
add(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
add(HostFunctions&, wasm_val_vec_t const* params, wasm_val_vec_t* results)
{
int32_t const val1 = params->data[0].of.i32;
int32_t const val2 = params->data[1].of.i32;
@@ -218,7 +217,7 @@ struct Wasm_test : public beast::unit_test::Suite
HostFunctions hfs;
ImportVec imports;
WasmImpFunc<Add_proto>(imports, "func-add", reinterpret_cast<void*>(&add), &hfs);
WasmImpFunc<Add_proto>(imports, "func-add", add, hfs);
auto re = vm.run(wasm, hfs, 10'000'000, "addTwo", wasmParams(1234, 5678), imports);
@@ -287,7 +286,7 @@ struct Wasm_test : public beast::unit_test::Suite
Env env{*this};
TestLedgerDataProvider hfs(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs, 33);
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs, 33);
auto& engine = WasmEngine::instance();
auto re =
@@ -316,8 +315,8 @@ struct Wasm_test : public beast::unit_test::Suite
Env env{*this};
TestLedgerDataProvider hfs(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs, 33);
WASM_IMPORT_FUNC2(imports, getParentLedgerHash, "get_parent_ledger_hash", &hfs, 60);
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs, 33);
WASM_IMPORT_FUNC2(imports, getParentLedgerHash, "get_parent_ledger_hash", hfs, 60);
auto& engine = WasmEngine::instance();
// Test exp_func1() - should return 1
@@ -396,7 +395,7 @@ struct Wasm_test : public beast::unit_test::Suite
auto& engine = WasmEngine::instance();
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto imp = createWasmImport(hfs);
for (auto& i : imp)
i.second.second.gas = 0;
@@ -404,7 +403,7 @@ struct Wasm_test : public beast::unit_test::Suite
auto re = engine.run(
allHostFuncWasm, hfs, 1'000'000, escrowFunctionName, {}, imp, env.journal);
checkResult(re, 1, 27'080);
checkResult(re, 1, 27'617);
env.close();
}
@@ -420,13 +419,13 @@ struct Wasm_test : public beast::unit_test::Suite
auto& engine = WasmEngine::instance();
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto const imp = createWasmImport(hfs);
auto re = engine.run(
allHostFuncWasm, hfs, 1'000'000, escrowFunctionName, {}, imp, env.journal);
checkResult(re, 1, 70'340);
checkResult(re, 1, 70'877);
env.close();
}
@@ -437,7 +436,7 @@ struct Wasm_test : public beast::unit_test::Suite
auto& engine = WasmEngine::instance();
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto const imp = createWasmImport(hfs);
auto re =
@@ -463,14 +462,14 @@ struct Wasm_test : public beast::unit_test::Suite
using namespace test::jtx;
Env env{*this};
{
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName, {});
checkResult(re, 1, 70'340);
checkResult(re, 1, 70'877);
}
{
// Invalid gas limit (0) should be rejected (boundary condition)
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto re = runEscrowWasm(allHFWasm, hfs, -1, escrowFunctionName, {});
BEAST_EXPECT(!re.has_value());
BEAST_EXPECT(re.error() == temBAD_AMOUNT);
@@ -478,7 +477,7 @@ struct Wasm_test : public beast::unit_test::Suite
{
// Invalid gas limit (-1) should be rejected
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto re = runEscrowWasm(allHFWasm, hfs, 0, escrowFunctionName, {});
BEAST_EXPECT(!re.has_value());
BEAST_EXPECT(re.error() == temBAD_AMOUNT);
@@ -486,10 +485,10 @@ struct Wasm_test : public beast::unit_test::Suite
{
// max<int64_t>() gas
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto re = runEscrowWasm(
allHFWasm, hfs, std::numeric_limits<int64_t>::max(), escrowFunctionName, {});
checkResult(re, 1, 70'340);
checkResult(re, 1, 70'877);
}
{ // fail because trying to access nonexistent field
@@ -507,7 +506,7 @@ struct Wasm_test : public beast::unit_test::Suite
FieldNotFoundHostFunctions hfs(env);
auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName, {});
checkResult(re, -201, 28'965);
checkResult(re, -201, 29'502);
}
{ // fail because trying to allocate more than MAX_PAGES memory
@@ -525,7 +524,7 @@ struct Wasm_test : public beast::unit_test::Suite
OversizedFieldHostFunctions hfs(env);
auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName, {});
checkResult(re, -201, 28'965);
checkResult(re, -201, 29'502);
}
// This test use log output, so DEBUG_OUTPUT must be disabled.
@@ -562,7 +561,7 @@ struct Wasm_test : public beast::unit_test::Suite
{ // infinite loop
auto const infiniteLoopWasm = hexToBytes(kInfiniteLoopWasmHex);
std::string const funcName("loop");
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
// infinite loop should be caught and fail
auto const re = runEscrowWasm(infiniteLoopWasm, hfs, 1'000'000, funcName, {});
@@ -577,7 +576,7 @@ struct Wasm_test : public beast::unit_test::Suite
auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex);
TestLedgerDataProvider hfs(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn2", &hfs);
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn2", hfs);
auto& engine = WasmEngine::instance();
@@ -588,12 +587,12 @@ struct Wasm_test : public beast::unit_test::Suite
}
{
// bad import format
// HF unsync between import and VM
auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex);
TestLedgerDataProvider hfs(env);
TestLedgerDataProvider hfs2(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs);
imports["get_ledger_sqn"].first = nullptr;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs2);
auto& engine = WasmEngine::instance();
@@ -608,7 +607,7 @@ struct Wasm_test : public beast::unit_test::Suite
auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex);
TestLedgerDataProvider hfs(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs);
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs);
auto& engine = WasmEngine::instance();
auto re = engine.run(lgrSqnWasm, hfs, 1'000'000, "func1", {}, imports, env.journal);
@@ -630,7 +629,7 @@ struct Wasm_test : public beast::unit_test::Suite
{
auto const floatTestWasm = hexToBytes(kFloatTestsWasmHex);
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto re = runEscrowWasm(floatTestWasm, hfs, 200'000, funcName, {});
checkResult(re, 1, 134'938);
env.close();
@@ -639,9 +638,9 @@ struct Wasm_test : public beast::unit_test::Suite
{
auto const float0Wasm = hexToBytes(kFloat0Hex);
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto re = runEscrowWasm(float0Wasm, hfs, 100'000, funcName, {});
checkResult(re, 1, 4'309);
checkResult(re, 1, 2'819);
env.close();
}
}
@@ -656,7 +655,7 @@ struct Wasm_test : public beast::unit_test::Suite
Env env{*this};
auto const codecovWasm = hexToBytes(kCodecovTestsWasmHex);
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto const allowance = 220'169;
auto re = runEscrowWasm(codecovWasm, hfs, allowance, escrowFunctionName, {});
@@ -674,7 +673,7 @@ struct Wasm_test : public beast::unit_test::Suite
auto disabledFloatWasm = hexToBytes(kDisabledFloatHex);
std::string const funcName("finish");
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
{
// f32 set constant, opcode disabled exception
@@ -810,7 +809,7 @@ struct Wasm_test : public beast::unit_test::Suite
using namespace test::jtx;
Env env{*this};
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto imports = createWasmImport(hfs);
{ // Calls float_from_uint with bad alignment.
@@ -832,7 +831,7 @@ struct Wasm_test : public beast::unit_test::Suite
{
using namespace test::jtx;
Env env(*this);
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
testcase("Wasm invalid return type");
@@ -887,7 +886,7 @@ struct Wasm_test : public beast::unit_test::Suite
{
using namespace test::jtx;
Env env(*this);
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
testcase("Wasm invalid params");
@@ -999,7 +998,7 @@ struct Wasm_test : public beast::unit_test::Suite
using namespace test::jtx;
Env env{*this};
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto imports = createWasmImport(hfs);
// add 1k parameter (max that wasmi support)
@@ -1054,7 +1053,7 @@ struct Wasm_test : public beast::unit_test::Suite
Env env{*this};
auto& engine = WasmEngine::instance();
TestHostFunctions hfs(env, 0);
TestHostFunctions hfs(env);
auto imports = createWasmImport(hfs);
env.close();

View File

@@ -200,7 +200,7 @@ fn test_transaction_data_functions() -> i32 {
// Use get_tx_field() with appropriate parameters for all transaction field access.
// Test 2.2: get_tx_nested_field() - Nested field access with locator
let locator = [0x01, 0x00]; // Simple locator for first element
let locator = [0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8]; // Two int32s in little-endian: [1, 0]
let mut nested_buffer = [0u8; 32];
let nested_result = unsafe {
host::get_tx_nested_field(
@@ -314,7 +314,7 @@ fn test_current_ledger_object_functions() -> i32 {
}
// Test 3.2: get_current_ledger_obj_nested_field() - Nested field access
let locator = [0x01, 0x00]; // Simple locator
let locator = [0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8]; // Two int32s in little-endian: [1, 0]
let mut current_nested_buffer = [0u8; 32];
let current_nested_result = unsafe {
host::get_current_ledger_obj_nested_field(
@@ -426,7 +426,7 @@ fn test_any_ledger_object_functions() -> i32 {
}
// Test get_ledger_obj_nested_field with invalid slot
let locator = [0x01, 0x00];
let locator = [0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8]; // Two int32s in little-endian: [1, 0]
let nested_result = unsafe {
host::get_ledger_obj_nested_field(
1,
@@ -509,7 +509,7 @@ fn test_any_ledger_object_functions() -> i32 {
}
// Test 4.3: get_ledger_obj_nested_field() - Nested field from cached object
let locator = [0x01, 0x00];
let locator = [0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8]; // Two int32s in little-endian: [1, 0]
let mut cached_nested_buffer = [0u8; 32];
let cached_nested_result = unsafe {
host::get_ledger_obj_nested_field(

View File

@@ -45,13 +45,13 @@ extern std::string const kAllHostFunctionsWasmHex =
"65645f61727261795f6c656e000108686f73745f6c69620e6163636f756e745f6b65796c6574000208686f73745f6c"
"69620d74726163655f6163636f756e740002030c0b090a05050b05000101030005030100110619037f01418080c000"
"0b7f0041af99c0000b7f0041b099c0000b072e04066d656d6f727902000666696e697368001e0a5f5f646174615f65"
"6e6403010b5f5f686561705f6261736503020ac61d0b990101027f230041306b220124002000027f41818020200141"
"6e6403010b5f5f686561705f6261736503020a911e0b990101027f230041306b220124002000027f41818020200141"
"1c6a4114100022024114470440417f20022002417f4e1b210241010c010b200020012f001c3b0001200041036a2001"
"411e6a2d00003a0000200120012900233703082001200141286a29000037000d200128001f21022000410d6a200129"
"000d3700002000200129030837020841000b3a000020002002360204200141306a24000b460020012d000041014604"
"40418080c000410b20013402041001000b20002001290001370000200041106a200141116a28000036000020004108"
"6a200141096a2900003700000b1900200241214f0440000b20002002360204200020013602000b1900200241094f04"
"40000b20002002360204200020013602000bde1a01097f230041b0036b22002400418b80c000411b41014100410010"
"6a200141096a2900003700000b1900200241094f0440000b20002002360204200020013602000b1900200241214f04"
"40000b20002002360204200020013602000ba91b01097f230041b0036b22002400418b80c000411b41014100410010"
"021a41a680c000411941014100410010021a41e780c000412b41014100410010021a20004100360270024002400240"
"02400240024002400240200041f0006a220741041003220141004a0440419281c00041172000280270220141187420"
"014180fe03714108747220014108764180fe037120014118767272ad10011a200041003602900120004190016a2203"
@@ -60,144 +60,146 @@ extern std::string const kAllHostFunctionsWasmHex =
"044200370300200042003703b001200041b0016a22064120100522014120470d0241bc81c000411320064120410110"
"021a41cf81c000412041014100410010021a41dc82c000412e41014100410010021a200041a0016a41003602002000"
"4198016a420037030020004200370390014181802020034114100022014114470d03418a83c00041142003101f2000"
"42003703704188801820074108100022014108470d04419e83c0004117420810011a41b583c0004128200741084101"
"10021a2000410036024841848008200041c8006a22034104100022014104470d0541dd83c000411520034104410110"
"021a200041013b0034200242003703002005420037030020044200370300200042003703b0010240200041346a4102"
"200641201006220141004e044041f283c00041142001ad10011a200041286a20062001101c418684c000410d200028"
"0228200028022c410110021a0c010b419384c00041292001ac10011a0b41bc84c00041154183803c1007ac10011a41"
"d184c00041134189803c1007ac10011a0240200041346a41021008220141004e044041e484c00041142001ad10011a"
"0c010b41f884c000412d2001ac10011a0b41a585c000412341014100410010021a41de86c000413341014100410010"
"021a2000420037037041828018200041f0006a220141081009220341004c0d0620034108460440419187c000412b42"
"0810011a41bc87c000412f20014108410110021a0c080b41eb87c000412f2003ad10011a200041206a200041f0006a"
"2003101d419a88c000411720002802202000280224410110021a0c070b41bf82c000411d2001ac10011a419b7f2102"
"0c070b419a82c00041252001ac10011a419a7f21020c060b41ef81c000412b2001ac10011a41997f21020c050b41b4"
"86c000412a2001ac10011a41b77e21020c040b41f385c00041c1002001ac10011a41b67e21020c030b41c885c00041"
"2b2001ac10011a41b57e21020c020b41b188c00041c5002003ac10011a0b200041a0016a410036020020004198016a"
"4200370300200042003703900102404181802020004190016a220341141009220141004a044041f688c000411e2003"
"101f0c010b419489c00041332001ac10011a0b200041013b0048200041c8016a4200370300200041c0016a42003703"
"00200041b8016a4200370300200042003703b0010240200041c8006a4102200041b0016a22014120100a220341004e"
"044041c789c000411c2003ad10011a200041186a20012003101c41e389c00041152000280218200028021c41011002"
"1a0c010b41f889c00041392003ac10011a0b41b18ac00041244183803c100bac10011a0240200041c8006a4102100c"
"220141004e044041d58ac000411c2001ad10011a0c010b41f18ac000413d2001ac10011a0b41ae8bc0004128410141"
"00410010021a41d68bc000412f41014100410010021a200041b0016a2203101a200041f0006a22012003101b200041"
"a8016a4200370300200041a0016a420037030020004198016a42003703002000420037039001024002400240024002"
"40200120004190016a2203102022014120460440200341204100100d220441004a044041858cc00041232004ad1001"
"1a200042003703482004200041c8006a220141081021220341004c0d022003410846044041a88cc000412a42081001"
"1a41d28cc000412e20014108410110021a0c060b41808dc000412e2003ad10011a200041106a200041c8006a200310"
"1d41ae8dc000411620002802102000280214410110021a0c050b41e68fc000413c2004ac10011a200041c8016a4200"
"370300200041c0016a4200370300200041b8016a4200370300200042003703b0014101200041b0016a412010212201"
"4100480d020c030b41ba92c000412e2001ac10011a41ef7c21020c050b41c48dc000412b2003ac10011a0c020b41a2"
"90c00041c1002001ac10011a0b200041013b00484101200041c8006a200041b0016a10222201410048044041e390c0"
"0041352001ac10011a0b4101102322014100480440419891c00041322001ac10011a0b4101200041c8006a10242201"
"410048044041ca91c00041392001ac10011a0b418392c000413741014100410010021a0c010b200041013b00342000"
"41c8016a4200370300200041c0016a4200370300200041b8016a4200370300200042003703b0010240200420004134"
"6a200041b0016a22011022220341004e044041ef8dc000411b2003ad10011a200041086a20012003101c418a8ec000"
"41142000280208200028020c410110021a0c010b419e8ec00041312003ac10011a0b41cf8ec000412320041023ac10"
"011a02402004200041346a1024220141004e044041f28ec000411b2001ad10011a0c010b418d8fc00041352001ac10"
"011a0b41c28fc000412441014100410010021a0b41e892c000412f41014100410010021a200041b0016a2201101a20"
"0041346a22042001101b200041e0006a4200370300200041d8006a4200370300200041d0006a420037030020004200"
"370348024002400240024002402004200041c8006a2203102022014120460440419793c000410f2003412041011002"
"1a20004188016a420037030020004180016a4200370300200041f8006a420037030020004200370370024020044114"
"2004411441a693c0004109200041f0006a22014120100e220341004a0440200020012003101c41ae93c00041122000"
"2802002000280204410110021a0c010b41c093c000413c2003ac10011a0b200041a8016a22064200370300200041a0"
"016a2202420037030020004198016a22054200370300200042003703900120004180808cc07e360268200041346a22"
"034114200041e8006a410420004190016a22084120100f22014120470d0141fc93c000410e20084120410110021a20"
"0041c8016a4200370300200041c0016a4200370300200041b8016a4200370300200042003703b001200041808080d0"
"0236026c20034114200041ec006a4104200041b0016a22044120101022014120470d02418a94c000410e2004412041"
"0110021a419894c000412441014100410010021a419195c000412541014100410010021a20004188016a4200370300"
"20004180016a4200370300200041f8006a42003703002000420037037041b695c0004117200041f0006a2203412010"
"1122014120470d0341cd95c000410b41b695c0004117410110021a41d895c000411120034120410110021a2004101a"
"200041c8006a22072004101b2006420037030020024200370300200542003703002000420037039001024041002004"
"22026b410371220320026a220520024d0d0020030440200321010340200241003a0000200241016a2102200141016b"
"22010d000b0b200341016b4107490d000340200241003a0000200241076a41003a0000200241066a41003a00002002"
"41056a41003a0000200241046a41003a0000200241036a41003a0000200241026a41003a0000200241016a41003a00"
"00200241086a22022005470d000b0b200541800220036b2201417c716a220220054b04400340200541003602002005"
"41046a22052002490d000b0b024020022001410371220120026a22034f0d002001220504400340200241003a000020"
"0241016a2102200541016b22050d000b0b200141016b4107490d000340200241003a0000200241076a41003a000020"
"0241066a41003a0000200241056a41003a0000200241046a41003a0000200241036a41003a0000200241026a41003a"
"0000200241016a41003a0000200241086a22022003470d000b0b024020074114200841202004418002101222014100"
"4a044041e995c00041102001ad10011a20014181024f0d0641f995c000410920042001410110021a0c010b418296c0"
"00412e2001ac10011a0b41b096c000411241c296c00041074101100222014100480d0541c996c000411d2001ad1001"
"1a41e696c0004111422a1001410048044041ad97c000411a42a47b10011a41a47b21020c070b41f796c000411c4200"
"10011a41012102419397c000411a41014100410010021a41ff97c000412941014100410010021a41a898c000412810"
"132201412846044041d098c000412741a898c0004128410110021a41f798c000411e41014100410010021a41bf80c0"
"00412841014100410010021a0c070b419599c000411a2001ac10011a41c37a21020c060b41f494c000411d2001ac10"
"011a418b7c21020c050b41d894c000411c2001ac10011a41897c21020c040b41bc94c000411c2001ac10011a41887c"
"21020c030b41dd97c00041222001ac10011a41a77b21020c020b000b41c797c00041162001ac10011a41a57b21020b"
"200041b0036a240020020b0d00200020012002411410191a0b0c00200041142001412010180b0e0020004182801820"
"01200210140b0e002000200141022002412010150b0a0020004183803c10160b0a0020002001410210170b0bb91901"
"00418080c0000baf196572726f725f636f64653d3d3d3d20484f53542046554e4354494f4e532054455354203d3d3d"
"54657374696e6720323620686f73742066756e6374696f6e73535543434553533a20416c6c20686f73742066756e63"
"74696f6e20746573747320706173736564212d2d2d2043617465676f727920313a204c656467657220486561646572"
"2046756e6374696f6e73202d2d2d4c65646765722073657175656e6365206e756d6265723a506172656e74206c6564"
"6765722074696d653a506172656e74206c656467657220686173683a535543434553533a204c656467657220686561"
"6465722066756e6374696f6e734552524f523a206765745f706172656e745f6c65646765725f686173682077726f6e"
"67206c656e6774683a4552524f523a206765745f706172656e745f6c65646765725f74696d65206661696c65643a45"
"52524f523a206765745f6c65646765725f73716e206661696c65643a2d2d2d2043617465676f727920323a20547261"
"6e73616374696f6e20446174612046756e6374696f6e73202d2d2d5472616e73616374696f6e204163636f756e743a"
"5472616e73616374696f6e20466565206c656e6774683a5472616e73616374696f6e20466565202873657269616c69"
"7a65642058525020616d6f756e74293a5472616e73616374696f6e2053657175656e63653a4e657374656420666965"
"6c64206c656e6774683a4e6573746564206669656c643a494e464f3a206765745f74785f6e65737465645f6669656c"
"64206e6f74206170706c696361626c653a5369676e657273206172726179206c656e6774683a4d656d6f7320617272"
"6179206c656e6774683a4e6573746564206172726179206c656e6774683a494e464f3a206765745f74785f6e657374"
"65645f61727261795f6c656e206e6f74206170706c696361626c653a535543434553533a205472616e73616374696f"
"6e20646174612066756e6374696f6e734552524f523a206765745f74785f6669656c642853657175656e6365292077"
"726f6e67206c656e6774683a4552524f523a206765745f74785f6669656c6428466565292077726f6e67206c656e67"
"746820286578706563746564203820627974657320666f7220585250293a4552524f523a206765745f74785f666965"
"6c64284163636f756e74292077726f6e67206c656e6774683a2d2d2d2043617465676f727920333a2043757272656e"
"74204c6564676572204f626a6563742046756e6374696f6e73202d2d2d43757272656e74206f626a6563742062616c"
"616e6365206c656e677468202858525020616d6f756e74293a43757272656e74206f626a6563742062616c616e6365"
"202873657269616c697a65642058525020616d6f756e74293a43757272656e74206f626a6563742062616c616e6365"
"206c656e67746820286e6f6e2d58525020616d6f756e74293a43757272656e74206f626a6563742062616c616e6365"
"3a494e464f3a206765745f63757272656e745f6c65646765725f6f626a5f6669656c642842616c616e636529206661"
"696c656420286d6179206265206578706563746564293a43757272656e74206c6564676572206f626a656374206163"
"636f756e743a494e464f3a206765745f63757272656e745f6c65646765725f6f626a5f6669656c64284163636f756e"
"7429206661696c65643a43757272656e74206e6573746564206669656c64206c656e6774683a43757272656e74206e"
"6573746564206669656c643a494e464f3a206765745f63757272656e745f6c65646765725f6f626a5f6e6573746564"
"5f6669656c64206e6f74206170706c696361626c653a43757272656e74206f626a656374205369676e657273206172"
"726179206c656e6774683a43757272656e74206e6573746564206172726179206c656e6774683a494e464f3a206765"
"745f63757272656e745f6c65646765725f6f626a5f6e65737465645f61727261795f6c656e206e6f74206170706c69"
"6361626c653a535543434553533a2043757272656e74206c6564676572206f626a6563742066756e6374696f6e732d"
"2d2d2043617465676f727920343a20416e79204c6564676572204f626a6563742046756e6374696f6e73202d2d2d53"
"75636365737366756c6c7920636163686564206f626a65637420696e20736c6f743a436163686564206f626a656374"
"2062616c616e6365206c656e677468202858525020616d6f756e74293a436163686564206f626a6563742062616c61"
"6e6365202873657269616c697a65642058525020616d6f756e74293a436163686564206f626a6563742062616c616e"
"6365206c656e67746820286e6f6e2d58525020616d6f756e74293a436163686564206f626a6563742062616c616e63"
"653a494e464f3a206765745f6c65646765725f6f626a5f6669656c642842616c616e636529206661696c65643a4361"
"63686564206e6573746564206669656c64206c656e6774683a436163686564206e6573746564206669656c643a494e"
"464f3a206765745f6c65646765725f6f626a5f6e65737465645f6669656c64206e6f74206170706c696361626c653a"
"436163686564206f626a656374205369676e657273206172726179206c656e6774683a436163686564206e65737465"
"64206172726179206c656e6774683a494e464f3a206765745f6c65646765725f6f626a5f6e65737465645f61727261"
"795f6c656e206e6f74206170706c696361626c653a535543434553533a20416e79206c6564676572206f626a656374"
"2066756e6374696f6e73494e464f3a2063616368655f6c65646765725f6f626a206661696c65642028657870656374"
"656420776974682074657374206669787475726573293a494e464f3a206765745f6c65646765725f6f626a5f666965"
"6c64206661696c656420617320657870656374656420286e6f20636163686564206f626a656374293a494e464f3a20"
"6765745f6c65646765725f6f626a5f6e65737465645f6669656c64206661696c65642061732065787065637465643a"
"494e464f3a206765745f6c65646765725f6f626a5f61727261795f6c656e206661696c656420617320657870656374"
"65643a494e464f3a206765745f6c65646765725f6f626a5f6e65737465645f61727261795f6c656e206661696c6564"
"2061732065787065637465643a535543434553533a20416e79206c6564676572206f626a6563742066756e6374696f"
"6e732028696e7465726661636520746573746564294552524f523a206163636f756e745f6b65796c6574206661696c"
"656420666f722063616368696e6720746573743a2d2d2d2043617465676f727920353a204b65796c65742047656e65"
"726174696f6e2046756e6374696f6e73202d2d2d4163636f756e74206b65796c65743a546573745479706543726564"
"656e7469616c206b65796c65743a494e464f3a2063726564656e7469616c5f6b65796c6574206661696c6564202865"
"78706563746564202d20696e74657266616365206973737565293a457363726f77206b65796c65743a4f7261636c65"
"206b65796c65743a535543434553533a204b65796c65742067656e65726174696f6e2066756e6374696f6e73455252"
"4f523a206f7261636c655f6b65796c6574206661696c65643a4552524f523a20657363726f775f6b65796c65742066"
"61696c65643a4552524f523a206163636f756e745f6b65796c6574206661696c65643a2d2d2d2043617465676f7279"
"20363a205574696c6974792046756e6374696f6e73202d2d2d48656c6c6f2c205852504c205741534d20776f726c64"
"21496e70757420646174613a5348413531322068616c6620686173683a4e46542064617461206c656e6774683a4e46"
"5420646174613a494e464f3a206765745f6e6674206661696c656420286578706563746564202d206e6f2073756368"
"204e4654293a54657374207472616365206d6573736167657061796c6f616454726163652066756e6374696f6e2062"
"79746573207772697474656e3a54657374206e756d62657220747261636554726163655f6e756d2066756e6374696f"
"6e20737563636565646564535543434553533a205574696c6974792066756e6374696f6e734552524f523a20747261"
"63655f6e756d2829206661696c65643a4552524f523a2074726163652829206661696c65643a4552524f523a20636f"
"6d707574655f7368613531325f68616c66206661696c65643a2d2d2d2043617465676f727920373a20446174612055"
"70646174652046756e6374696f6e73202d2d2d55706461746564206c656467657220656e7472792064617461206672"
"6f6d205741534d20746573745375636365737366756c6c792075706461746564206c656467657220656e7472792077"
"6974683a535543434553533a2044617461207570646174652066756e6374696f6e734552524f523a20757064617465"
"5f64617461206661696c65643a004d0970726f64756365727302086c616e6775616765010452757374000c70726f63"
"65737365642d6279010572757374631d312e38372e30202831373036376539616320323032352d30352d303929002c"
"0f7461726765745f6665617475726573022b0f6d757461626c652d676c6f62616c732b087369676e2d657874";
"420037034841888018200041c8006a22034108100022014108470d04419e83c0004117420810011a41b583c0004128"
"20034108410110021a2000410036023041848008200041306a22034104100022014104470d0541dd83c00041152003"
"4104410110021a200041f4006a410036000020004100360071200041013a0070200242003703002005420037030020"
"044200370300200042003703b001024020074108200641201006220141004e044041f283c00041142001ad10011a20"
"0041286a20062001101d418684c000410d2000280228200028022c410110021a0c010b419384c00041292001ac1001"
"1a0b41bc84c00041154183803c1007ac10011a41d184c00041134189803c1007ac10011a0240200041f0006a410810"
"08220141004e044041e484c00041142001ad10011a0c010b41f884c000412d2001ac10011a0b41a585c00041234101"
"4100410010021a41de86c000413341014100410010021a2000420037034841828018200041c8006a22014108100922"
"0341004c0d0620034108460440419187c000412b420810011a41bc87c000412f20014108410110021a0c080b41eb87"
"c000412f2003ad10011a200041206a200041c8006a2003101c419a88c000411720002802202000280224410110021a"
"0c070b41bf82c000411d2001ac10011a419b7f21020c070b419a82c00041252001ac10011a419a7f21020c060b41ef"
"81c000412b2001ac10011a41997f21020c050b41b486c000412a2001ac10011a41b77e21020c040b41f385c00041c1"
"002001ac10011a41b67e21020c030b41c885c000412b2001ac10011a41b57e21020c020b41b188c00041c5002003ac"
"10011a0b200041a0016a410036020020004198016a4200370300200042003703900102404181802020004190016a22"
"0341141009220141004a044041f688c000411e2003101f0c010b419489c00041332001ac10011a0b200041f4006a41"
"0036000020004100360071200041013a0070200041c8016a4200370300200041c0016a4200370300200041b8016a42"
"00370300200042003703b0010240200041f0006a4108200041b0016a22014120100a220341004e044041c789c00041"
"1c2003ad10011a200041186a20012003101d41e389c00041152000280218200028021c410110021a0c010b41f889c0"
"0041392003ac10011a0b41b18ac00041244183803c100bac10011a0240200041f0006a4108100c220141004e044041"
"d58ac000411c2001ad10011a0c010b41f18ac000413d2001ac10011a0b41ae8bc000412841014100410010021a41d6"
"8bc000412f41014100410010021a200041b0016a2203101a200041f0006a22012003101b200041a8016a4200370300"
"200041a0016a420037030020004198016a420037030020004200370390010240024002400240024020012000419001"
"6a2203102022014120460440200341204100100d220441004a044041858cc00041232004ad10011a20004200370330"
"2004200041306a220141081021220341004c0d022003410846044041a88cc000412a420810011a41d28cc000412e20"
"014108410110021a0c060b41808dc000412e2003ad10011a200041106a200041306a2003101c41ae8dc00041162000"
"2802102000280214410110021a0c050b41e68fc000413c2004ac10011a200041c8016a4200370300200041c0016a42"
"00370300200041b8016a4200370300200042003703b0014101200041b0016a4120102122014100480d020c030b41ba"
"92c000412e2001ac10011a41ef7c21020c050b41c48dc000412b2003ac10011a0c020b41a290c00041c1002001ac10"
"011a0b200041cc006a410036000020004100360049200041013a00484101200041c8006a200041b0016a1022220141"
"0048044041e390c00041352001ac10011a0b4101102322014100480440419891c00041322001ac10011a0b41012000"
"41c8006a10242201410048044041ca91c00041392001ac10011a0b418392c000413741014100410010021a0c010b20"
"0041cc006a410036000020004100360049200041013a0048200041c8016a4200370300200041c0016a420037030020"
"0041b8016a4200370300200042003703b00102402004200041c8006a200041b0016a22011022220341004e044041ef"
"8dc000411b2003ad10011a200041086a20012003101d418a8ec00041142000280208200028020c410110021a0c010b"
"419e8ec00041312003ac10011a0b41cf8ec000412320041023ac10011a02402004200041c8006a1024220141004e04"
"4041f28ec000411b2001ad10011a0c010b418d8fc00041352001ac10011a0b41c28fc000412441014100410010021a"
"0b41e892c000412f41014100410010021a200041b0016a2201101a200041306a22042001101b200041e0006a420037"
"0300200041d8006a4200370300200041d0006a420037030020004200370348024002400240024002402004200041c8"
"006a2203102022014120460440419793c000410f20034120410110021a20004188016a420037030020004180016a42"
"00370300200041f8006a4200370300200042003703700240200441142004411441a693c0004109200041f0006a2201"
"4120100e220341004a0440200020012003101d41ae93c000411220002802002000280204410110021a0c010b41c093"
"c000413c2003ac10011a0b200041a8016a22064200370300200041a0016a2202420037030020004198016a22054200"
"370300200042003703900120004180808cc07e360268200041306a22034114200041e8006a410420004190016a2208"
"4120100f22014120470d0141fc93c000410e20084120410110021a200041c8016a4200370300200041c0016a420037"
"0300200041b8016a4200370300200042003703b001200041808080d00236026c20034114200041ec006a4104200041"
"b0016a22044120101022014120470d02418a94c000410e20044120410110021a419894c00041244101410041001002"
"1a419195c000412541014100410010021a20004188016a420037030020004180016a4200370300200041f8006a4200"
"3703002000420037037041b695c0004117200041f0006a22034120101122014120470d0341cd95c000410b41b695c0"
"004117410110021a41d895c000411120034120410110021a2004101a200041c8006a22072004101b20064200370300"
"2002420037030020054200370300200042003703900102404100200422026b410371220320026a220520024d0d0020"
"030440200321010340200241003a0000200241016a2102200141016b22010d000b0b200341016b4107490d00034020"
"0241003a0000200241076a41003a0000200241066a41003a0000200241056a41003a0000200241046a41003a000020"
"0241036a41003a0000200241026a41003a0000200241016a41003a0000200241086a22022005470d000b0b20054180"
"0220036b2201417c716a220220054b0440034020054100360200200541046a22052002490d000b0b02402002200141"
"0371220120026a22034f0d002001220504400340200241003a0000200241016a2102200541016b22050d000b0b2001"
"41016b4107490d000340200241003a0000200241076a41003a0000200241066a41003a0000200241056a41003a0000"
"200241046a41003a0000200241036a41003a0000200241026a41003a0000200241016a41003a0000200241086a2202"
"2003470d000b0b0240200741142008412020044180021012220141004a044041e995c00041102001ad10011a200141"
"81024f0d0641f995c000410920042001410110021a0c010b418296c000412e2001ac10011a0b41b096c000411241c2"
"96c00041074101100222014100480d0541c996c000411d2001ad10011a41e696c0004111422a1001410048044041ad"
"97c000411a42a47b10011a41a47b21020c070b41f796c000411c420010011a41012102419397c000411a4101410041"
"0010021a41ff97c000412941014100410010021a41a898c000412810132201412846044041d098c000412741a898c0"
"004128410110021a41f798c000411e41014100410010021a41bf80c000412841014100410010021a0c070b419599c0"
"00411a2001ac10011a41c37a21020c060b41f494c000411d2001ac10011a418b7c21020c050b41d894c000411c2001"
"ac10011a41897c21020c040b41bc94c000411c2001ac10011a41887c21020c030b41dd97c00041222001ac10011a41"
"a77b21020c020b000b41c797c00041162001ac10011a41a57b21020b200041b0036a240020020b0d00200020012002"
"411410191a0b0c00200041142001412010180b0e002000418280182001200210140b0e002000200141082002412010"
"150b0a0020004183803c10160b0a0020002001410810170b0bb9190100418080c0000baf196572726f725f636f6465"
"3d3d3d3d20484f53542046554e4354494f4e532054455354203d3d3d54657374696e6720323620686f73742066756e"
"6374696f6e73535543434553533a20416c6c20686f73742066756e6374696f6e20746573747320706173736564212d"
"2d2d2043617465676f727920313a204c6564676572204865616465722046756e6374696f6e73202d2d2d4c65646765"
"722073657175656e6365206e756d6265723a506172656e74206c65646765722074696d653a506172656e74206c6564"
"67657220686173683a535543434553533a204c6564676572206865616465722066756e6374696f6e734552524f523a"
"206765745f706172656e745f6c65646765725f686173682077726f6e67206c656e6774683a4552524f523a20676574"
"5f706172656e745f6c65646765725f74696d65206661696c65643a4552524f523a206765745f6c65646765725f7371"
"6e206661696c65643a2d2d2d2043617465676f727920323a205472616e73616374696f6e20446174612046756e6374"
"696f6e73202d2d2d5472616e73616374696f6e204163636f756e743a5472616e73616374696f6e20466565206c656e"
"6774683a5472616e73616374696f6e20466565202873657269616c697a65642058525020616d6f756e74293a547261"
"6e73616374696f6e2053657175656e63653a4e6573746564206669656c64206c656e6774683a4e6573746564206669"
"656c643a494e464f3a206765745f74785f6e65737465645f6669656c64206e6f74206170706c696361626c653a5369"
"676e657273206172726179206c656e6774683a4d656d6f73206172726179206c656e6774683a4e6573746564206172"
"726179206c656e6774683a494e464f3a206765745f74785f6e65737465645f61727261795f6c656e206e6f74206170"
"706c696361626c653a535543434553533a205472616e73616374696f6e20646174612066756e6374696f6e73455252"
"4f523a206765745f74785f6669656c642853657175656e6365292077726f6e67206c656e6774683a4552524f523a20"
"6765745f74785f6669656c6428466565292077726f6e67206c656e6774682028657870656374656420382062797465"
"7320666f7220585250293a4552524f523a206765745f74785f6669656c64284163636f756e74292077726f6e67206c"
"656e6774683a2d2d2d2043617465676f727920333a2043757272656e74204c6564676572204f626a6563742046756e"
"6374696f6e73202d2d2d43757272656e74206f626a6563742062616c616e6365206c656e677468202858525020616d"
"6f756e74293a43757272656e74206f626a6563742062616c616e6365202873657269616c697a65642058525020616d"
"6f756e74293a43757272656e74206f626a6563742062616c616e6365206c656e67746820286e6f6e2d58525020616d"
"6f756e74293a43757272656e74206f626a6563742062616c616e63653a494e464f3a206765745f63757272656e745f"
"6c65646765725f6f626a5f6669656c642842616c616e636529206661696c656420286d617920626520657870656374"
"6564293a43757272656e74206c6564676572206f626a656374206163636f756e743a494e464f3a206765745f637572"
"72656e745f6c65646765725f6f626a5f6669656c64284163636f756e7429206661696c65643a43757272656e74206e"
"6573746564206669656c64206c656e6774683a43757272656e74206e6573746564206669656c643a494e464f3a2067"
"65745f63757272656e745f6c65646765725f6f626a5f6e65737465645f6669656c64206e6f74206170706c69636162"
"6c653a43757272656e74206f626a656374205369676e657273206172726179206c656e6774683a43757272656e7420"
"6e6573746564206172726179206c656e6774683a494e464f3a206765745f63757272656e745f6c65646765725f6f62"
"6a5f6e65737465645f61727261795f6c656e206e6f74206170706c696361626c653a535543434553533a2043757272"
"656e74206c6564676572206f626a6563742066756e6374696f6e732d2d2d2043617465676f727920343a20416e7920"
"4c6564676572204f626a6563742046756e6374696f6e73202d2d2d5375636365737366756c6c792063616368656420"
"6f626a65637420696e20736c6f743a436163686564206f626a6563742062616c616e6365206c656e67746820285852"
"5020616d6f756e74293a436163686564206f626a6563742062616c616e6365202873657269616c697a656420585250"
"20616d6f756e74293a436163686564206f626a6563742062616c616e6365206c656e67746820286e6f6e2d58525020"
"616d6f756e74293a436163686564206f626a6563742062616c616e63653a494e464f3a206765745f6c65646765725f"
"6f626a5f6669656c642842616c616e636529206661696c65643a436163686564206e6573746564206669656c64206c"
"656e6774683a436163686564206e6573746564206669656c643a494e464f3a206765745f6c65646765725f6f626a5f"
"6e65737465645f6669656c64206e6f74206170706c696361626c653a436163686564206f626a656374205369676e65"
"7273206172726179206c656e6774683a436163686564206e6573746564206172726179206c656e6774683a494e464f"
"3a206765745f6c65646765725f6f626a5f6e65737465645f61727261795f6c656e206e6f74206170706c696361626c"
"653a535543434553533a20416e79206c6564676572206f626a6563742066756e6374696f6e73494e464f3a20636163"
"68655f6c65646765725f6f626a206661696c6564202865787065637465642077697468207465737420666978747572"
"6573293a494e464f3a206765745f6c65646765725f6f626a5f6669656c64206661696c656420617320657870656374"
"656420286e6f20636163686564206f626a656374293a494e464f3a206765745f6c65646765725f6f626a5f6e657374"
"65645f6669656c64206661696c65642061732065787065637465643a494e464f3a206765745f6c65646765725f6f62"
"6a5f61727261795f6c656e206661696c65642061732065787065637465643a494e464f3a206765745f6c6564676572"
"5f6f626a5f6e65737465645f61727261795f6c656e206661696c65642061732065787065637465643a535543434553"
"533a20416e79206c6564676572206f626a6563742066756e6374696f6e732028696e74657266616365207465737465"
"64294552524f523a206163636f756e745f6b65796c6574206661696c656420666f722063616368696e672074657374"
"3a2d2d2d2043617465676f727920353a204b65796c65742047656e65726174696f6e2046756e6374696f6e73202d2d"
"2d4163636f756e74206b65796c65743a546573745479706543726564656e7469616c206b65796c65743a494e464f3a"
"2063726564656e7469616c5f6b65796c6574206661696c656420286578706563746564202d20696e74657266616365"
"206973737565293a457363726f77206b65796c65743a4f7261636c65206b65796c65743a535543434553533a204b65"
"796c65742067656e65726174696f6e2066756e6374696f6e734552524f523a206f7261636c655f6b65796c65742066"
"61696c65643a4552524f523a20657363726f775f6b65796c6574206661696c65643a4552524f523a206163636f756e"
"745f6b65796c6574206661696c65643a2d2d2d2043617465676f727920363a205574696c6974792046756e6374696f"
"6e73202d2d2d48656c6c6f2c205852504c205741534d20776f726c6421496e70757420646174613a53484135313220"
"68616c6620686173683a4e46542064617461206c656e6774683a4e465420646174613a494e464f3a206765745f6e66"
"74206661696c656420286578706563746564202d206e6f2073756368204e4654293a54657374207472616365206d65"
"73736167657061796c6f616454726163652066756e6374696f6e206279746573207772697474656e3a54657374206e"
"756d62657220747261636554726163655f6e756d2066756e6374696f6e20737563636565646564535543434553533a"
"205574696c6974792066756e6374696f6e734552524f523a2074726163655f6e756d2829206661696c65643a455252"
"4f523a2074726163652829206661696c65643a4552524f523a20636f6d707574655f7368613531325f68616c662066"
"61696c65643a2d2d2d2043617465676f727920373a2044617461205570646174652046756e6374696f6e73202d2d2d"
"55706461746564206c656467657220656e74727920646174612066726f6d205741534d207465737453756363657373"
"66756c6c792075706461746564206c656467657220656e74727920776974683a535543434553533a20446174612075"
"70646174652066756e6374696f6e734552524f523a207570646174655f64617461206661696c65643a004d0970726f"
"64756365727302086c616e6775616765010452757374000c70726f6365737365642d6279010572757374631d312e38"
"392e30202832393438333838336520323032352d30382d303429002c0f7461726765745f6665617475726573022b0f"
"6d757461626c652d676c6f62616c732b087369676e2d657874";
extern std::string const kDeepRecursionHex =
"0061736d010000000105016000017f030201000608017f0141c0843d0b070a010666696e69736800000a1601140023"
@@ -1008,33 +1010,18 @@ extern std::string const kFloat0Hex =
"0061736d0100000001290560057f7f7f7f7f017f60047e7f7f7f017f60077f7f7f7f7f7f7f017f60047f7f7f7f017f"
"6000017f025f0408686f73745f6c6962057472616365000008686f73745f6c69620e666c6f61745f66726f6d5f696e"
"74000108686f73745f6c69620e666c6f61745f7375627472616374000208686f73745f6c69620d666c6f61745f636f"
"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";
"6d7061726500030302010405030100110619037f01418080c0000b7f0041e980c0000b7f0041f080c0000b072e0406"
"6d656d6f727902000666696e69736800040a5f5f646174615f656e6403010b5f5f686561705f6261736503020ad201"
"01cf0101027f230041206b22002400418080c000411541014100410010001a200041086a4100360200200042003703"
"00200041186a41003602002000420037031002400240420a2000410c41001001410c4604402000410c2000410c2000"
"41106a2201410c41001002410c470d012001410c419580c000410c100345044041a180c000411a4101410041001000"
"1a0c030b41bb80c000411941014100410010001a0c020b41d480c000411541014100410010001a0c010b41d480c000"
"411541014100410010001a0b200041206a240041010b0b720100418080c0000b690a24242420746573745f666c6f61"
"745f30202424240000000000000000800000002020464c4f41545f5a45524f20636f6d706172653a20676f6f642020"
"464c4f41545f5a45524f20636f6d706172653a206261642020666c6f61742031302d31303a206661696c6564004d09"
"70726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d6279010572757374631d"
"312e38392e30202832393438333838336520323032352d30382d303429002c0f7461726765745f6665617475726573"
"022b0f6d757461626c652d676c6f62616c732b087369676e2d657874";
extern std::string const kDisabledFloatHex =
"0061736d010000000108026000006000017f03030200010503010002063e0a7f004180080b7f004180080b7f004180"

View File

@@ -39,13 +39,6 @@ pub extern "C" fn finish() -> i32 {
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");