Compare commits

...

5 Commits

Author SHA1 Message Date
Mayukha Vadari
f60a9f1c64 Revert "remove wasm engine tests"
This reverts commit 5ee903befc.
2026-06-09 17:10:13 -04:00
Mayukha Vadari
5ee903befc remove wasm engine tests 2026-06-09 17:09:45 -04:00
Olek
d582ae7990 HF one entry point (#7393)
Add one entry point for all HF for centralized exceptions handling, gas calculation and general checks.
Add exception handling for HF
Add FieldLocator object
Switch pointers to references for HF and runtime
Max size for parameters and sfData field is 1 kb now
Fix Allhf unittest, to provide correct locator
2026-06-03 21:53:12 -04:00
Olek
0dbe51c740 Cleanup and some refactoring (#7383) 2026-06-02 21:15:58 -04:00
Olek
63fff4b518 Fix HF tests (#7365) 2026-05-29 17:49:03 -04:00
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");