Compare commits

...

3 Commits

Author SHA1 Message Date
Oleksandr
6e410d9718 Fix clang format 2026-02-12 14:39:31 -05:00
Oleksandr
cb1bf20ab4 Check that HFS object is always new 2026-02-12 13:12:15 -05:00
Oleksandr
10864f1959 Remove ability to re-use wasm module 2026-02-12 12:55:44 -05:00
16 changed files with 559 additions and 516 deletions

View File

@@ -36,7 +36,7 @@ public:
}
Expected<std::uint32_t, HostFunctionError>
getLedgerSqn() override
getLedgerSqn() const override
{
return env_.current()->seq();
}
@@ -71,37 +71,37 @@ public:
}
Expected<std::uint32_t, HostFunctionError>
getLedgerSqn() override
getLedgerSqn() const override
{
return 12345;
}
Expected<std::uint32_t, HostFunctionError>
getParentLedgerTime() override
getParentLedgerTime() const override
{
return 67890;
}
Expected<Hash, HostFunctionError>
getParentLedgerHash() override
getParentLedgerHash() const override
{
return env_.current()->header().parentHash;
}
Expected<std::uint32_t, HostFunctionError>
getBaseFee() override
getBaseFee() const override
{
return 10;
}
Expected<int32_t, HostFunctionError>
isAmendmentEnabled(uint256 const& amendmentId) override
isAmendmentEnabled(uint256 const& amendmentId) const override
{
return 1;
}
Expected<int32_t, HostFunctionError>
isAmendmentEnabled(std::string_view const& amendmentName) override
isAmendmentEnabled(std::string_view const& amendmentName) const override
{
return 1;
}
@@ -113,7 +113,7 @@ public:
}
Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) override
getTxField(SField const& fname) const override
{
if (fname == sfAccount)
return Bytes(accountID_.begin(), accountID_.end());
@@ -137,7 +137,7 @@ public:
}
Expected<Bytes, HostFunctionError>
getCurrentLedgerObjField(SField const& fname) override
getCurrentLedgerObjField(SField const& fname) const override
{
auto const& sn = fname.getName();
if (sn == "Destination" || sn == "Account")
@@ -155,7 +155,7 @@ public:
}
Expected<Bytes, HostFunctionError>
getLedgerObjField(int32_t cacheIdx, SField const& fname) override
getLedgerObjField(int32_t cacheIdx, SField const& fname) const override
{
if (fname == sfBalance)
{
@@ -171,7 +171,7 @@ public:
}
Expected<Bytes, HostFunctionError>
getTxNestedField(Slice const& locator) override
getTxNestedField(Slice const& locator) const override
{
if (locator.size() == 4)
{
@@ -189,7 +189,7 @@ public:
}
Expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(Slice const& locator) override
getCurrentLedgerObjNestedField(Slice const& locator) const override
{
if (locator.size() == 4)
{
@@ -207,7 +207,7 @@ public:
}
Expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const override
{
if (locator.size() == 4)
{
@@ -225,37 +225,37 @@ public:
}
Expected<int32_t, HostFunctionError>
getTxArrayLen(SField const& fname) override
getTxArrayLen(SField const& fname) const override
{
return 32;
}
Expected<int32_t, HostFunctionError>
getCurrentLedgerObjArrayLen(SField const& fname) override
getCurrentLedgerObjArrayLen(SField const& fname) const override
{
return 32;
}
Expected<int32_t, HostFunctionError>
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const override
{
return 32;
}
Expected<int32_t, HostFunctionError>
getTxNestedArrayLen(Slice const& locator) override
getTxNestedArrayLen(Slice const& locator) const override
{
return 32;
}
Expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(Slice const& locator) override
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const override
{
return 32;
}
Expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const override
{
return 32;
}
@@ -267,19 +267,19 @@ public:
}
Expected<int32_t, HostFunctionError>
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) override
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const override
{
return 1;
}
Expected<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data) override
computeSha512HalfHash(Slice const& data) const override
{
return env_.current()->header().parentHash;
}
Expected<Bytes, HostFunctionError>
accountKeylet(AccountID const& account) override
accountKeylet(AccountID const& account) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -288,7 +288,7 @@ public:
}
Expected<Bytes, HostFunctionError>
ammKeylet(Asset const& issue1, Asset const& issue2) override
ammKeylet(Asset const& issue1, Asset const& issue2) const override
{
if (issue1 == issue2)
return Unexpected(HostFunctionError::INVALID_PARAMS);
@@ -299,7 +299,7 @@ public:
}
Expected<Bytes, HostFunctionError>
checkKeylet(AccountID const& account, std::uint32_t seq) override
checkKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -308,7 +308,7 @@ public:
}
Expected<Bytes, HostFunctionError>
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) override
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) const override
{
if (!subject || !issuer || credentialType.empty() || credentialType.size() > maxCredentialTypeLength)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -317,7 +317,7 @@ public:
}
Expected<Bytes, HostFunctionError>
escrowKeylet(AccountID const& account, std::uint32_t seq) override
escrowKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -326,7 +326,7 @@ public:
}
Expected<Bytes, HostFunctionError>
oracleKeylet(AccountID const& account, std::uint32_t documentId) override
oracleKeylet(AccountID const& account, std::uint32_t documentId) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -335,7 +335,7 @@ public:
}
Expected<Bytes, HostFunctionError>
getNFT(AccountID const& account, uint256 const& nftId) override
getNFT(AccountID const& account, uint256 const& nftId) const override
{
if (!account || !nftId)
{
@@ -347,38 +347,38 @@ public:
}
Expected<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId) override
getNFTIssuer(uint256 const& nftId) const override
{
return Bytes(accountID_.begin(), accountID_.end());
}
Expected<std::uint32_t, HostFunctionError>
getNFTTaxon(uint256 const& nftId) override
getNFTTaxon(uint256 const& nftId) const override
{
return 4;
}
Expected<int32_t, HostFunctionError>
getNFTFlags(uint256 const& nftId) override
getNFTFlags(uint256 const& nftId) const override
{
return 8;
}
Expected<int32_t, HostFunctionError>
getNFTTransferFee(uint256 const& nftId) override
getNFTTransferFee(uint256 const& nftId) const override
{
return 10;
}
Expected<std::uint32_t, HostFunctionError>
getNFTSerial(uint256 const& nftId) override
getNFTSerial(uint256 const& nftId) const override
{
return 4;
}
template <typename F>
void
log(std::string_view const& msg, F&& dataFn)
log(std::string_view const& msg, F&& dataFn) const
{
#ifdef DEBUG_OUTPUT
auto& j = std::cerr;
@@ -395,7 +395,7 @@ public:
}
Expected<int32_t, HostFunctionError>
trace(std::string_view const& msg, Slice const& data, bool asHex) override
trace(std::string_view const& msg, Slice const& data, bool asHex) const override
{
if (!asHex)
{
@@ -415,95 +415,95 @@ public:
}
Expected<int32_t, HostFunctionError>
traceNum(std::string_view const& msg, int64_t data) override
traceNum(std::string_view const& msg, int64_t data) const override
{
log(msg, [data] { return data; });
return 0;
}
Expected<int32_t, HostFunctionError>
traceAccount(std::string_view const& msg, AccountID const& account) override
traceAccount(std::string_view const& msg, AccountID const& account) const override
{
log(msg, [&account] { return toBase58(account); });
return 0;
}
Expected<int32_t, HostFunctionError>
traceFloat(std::string_view const& msg, Slice const& data) override
traceFloat(std::string_view const& msg, Slice const& data) const override
{
log(msg, [&data] { return wasm_float::floatToString(data); });
return 0;
}
Expected<int32_t, HostFunctionError>
traceAmount(std::string_view const& msg, STAmount const& amount) override
traceAmount(std::string_view const& msg, STAmount const& amount) const override
{
log(msg, [&amount] { return amount.getFullText(); });
return 0;
}
Expected<Bytes, HostFunctionError>
floatFromInt(int64_t x, int32_t mode) override
floatFromInt(int64_t x, int32_t mode) const override
{
return wasm_float::floatFromIntImpl(x, mode);
}
Expected<Bytes, HostFunctionError>
floatFromUint(uint64_t x, int32_t mode) override
floatFromUint(uint64_t x, int32_t mode) const override
{
return wasm_float::floatFromUintImpl(x, mode);
}
Expected<Bytes, HostFunctionError>
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) override
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const override
{
return wasm_float::floatSetImpl(mantissa, exponent, mode);
}
Expected<int32_t, HostFunctionError>
floatCompare(Slice const& x, Slice const& y) override
floatCompare(Slice const& x, Slice const& y) const override
{
return wasm_float::floatCompareImpl(x, y);
}
Expected<Bytes, HostFunctionError>
floatAdd(Slice const& x, Slice const& y, int32_t mode) override
floatAdd(Slice const& x, Slice const& y, int32_t mode) const override
{
return wasm_float::floatAddImpl(x, y, mode);
}
Expected<Bytes, HostFunctionError>
floatSubtract(Slice const& x, Slice const& y, int32_t mode) override
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const override
{
return wasm_float::floatSubtractImpl(x, y, mode);
}
Expected<Bytes, HostFunctionError>
floatMultiply(Slice const& x, Slice const& y, int32_t mode) override
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const override
{
return wasm_float::floatMultiplyImpl(x, y, mode);
}
Expected<Bytes, HostFunctionError>
floatDivide(Slice const& x, Slice const& y, int32_t mode) override
floatDivide(Slice const& x, Slice const& y, int32_t mode) const override
{
return wasm_float::floatDivideImpl(x, y, mode);
}
Expected<Bytes, HostFunctionError>
floatRoot(Slice const& x, int32_t n, int32_t mode) override
floatRoot(Slice const& x, int32_t n, int32_t mode) const override
{
return wasm_float::floatRootImpl(x, n, mode);
}
Expected<Bytes, HostFunctionError>
floatPower(Slice const& x, int32_t n, int32_t mode) override
floatPower(Slice const& x, int32_t n, int32_t mode) const override
{
return wasm_float::floatPowerImpl(x, n, mode);
}
Expected<Bytes, HostFunctionError>
floatLog(Slice const& x, int32_t mode) override
floatLog(Slice const& x, int32_t mode) const override
{
return wasm_float::floatLogImpl(x, mode);
}
@@ -528,14 +528,14 @@ public:
}
};
#ifdef WASM_PERF_TESTS
struct PerfHostFunctions : public TestHostFunctions
{
Keylet leKey;
std::shared_ptr<SLE const> currentLedgerObj = nullptr;
bool isLedgerObjCached = false;
Keylet leKey_;
mutable std::optional<std::shared_ptr<SLE const>> currentLedgerObj_;
static int constexpr MAX_CACHE = 256;
std::array<std::shared_ptr<SLE const>, MAX_CACHE> cache;
mutable std::array<std::shared_ptr<SLE const>, MAX_CACHE> cache_;
// std::optional<Bytes> data_; // deferred data update, not used in
// performance
std::shared_ptr<STTx const> tx_;
@@ -543,42 +543,42 @@ struct PerfHostFunctions : public TestHostFunctions
void const* rt_ = nullptr;
PerfHostFunctions(test::jtx::Env& env, Keylet const& k, std::shared_ptr<STTx const>&& tx)
: TestHostFunctions(env), leKey(k), tx_(std::move(tx))
: TestHostFunctions(env), leKey_(k), tx_(std::move(tx))
{
}
Expected<std::uint32_t, HostFunctionError>
getLedgerSqn() override
getLedgerSqn() const override
{
return env_.current()->seq();
}
Expected<std::uint32_t, HostFunctionError>
getParentLedgerTime() override
getParentLedgerTime() const override
{
return env_.current()->parentCloseTime().time_since_epoch().count();
}
Expected<Hash, HostFunctionError>
getParentLedgerHash() override
getParentLedgerHash() const override
{
return env_.current()->header().parentHash;
}
Expected<std::uint32_t, HostFunctionError>
getBaseFee() override
getBaseFee() const override
{
return env_.current()->fees().base.drops();
}
Expected<int32_t, HostFunctionError>
isAmendmentEnabled(uint256 const& amendmentId) override
isAmendmentEnabled(uint256 const& amendmentId) const override
{
return env_.current()->rules().enabled(amendmentId);
}
Expected<int32_t, HostFunctionError>
isAmendmentEnabled(std::string_view const& amendmentName) override
isAmendmentEnabled(std::string_view const& amendmentName) const override
{
auto const& table = env_.app().getAmendmentTable();
auto const amendment = table.find(std::string(amendmentName));
@@ -586,43 +586,40 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<std::shared_ptr<SLE const>, HostFunctionError>
getCurrentLedgerObj()
getCurrentLedgerObj() const
{
if (!isLedgerObjCached)
{
isLedgerObjCached = true;
currentLedgerObj = env_.le(leKey);
}
if (currentLedgerObj)
return currentLedgerObj;
if (!currentLedgerObj_)
currentLedgerObj_ = env_.le(leKey_);
if (*currentLedgerObj_)
return *currentLedgerObj_;
return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND);
}
Expected<std::shared_ptr<SLE const>, HostFunctionError>
peekCurrentLedgerObj(int32_t cacheIdx)
peekCurrentLedgerObj(int32_t cacheIdx) const
{
--cacheIdx;
if (cacheIdx < 0 || cacheIdx >= MAX_CACHE)
return Unexpected(HostFunctionError::SLOT_OUT_RANGE);
if (!cache[cacheIdx])
if (!cache_[cacheIdx])
{ // return Unexpected(HostFunctionError::INVALID_SLOT);
auto const r = getCurrentLedgerObj();
if (!r)
return Unexpected(r.error());
cache[cacheIdx] = *r;
cache_[cacheIdx] = *r;
}
return cache[cacheIdx];
return cache_[cacheIdx];
}
Expected<int32_t, HostFunctionError>
normalizeCacheIndex(int32_t cacheIdx)
normalizeCacheIndex(int32_t cacheIdx) const
{
--cacheIdx;
if (cacheIdx < 0 || cacheIdx >= MAX_CACHE)
return Unexpected(HostFunctionError::SLOT_OUT_RANGE);
if (!cache[cacheIdx])
if (!cache_[cacheIdx])
return Unexpected(HostFunctionError::EMPTY_SLOT);
return cacheIdx;
}
@@ -640,7 +637,7 @@ struct PerfHostFunctions : public TestHostFunctions
if (!cacheIdx)
{
for (cacheIdx = 0; cacheIdx < MAX_CACHE; ++cacheIdx)
if (!cache[cacheIdx])
if (!cache_[cacheIdx])
break;
if (cacheIdx >= MAX_CACHE)
cacheIdx = intIdx++ % MAX_CACHE;
@@ -651,8 +648,8 @@ struct PerfHostFunctions : public TestHostFunctions
if (cacheIdx >= MAX_CACHE)
return Unexpected(HostFunctionError::SLOTS_FULL);
cache[cacheIdx] = env_.le(leKey);
if (!cache[cacheIdx])
cache_[cacheIdx] = env_.le(leKey_);
if (!cache_[cacheIdx])
return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND);
return cacheIdx + 1;
}
@@ -732,13 +729,13 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) override
getTxField(SField const& fname) const override
{
return getAnyFieldData(tx_->peekAtPField(fname));
}
Expected<Bytes, HostFunctionError>
getCurrentLedgerObjField(SField const& fname) override
getCurrentLedgerObjField(SField const& fname) const override
{
auto const sle = getCurrentLedgerObj();
if (!sle)
@@ -747,7 +744,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
getLedgerObjField(int32_t cacheIdx, SField const& fname) override
getLedgerObjField(int32_t cacheIdx, SField const& fname) const override
{
auto const sle = peekCurrentLedgerObj(cacheIdx);
if (!sle)
@@ -819,7 +816,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
getTxNestedField(Slice const& locator) override
getTxNestedField(Slice const& locator) const override
{
// std::cout << tx_->getJson(JsonOptions::none).toStyledString() <<
// std::endl;
@@ -830,7 +827,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(Slice const& locator) override
getCurrentLedgerObjNestedField(Slice const& locator) const override
{
auto const sle = getCurrentLedgerObj();
if (!sle)
@@ -844,7 +841,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const override
{
auto const sle = peekCurrentLedgerObj(cacheIdx);
if (!sle)
@@ -858,7 +855,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<int32_t, HostFunctionError>
getTxArrayLen(SField const& fname) override
getTxArrayLen(SField const& fname) const override
{
if (fname.fieldType != STI_ARRAY)
return Unexpected(HostFunctionError::NO_ARRAY);
@@ -875,7 +872,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<int32_t, HostFunctionError>
getCurrentLedgerObjArrayLen(SField const& fname) override
getCurrentLedgerObjArrayLen(SField const& fname) const override
{
if (fname.fieldType != STI_ARRAY)
return Unexpected(HostFunctionError::NO_ARRAY);
@@ -896,7 +893,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<int32_t, HostFunctionError>
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const override
{
if (fname.fieldType != STI_ARRAY)
return Unexpected(HostFunctionError::NO_ARRAY);
@@ -917,7 +914,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<int32_t, HostFunctionError>
getTxNestedArrayLen(Slice const& locator) override
getTxNestedArrayLen(Slice const& locator) const override
{
auto const r = locateField(*tx_, locator);
if (!r)
@@ -932,7 +929,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(Slice const& locator) override
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const override
{
auto const sle = getCurrentLedgerObj();
if (!sle)
@@ -951,7 +948,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const override
{
auto const sle = peekCurrentLedgerObj(cacheIdx);
if (!sle)
@@ -978,7 +975,7 @@ struct PerfHostFunctions : public TestHostFunctions
xrpl::detail::ApplyViewBase v(env_.app().openLedger().current().get(), tapNONE);
auto sle = v.peek(leKey);
auto sle = v.peek(leKey_);
if (!sle)
return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND);
@@ -989,7 +986,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<int32_t, HostFunctionError>
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) override
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const override
{
if (!publicKeyType(pubkey))
return Unexpected(HostFunctionError::INVALID_PARAMS);
@@ -999,14 +996,14 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data) override
computeSha512HalfHash(Slice const& data) const override
{
auto const hash = sha512Half(data);
return hash;
}
Expected<Bytes, HostFunctionError>
accountKeylet(AccountID const& account) override
accountKeylet(AccountID const& account) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1015,7 +1012,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
ammKeylet(Asset const& issue1, Asset const& issue2) override
ammKeylet(Asset const& issue1, Asset const& issue2) const override
{
if (issue1 == issue2)
return Unexpected(HostFunctionError::INVALID_PARAMS);
@@ -1029,7 +1026,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
checkKeylet(AccountID const& account, std::uint32_t seq) override
checkKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1038,7 +1035,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) override
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) const override
{
if (!subject || !issuer)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1052,7 +1049,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
didKeylet(AccountID const& account) override
didKeylet(AccountID const& account) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1061,7 +1058,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
delegateKeylet(AccountID const& account, AccountID const& authorize) override
delegateKeylet(AccountID const& account, AccountID const& authorize) const override
{
if (!account || !authorize)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1072,7 +1069,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) override
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const override
{
if (!account || !authorize)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1083,7 +1080,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
escrowKeylet(AccountID const& account, std::uint32_t seq) override
escrowKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1092,7 +1089,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) override
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const override
{
if (!account1 || !account2)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1106,7 +1103,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) override
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const override
{
if (!issuer)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1116,7 +1113,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
mptokenKeylet(MPTID const& mptid, AccountID const& holder) override
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const override
{
if (!mptid)
return Unexpected(HostFunctionError::INVALID_PARAMS);
@@ -1128,7 +1125,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
nftOfferKeylet(AccountID const& account, std::uint32_t seq) override
nftOfferKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1137,7 +1134,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
offerKeylet(AccountID const& account, std::uint32_t seq) override
offerKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1146,7 +1143,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
oracleKeylet(AccountID const& account, std::uint32_t documentId) override
oracleKeylet(AccountID const& account, std::uint32_t documentId) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1155,7 +1152,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) override
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const override
{
if (!account || !destination)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1166,7 +1163,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) override
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1175,7 +1172,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
signersKeylet(AccountID const& account) override
signersKeylet(AccountID const& account) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1184,7 +1181,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
ticketKeylet(AccountID const& account, std::uint32_t seq) override
ticketKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1193,7 +1190,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
vaultKeylet(AccountID const& account, std::uint32_t seq) override
vaultKeylet(AccountID const& account, std::uint32_t seq) const override
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -1202,7 +1199,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
getNFT(AccountID const& account, uint256 const& nftId) override
getNFT(AccountID const& account, uint256 const& nftId) const override
{
if (!account || !nftId)
{
@@ -1226,7 +1223,7 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId) override
getNFTIssuer(uint256 const& nftId) const override
{
auto const issuer = nft::getIssuer(nftId);
if (!issuer)
@@ -1236,29 +1233,31 @@ struct PerfHostFunctions : public TestHostFunctions
}
Expected<std::uint32_t, HostFunctionError>
getNFTTaxon(uint256 const& nftId) override
getNFTTaxon(uint256 const& nftId) const override
{
return nft::toUInt32(nft::getTaxon(nftId));
}
Expected<int32_t, HostFunctionError>
getNFTFlags(uint256 const& nftId) override
getNFTFlags(uint256 const& nftId) const override
{
return nft::getFlags(nftId);
}
Expected<int32_t, HostFunctionError>
getNFTTransferFee(uint256 const& nftId) override
getNFTTransferFee(uint256 const& nftId) const override
{
return nft::getTransferFee(nftId);
}
Expected<std::uint32_t, HostFunctionError>
getNFTSerial(uint256 const& nftId) override
getNFTSerial(uint256 const& nftId) const override
{
return nft::getSerial(nftId);
}
};
#endif
} // namespace test
} // namespace xrpl

View File

@@ -37,7 +37,8 @@ runFinishFunction(std::string const& code)
{
auto& engine = WasmEngine::instance();
auto const wasm = hexToBytes(code);
auto const re = engine.run(wasm, "finish");
HostFunctions hfs;
auto const re = engine.run(wasm, hfs, "finish");
if (re.has_value())
{
return std::optional<int32_t>(re->result);
@@ -107,10 +108,11 @@ struct Wasm_test : public beast::unit_test::suite
// clang-format on
auto& vm = WasmEngine::instance();
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
WasmImpFunc<Add_proto>(*imports, "func-add", reinterpret_cast<void*>(&Add));
HostFunctions hfs;
ImportVec imports;
WasmImpFunc<Add_proto>(imports, "func-add", reinterpret_cast<void*>(&Add), &hfs);
auto re = vm.run(wasm, "addTwo", wasmParams(1234, 5678), imports);
auto re = vm.run(wasm, hfs, "addTwo", wasmParams(1234, 5678), imports);
// if (res) printf("invokeAdd get the result: %d\n", res.value());
@@ -125,7 +127,7 @@ struct Wasm_test : public beast::unit_test::suite
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new HostFunctions(env.journal));
HostFunctions hfs(env.journal);
{
auto wasm = hexToBytes("00000000");
@@ -175,12 +177,12 @@ struct Wasm_test : public beast::unit_test::suite
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
auto imports = std::make_shared<ImportVec>();
WASM_IMPORT_FUNC2(*imports, getLedgerSqn, "get_ledger_sqn", hfs.get(), 33);
TestLedgerDataProvider hfs(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs, 33);
auto& engine = WasmEngine::instance();
auto re = engine.run(ledgerSqnWasm, ESCROW_FUNCTION_NAME, {}, imports, hfs, 1'000'000, env.journal);
auto re = engine.run(ledgerSqnWasm, hfs, ESCROW_FUNCTION_NAME, {}, imports, 1'000'000, env.journal);
checkResult(re, 0, 440);
@@ -188,9 +190,13 @@ struct Wasm_test : public beast::unit_test::suite
env.close();
// empty module - run the same instance
re = engine.run({}, ESCROW_FUNCTION_NAME, {}, imports, hfs, 1'000'000, env.journal);
re = engine.run({}, hfs, ESCROW_FUNCTION_NAME, {}, imports, 1'000'000, env.journal);
#ifdef WASM_PERF_TESTS
checkResult(re, 5, 488);
#else
BEAST_EXPECT(!re);
#endif
env.close();
}
void
@@ -200,12 +206,14 @@ struct Wasm_test : public beast::unit_test::suite
auto const fibWasm = hexToBytes(fibWasmHex);
auto& engine = WasmEngine::instance();
HostFunctions hfs;
auto const re = engine.run(fibWasm, "fib", wasmParams(10));
auto const re = engine.run(fibWasm, hfs, "fib", wasmParams(10));
checkResult(re, 55, 1'137);
}
#ifdef WASM_PERF_TESTS
void
testWasmSha()
{
@@ -213,8 +221,9 @@ struct Wasm_test : public beast::unit_test::suite
auto const sha512Wasm = hexToBytes(sha512PureWasmHex);
auto& engine = WasmEngine::instance();
HostFunctions hfs;
auto const re = engine.run(sha512Wasm, "sha512_process", wasmParams(sha512PureWasmHex));
auto const re = engine.run(sha512Wasm, hfs, "sha512_process", wasmParams(sha512PureWasmHex));
checkResult(re, 34'432, 151'155);
}
@@ -225,6 +234,7 @@ struct Wasm_test : public beast::unit_test::suite
testcase("Wasm base58");
auto const b58Wasm = hexToBytes(b58WasmHex);
auto& engine = WasmEngine::instance();
HostFunctions hfs;
Bytes outb;
outb.resize(1024);
@@ -232,10 +242,11 @@ struct Wasm_test : public beast::unit_test::suite
auto const minSize = std::min(static_cast<std::uint32_t>(512), static_cast<std::uint32_t>(b58WasmHex.size()));
auto const s = std::string_view(b58WasmHex.c_str(), minSize);
auto const re = engine.run(b58Wasm, "b58enco", wasmParams(outb, s));
auto const re = engine.run(b58Wasm, hfs, "b58enco", wasmParams(outb, s));
checkResult(re, 700, 2'886'069);
}
#endif
void
testHFCost()
@@ -250,12 +261,12 @@ struct Wasm_test : public beast::unit_test::suite
auto& engine = WasmEngine::instance();
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto imp = createWasmImport(*hfs);
for (auto& i : *imp)
TestHostFunctions hfs(env, 0);
auto imp = createWasmImport(hfs);
for (auto& i : imp)
i.second.gas = 0;
auto re = engine.run(allHostFuncWasm, ESCROW_FUNCTION_NAME, {}, imp, hfs, 1'000'000, env.journal);
auto re = engine.run(allHostFuncWasm, hfs, ESCROW_FUNCTION_NAME, {}, imp, 1'000'000, env.journal);
checkResult(re, 1, 27'080);
@@ -273,10 +284,10 @@ struct Wasm_test : public beast::unit_test::suite
auto& engine = WasmEngine::instance();
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto const imp = createWasmImport(*hfs);
TestHostFunctions hfs(env, 0);
auto const imp = createWasmImport(hfs);
auto re = engine.run(allHostFuncWasm, ESCROW_FUNCTION_NAME, {}, imp, hfs, 1'000'000, env.journal);
auto re = engine.run(allHostFuncWasm, hfs, ESCROW_FUNCTION_NAME, {}, imp, 1'000'000, env.journal);
checkResult(re, 1, 66'340);
@@ -289,10 +300,10 @@ struct Wasm_test : public beast::unit_test::suite
auto& engine = WasmEngine::instance();
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto const imp = createWasmImport(*hfs);
TestHostFunctions hfs(env, 0);
auto const imp = createWasmImport(hfs);
auto re = engine.run(allHostFuncWasm, ESCROW_FUNCTION_NAME, {}, imp, hfs, 200, env.journal);
auto re = engine.run(allHostFuncWasm, hfs, ESCROW_FUNCTION_NAME, {}, imp, 200, env.journal);
if (BEAST_EXPECT(!re))
{
@@ -313,14 +324,14 @@ struct Wasm_test : public beast::unit_test::suite
using namespace test::jtx;
Env env{*this};
{
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
TestHostFunctions hfs(env, 0);
auto re = runEscrowWasm(allHFWasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000);
checkResult(re, 1, 66'340);
}
{
// max<int64_t>() gas
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
TestHostFunctions hfs(env, 0);
auto re = runEscrowWasm(allHFWasm, hfs, ESCROW_FUNCTION_NAME, {}, -1);
checkResult(re, 1, 66'340);
}
@@ -332,13 +343,13 @@ struct Wasm_test : public beast::unit_test::suite
{
}
Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) override
getTxField(SField const& fname) const override
{
return Unexpected(HostFunctionError::FIELD_NOT_FOUND);
}
};
std::shared_ptr<HostFunctions> hfs(new BadTestHostFunctions(env));
BadTestHostFunctions hfs(env);
auto re = runEscrowWasm(allHFWasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000);
checkResult(re, -201, 28'965);
}
@@ -350,13 +361,13 @@ struct Wasm_test : public beast::unit_test::suite
{
}
Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) override
getTxField(SField const& fname) const override
{
return Bytes((128 + 1) * 64 * 1024, 1);
}
};
std::shared_ptr<HostFunctions> hfs(new BadTestHostFunctions(env));
BadTestHostFunctions hfs(env);
auto re = runEscrowWasm(allHFWasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000);
checkResult(re, -201, 28'965);
}
@@ -365,14 +376,14 @@ struct Wasm_test : public beast::unit_test::suite
auto const deepWasm = hexToBytes(deepRecursionHex);
std::shared_ptr<TestHostFunctionsSink> hfs(new TestHostFunctionsSink(env));
TestHostFunctionsSink hfs(env);
std::string funcName("finish");
auto re = runEscrowWasm(deepWasm, hfs, funcName, {}, 1'000'000'000);
BEAST_EXPECT(!re && re.error());
// std::cout << "bad case (deep recursion) result " << re.error()
// << std::endl;
auto const& sink = hfs->getSink();
auto const& sink = hfs.getSink();
auto countSubstr = [](std::string const& str, std::string const& substr) {
std::size_t pos = 0;
int occurrences = 0;
@@ -392,7 +403,7 @@ struct Wasm_test : public beast::unit_test::suite
{ // infinite loop
auto const infiniteLoopWasm = hexToBytes(infiniteLoopWasmHex);
std::string const funcName("loop");
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
TestHostFunctions hfs(env, 0);
// infinite loop should be caught and fail
auto const re = runEscrowWasm(infiniteLoopWasm, hfs, funcName, {}, 1'000'000);
@@ -405,13 +416,13 @@ struct Wasm_test : public beast::unit_test::suite
{
// expected import not provided
auto const lgrSqnWasm = hexToBytes(ledgerSqnWasmHex);
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
WASM_IMPORT_FUNC2(*imports, getLedgerSqn, "get_ledger_sqn2", hfs.get());
TestLedgerDataProvider hfs(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn2", &hfs);
auto& engine = WasmEngine::instance();
auto re = engine.run(lgrSqnWasm, ESCROW_FUNCTION_NAME, {}, imports, hfs, 1'000'000, env.journal);
auto re = engine.run(lgrSqnWasm, hfs, ESCROW_FUNCTION_NAME, {}, imports, 1'000'000, env.journal);
BEAST_EXPECT(!re);
}
@@ -419,14 +430,14 @@ struct Wasm_test : public beast::unit_test::suite
{
// bad import format
auto const lgrSqnWasm = hexToBytes(ledgerSqnWasmHex);
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
WASM_IMPORT_FUNC2(*imports, getLedgerSqn, "get_ledger_sqn", hfs.get());
(*imports)[0].first = nullptr;
TestLedgerDataProvider hfs(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs);
imports[0].first = nullptr;
auto& engine = WasmEngine::instance();
auto re = engine.run(lgrSqnWasm, ESCROW_FUNCTION_NAME, {}, imports, hfs, 1'000'000, env.journal);
auto re = engine.run(lgrSqnWasm, hfs, ESCROW_FUNCTION_NAME, {}, imports, 1'000'000, env.journal);
BEAST_EXPECT(!re);
}
@@ -434,12 +445,12 @@ struct Wasm_test : public beast::unit_test::suite
{
// bad function name
auto const lgrSqnWasm = hexToBytes(ledgerSqnWasmHex);
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
WASM_IMPORT_FUNC2(*imports, getLedgerSqn, "get_ledger_sqn", hfs.get());
TestLedgerDataProvider hfs(env);
ImportVec imports;
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hfs);
auto& engine = WasmEngine::instance();
auto re = engine.run(lgrSqnWasm, "func1", {}, imports, hfs, 1'000'000, env.journal);
auto re = engine.run(lgrSqnWasm, hfs, "func1", {}, imports, 1'000'000, env.journal);
BEAST_EXPECT(!re);
}
@@ -458,7 +469,7 @@ struct Wasm_test : public beast::unit_test::suite
{
auto const floatTestWasm = hexToBytes(floatTestsWasmHex);
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
TestHostFunctions hfs(env, 0);
auto re = runEscrowWasm(floatTestWasm, hfs, funcName, {}, 200'000);
checkResult(re, 1, 110'699);
env.close();
@@ -467,13 +478,14 @@ struct Wasm_test : public beast::unit_test::suite
{
auto const float0Wasm = hexToBytes(float0Hex);
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
TestHostFunctions hfs(env, 0);
auto re = runEscrowWasm(float0Wasm, hfs, funcName, {}, 100'000);
checkResult(re, 1, 4'259);
env.close();
}
}
#ifdef WASM_PERF_TESTS
void
perfTest()
{
@@ -544,7 +556,7 @@ struct Wasm_test : public beast::unit_test::suite
env(token::mint(alan, 0u));
env.close();
std::shared_ptr<HostFunctions> hfs(new PerfHostFunctions(env, k, env.tx()));
PerfHostFunctions hfs(env, k, env.tx());
auto re = runEscrowWasm(perfWasm, hfs, ESCROW_FUNCTION_NAME);
if (BEAST_EXPECT(re.has_value()))
@@ -561,6 +573,7 @@ struct Wasm_test : public beast::unit_test::suite
env.close();
}
}
#endif
void
testCodecovWasm()
@@ -572,7 +585,7 @@ struct Wasm_test : public beast::unit_test::suite
Env env{*this};
auto const codecovWasm = hexToBytes(codecovTestsWasmHex);
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
TestHostFunctions hfs(env, 0);
auto const allowance = 201'503;
auto re = runEscrowWasm(codecovWasm, hfs, ESCROW_FUNCTION_NAME, {}, allowance);
@@ -590,7 +603,7 @@ struct Wasm_test : public beast::unit_test::suite
auto disabledFloatWasm = hexToBytes(disabledFloatHex);
std::string const funcName("finish");
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
TestHostFunctions hfs(env, 0);
{
// f32 set constant, opcode disabled exception
@@ -703,17 +716,18 @@ struct Wasm_test : public beast::unit_test::suite
Env env(*this);
auto const startLoopWasm = hexToBytes(startLoopHex);
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
TestLedgerDataProvider hfs(env);
ImportVec imports;
auto& engine = WasmEngine::instance();
auto checkRes = engine.check(startLoopWasm, "finish", {}, imports, hfs, env.journal);
auto checkRes = engine.check(startLoopWasm, hfs, "finish", {}, imports, env.journal);
BEAST_EXPECTS(checkRes == tesSUCCESS, std::to_string(TERtoInt(checkRes)));
auto re = engine.run(startLoopWasm, ESCROW_FUNCTION_NAME, {}, imports, hfs, 1'000'000, env.journal);
auto re = engine.run(startLoopWasm, hfs, ESCROW_FUNCTION_NAME, {}, imports, 1'000'000, env.journal);
BEAST_EXPECTS(re.error() == tecFAILED_PROCESSING, std::to_string(TERtoInt(re.error())));
}
#ifdef WASM_PERF_TESTS
void
testBadAlloc()
{
@@ -725,15 +739,14 @@ struct Wasm_test : public beast::unit_test::suite
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
TestLedgerDataProvider hfs(env);
// std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
uint8_t buf1[8] = {7, 8, 9, 10, 11, 12, 13, 14};
{ // forged "allocate" return valid address
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = sizeof(buf1)}}}};
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = sizeof(buf1) } } }};
auto& engine = WasmEngine::instance();
auto re = engine.run(badAllocWasm, "test", params, {}, hfs, 1'000'000, env.journal);
auto re = engine.run(badAllocWasm, hfs, "test", params, {}, 1'000'000, env.journal);
if (BEAST_EXPECT(re))
{
BEAST_EXPECTS(re->result == 7, std::to_string(re->result));
@@ -742,30 +755,30 @@ struct Wasm_test : public beast::unit_test::suite
}
{ // return 0 whithout calling wasm
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 0}}}};
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 0 } } }};
auto& engine = WasmEngine::instance();
auto re = engine.run(badAllocWasm, "test", params, {}, hfs, 1'000'000, env.journal);
auto re = engine.run(badAllocWasm, hfs, "test", params, {}, 1'000'000, env.journal);
BEAST_EXPECT(!re) && BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
{ // forged "allocate" return 8Mb (which is more than memory limit)
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 1}}}};
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 1 } } }};
auto& engine = WasmEngine::instance();
auto re = engine.run(badAllocWasm, "test", params, {}, hfs, 1'000'000, env.journal);
auto re = engine.run(badAllocWasm, hfs, "test", params, {}, 1'000'000, env.journal);
BEAST_EXPECT(!re) && BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
{ // forged "allocate" return 0
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 2}}}};
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 2 } } }};
auto& engine = WasmEngine::instance();
auto re = engine.run(badAllocWasm, "test", params, {}, hfs, 1'000'000, env.journal);
auto re = engine.run(badAllocWasm, hfs, "test", params, {}, 1'000'000, env.journal);
BEAST_EXPECT(!re) && BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
{ // forged "allocate" return -1
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 3}}}};
std::vector<WasmParam> params = {{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 3 } } }};
auto& engine = WasmEngine::instance();
auto re = engine.run(badAllocWasm, "test", params, {}, hfs, 1'000'000, env.journal);
auto re = engine.run(badAllocWasm, hfs, "test", params, {}, 1'000'000, env.journal);
BEAST_EXPECT(!re) && BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
@@ -787,6 +800,7 @@ struct Wasm_test : public beast::unit_test::suite
env.close();
}
#endif
void
testBadAlign()
@@ -799,14 +813,14 @@ struct Wasm_test : public beast::unit_test::suite
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto imports = createWasmImport(*hfs);
TestHostFunctions hfs(env, 0);
auto imports = createWasmImport(hfs);
{ // Calls float_from_uint with bad alignment.
// Can be checked through codecov
auto& engine = WasmEngine::instance();
auto re = engine.run(badAlignWasm, "test", {}, imports, hfs, 1'000'000, env.journal);
auto re = engine.run(badAlignWasm, hfs, "test", {}, imports, 1'000'000, env.journal);
if (BEAST_EXPECTS(re, transToken(re.error())))
{
BEAST_EXPECTS(re->result == 0x684f7941, std::to_string(re->result));
@@ -821,7 +835,7 @@ struct Wasm_test : public beast::unit_test::suite
{
using namespace test::jtx;
Env env(*this);
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
TestHostFunctions hfs(env, 0);
// return int64.
{ // (module
@@ -934,8 +948,8 @@ struct Wasm_test : public beast::unit_test::suite
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto imports = createWasmImport(*hfs);
TestHostFunctions hfs(env, 0);
auto imports = createWasmImport(hfs);
// add 1k parameter (max that wasmi support)
std::vector<WasmParam> params;
@@ -944,28 +958,28 @@ struct Wasm_test : public beast::unit_test::suite
auto& engine = WasmEngine::instance();
{
auto re = engine.run(params1k, "test", params, imports, hfs, 1'000'000, env.journal);
auto re = engine.run(params1k, hfs, "test", params, imports, 1'000'000, env.journal);
BEAST_EXPECT(re && re->result == 999000);
}
// add 1 more parameter, module can't be created now
params.push_back({.type = WT_I32, .of = {.i32 = 2 * 1000}});
{
auto re = engine.run(params1k1, "test", params, imports, hfs, 1'000'000, env.journal);
auto re = engine.run(params1k1, hfs, "test", params, imports, 1'000'000, env.journal);
BEAST_EXPECT(!re);
}
// function that create 10k local variables
auto const locals10k = hexToBytes(locals10kHex);
{
auto re = engine.run(locals10k, "test", wasmParams(0, 1), imports, hfs, 1'000'000, env.journal);
auto re = engine.run(locals10k, hfs, "test", wasmParams(0, 1), imports, 1'000'000, env.journal);
BEAST_EXPECT(re && re->result == 890'489'442);
}
// module has 5k functions
auto const functions5k = hexToBytes(functions5kHex);
{
auto re = engine.run(functions5k, "test0001", wasmParams(2, 3), imports, hfs, 1'000'000, env.journal);
auto re = engine.run(functions5k, hfs, "test0001", wasmParams(2, 3), imports, 1'000'000, env.journal);
BEAST_EXPECT(re && re->result == 5);
}
@@ -983,8 +997,6 @@ struct Wasm_test : public beast::unit_test::suite
testWasmLedgerSqn();
testWasmFib();
testWasmSha();
testWasmB58();
testHFCost();
testEscrowWasmDN();
@@ -1001,13 +1013,18 @@ struct Wasm_test : public beast::unit_test::suite
testWasmSectionCorruption();
testStartFunctionLoop();
testBadAlloc();
testBadAlign();
testReturnType();
testSwapBytes();
testManyParams();
#ifdef WASM_PERF_TESTS
// only performance tests can pass buffer to Wasm (and call exported "allocate" function)
testWasmSha();
testWasmB58();
testBadAlloc();
// perfTest();
#endif
}
};

View File

@@ -104,56 +104,50 @@ struct HostFunctions
return nullptr;
}
std::int64_t
getGas()
{
return -1;
}
void
setGas(std::int64_t)
{
return;
}
beast::Journal
getJournal()
getJournal() const
{
return j_;
}
virtual bool
checkSelf() const
{
return true;
}
virtual Expected<std::uint32_t, HostFunctionError>
getLedgerSqn()
getLedgerSqn() const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<std::uint32_t, HostFunctionError>
getParentLedgerTime()
getParentLedgerTime() const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Hash, HostFunctionError>
getParentLedgerHash()
getParentLedgerHash() const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<uint32_t, HostFunctionError>
getBaseFee()
getBaseFee() const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
isAmendmentEnabled(uint256 const& amendmentId)
isAmendmentEnabled(uint256 const& amendmentId) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
isAmendmentEnabled(std::string_view const& amendmentName)
isAmendmentEnabled(std::string_view const& amendmentName) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
@@ -165,73 +159,73 @@ struct HostFunctions
}
virtual Expected<Bytes, HostFunctionError>
getTxField(SField const& fname)
getTxField(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
getCurrentLedgerObjField(SField const& fname)
getCurrentLedgerObjField(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
getLedgerObjField(int32_t cacheIdx, SField const& fname)
getLedgerObjField(int32_t cacheIdx, SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
getTxNestedField(Slice const& locator)
getTxNestedField(Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(Slice const& locator)
getCurrentLedgerObjNestedField(Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator)
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
getTxArrayLen(SField const& fname)
getTxArrayLen(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
getCurrentLedgerObjArrayLen(SField const& fname)
getCurrentLedgerObjArrayLen(SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname)
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
getTxNestedArrayLen(Slice const& locator)
getTxNestedArrayLen(Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(Slice const& locator)
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator)
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
@@ -243,259 +237,259 @@ struct HostFunctions
}
virtual Expected<int32_t, HostFunctionError>
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey)
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data)
computeSha512HalfHash(Slice const& data) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
accountKeylet(AccountID const& account)
accountKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
ammKeylet(Asset const& issue1, Asset const& issue2)
ammKeylet(Asset const& issue1, Asset const& issue2) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
checkKeylet(AccountID const& account, std::uint32_t seq)
checkKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType)
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
didKeylet(AccountID const& account)
didKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
delegateKeylet(AccountID const& account, AccountID const& authorize)
delegateKeylet(AccountID const& account, AccountID const& authorize) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
depositPreauthKeylet(AccountID const& account, AccountID const& authorize)
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
escrowKeylet(AccountID const& account, std::uint32_t seq)
escrowKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency)
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq)
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
mptokenKeylet(MPTID const& mptid, AccountID const& holder)
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
nftOfferKeylet(AccountID const& account, std::uint32_t seq)
nftOfferKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
offerKeylet(AccountID const& account, std::uint32_t seq)
offerKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
oracleKeylet(AccountID const& account, std::uint32_t docId)
oracleKeylet(AccountID const& account, std::uint32_t docId) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq)
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq)
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
signersKeylet(AccountID const& account)
signersKeylet(AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
ticketKeylet(AccountID const& account, std::uint32_t seq)
ticketKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
vaultKeylet(AccountID const& account, std::uint32_t seq)
vaultKeylet(AccountID const& account, std::uint32_t seq) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
getNFT(AccountID const& account, uint256 const& nftId)
getNFT(AccountID const& account, uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId)
getNFTIssuer(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<std::uint32_t, HostFunctionError>
getNFTTaxon(uint256 const& nftId)
getNFTTaxon(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
getNFTFlags(uint256 const& nftId)
getNFTFlags(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
getNFTTransferFee(uint256 const& nftId)
getNFTTransferFee(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<std::uint32_t, HostFunctionError>
getNFTSerial(uint256 const& nftId)
getNFTSerial(uint256 const& nftId) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
trace(std::string_view const& msg, Slice const& data, bool asHex)
trace(std::string_view const& msg, Slice const& data, bool asHex) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
traceNum(std::string_view const& msg, int64_t data)
traceNum(std::string_view const& msg, int64_t data) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
traceAccount(std::string_view const& msg, AccountID const& account)
traceAccount(std::string_view const& msg, AccountID const& account) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
traceFloat(std::string_view const& msg, Slice const& data)
traceFloat(std::string_view const& msg, Slice const& data) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
traceAmount(std::string_view const& msg, STAmount const& amount)
traceAmount(std::string_view const& msg, STAmount const& amount) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatFromInt(int64_t x, int32_t mode)
floatFromInt(int64_t x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatFromUint(uint64_t x, int32_t mode)
floatFromUint(uint64_t x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatSet(int64_t mantissa, int32_t exponent, int32_t mode)
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<int32_t, HostFunctionError>
floatCompare(Slice const& x, Slice const& y)
floatCompare(Slice const& x, Slice const& y) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatAdd(Slice const& x, Slice const& y, int32_t mode)
floatAdd(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatSubtract(Slice const& x, Slice const& y, int32_t mode)
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatMultiply(Slice const& x, Slice const& y, int32_t mode)
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatDivide(Slice const& x, Slice const& y, int32_t mode)
floatDivide(Slice const& x, Slice const& y, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatRoot(Slice const& x, int32_t n, int32_t mode)
floatRoot(Slice const& x, int32_t n, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatPower(Slice const& x, int32_t n, int32_t mode)
floatPower(Slice const& x, int32_t n, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}
virtual Expected<Bytes, HostFunctionError>
floatLog(Slice const& x, int32_t mode)
floatLog(Slice const& x, int32_t mode) const
{
return Unexpected(HostFunctionError::INTERNAL);
}

View File

@@ -6,44 +6,42 @@
namespace xrpl {
class WasmHostFunctionsImpl : public HostFunctions
{
ApplyContext& ctx;
Keylet leKey;
std::shared_ptr<SLE const> currentLedgerObj = nullptr;
bool isLedgerObjCached = false;
ApplyContext& ctx_;
Keylet leKey_;
mutable std::optional<std::shared_ptr<SLE const>> currentLedgerObj_;
static int constexpr MAX_CACHE = 256;
std::array<std::shared_ptr<SLE const>, MAX_CACHE> cache;
std::array<std::shared_ptr<SLE const>, MAX_CACHE> cache_;
std::optional<Bytes> data_;
void const* rt_ = nullptr;
Expected<std::shared_ptr<SLE const>, HostFunctionError>
getCurrentLedgerObj()
getCurrentLedgerObj() const
{
if (!isLedgerObjCached)
{
isLedgerObjCached = true;
currentLedgerObj = ctx.view().read(leKey);
}
if (currentLedgerObj)
return currentLedgerObj;
if (!currentLedgerObj_)
currentLedgerObj_ = ctx_.view().read(leKey_);
if (*currentLedgerObj_)
return *currentLedgerObj_;
return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND);
}
Expected<int32_t, HostFunctionError>
normalizeCacheIndex(int32_t cacheIdx)
normalizeCacheIndex(int32_t cacheIdx) const
{
--cacheIdx;
if (cacheIdx < 0 || cacheIdx >= MAX_CACHE)
return Unexpected(HostFunctionError::SLOT_OUT_RANGE);
if (!cache[cacheIdx])
if (!cache_[cacheIdx])
return Unexpected(HostFunctionError::EMPTY_SLOT);
return cacheIdx;
}
template <typename F>
void
log(std::string_view const& msg, F&& dataFn)
log(std::string_view const& msg, F&& dataFn) const
{
#ifdef DEBUG_OUTPUT
auto& j = std::cerr;
@@ -52,7 +50,7 @@ class WasmHostFunctionsImpl : public HostFunctions
return;
auto j = getJournal().trace();
#endif
j << "WasmTrace[" << to_short_string(leKey.key) << "]: " << msg << " " << dataFn();
j << "WasmTrace[" << to_short_string(leKey_.key) << "]: " << msg << " " << dataFn();
#ifdef DEBUG_OUTPUT
j << std::endl;
@@ -60,7 +58,7 @@ class WasmHostFunctionsImpl : public HostFunctions
}
public:
WasmHostFunctionsImpl(ApplyContext& ct, Keylet const& leKey) : HostFunctions(ct.journal), ctx(ct), leKey(leKey)
WasmHostFunctionsImpl(ApplyContext& ct, Keylet const& leKey) : HostFunctions(ct.journal), ctx_(ct), leKey_(leKey)
{
}
@@ -76,6 +74,13 @@ public:
return rt_;
}
virtual bool
checkSelf() const override
{
return !currentLedgerObj_ && !data_ &&
std::ranges::find_if(cache_, [](auto& p) { return !!p; }) == cache_.end();
}
std::optional<Bytes> const&
getData() const
{
@@ -83,193 +88,193 @@ public:
}
Expected<std::uint32_t, HostFunctionError>
getLedgerSqn() override;
getLedgerSqn() const override;
Expected<std::uint32_t, HostFunctionError>
getParentLedgerTime() override;
getParentLedgerTime() const override;
Expected<Hash, HostFunctionError>
getParentLedgerHash() override;
getParentLedgerHash() const override;
Expected<std::uint32_t, HostFunctionError>
getBaseFee() override;
getBaseFee() const override;
Expected<int32_t, HostFunctionError>
isAmendmentEnabled(uint256 const& amendmentId) override;
isAmendmentEnabled(uint256 const& amendmentId) const override;
Expected<int32_t, HostFunctionError>
isAmendmentEnabled(std::string_view const& amendmentName) override;
isAmendmentEnabled(std::string_view const& amendmentName) const override;
Expected<int32_t, HostFunctionError>
cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override;
Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) override;
getTxField(SField const& fname) const override;
Expected<Bytes, HostFunctionError>
getCurrentLedgerObjField(SField const& fname) override;
getCurrentLedgerObjField(SField const& fname) const override;
Expected<Bytes, HostFunctionError>
getLedgerObjField(int32_t cacheIdx, SField const& fname) override;
getLedgerObjField(int32_t cacheIdx, SField const& fname) const override;
Expected<Bytes, HostFunctionError>
getTxNestedField(Slice const& locator) override;
getTxNestedField(Slice const& locator) const override;
Expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(Slice const& locator) override;
getCurrentLedgerObjNestedField(Slice const& locator) const override;
Expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override;
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const override;
Expected<int32_t, HostFunctionError>
getTxArrayLen(SField const& fname) override;
getTxArrayLen(SField const& fname) const override;
Expected<int32_t, HostFunctionError>
getCurrentLedgerObjArrayLen(SField const& fname) override;
getCurrentLedgerObjArrayLen(SField const& fname) const override;
Expected<int32_t, HostFunctionError>
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override;
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const override;
Expected<int32_t, HostFunctionError>
getTxNestedArrayLen(Slice const& locator) override;
getTxNestedArrayLen(Slice const& locator) const override;
Expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(Slice const& locator) override;
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const override;
Expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override;
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const override;
Expected<int32_t, HostFunctionError>
updateData(Slice const& data) override;
Expected<int32_t, HostFunctionError>
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) override;
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const override;
Expected<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data) override;
computeSha512HalfHash(Slice const& data) const override;
Expected<Bytes, HostFunctionError>
accountKeylet(AccountID const& account) override;
accountKeylet(AccountID const& account) const override;
Expected<Bytes, HostFunctionError>
ammKeylet(Asset const& issue1, Asset const& issue2) override;
ammKeylet(Asset const& issue1, Asset const& issue2) const override;
Expected<Bytes, HostFunctionError>
checkKeylet(AccountID const& account, std::uint32_t seq) override;
checkKeylet(AccountID const& account, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) override;
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) const override;
Expected<Bytes, HostFunctionError>
didKeylet(AccountID const& account) override;
didKeylet(AccountID const& account) const override;
Expected<Bytes, HostFunctionError>
delegateKeylet(AccountID const& account, AccountID const& authorize) override;
delegateKeylet(AccountID const& account, AccountID const& authorize) const override;
Expected<Bytes, HostFunctionError>
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) override;
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const override;
Expected<Bytes, HostFunctionError>
escrowKeylet(AccountID const& account, std::uint32_t seq) override;
escrowKeylet(AccountID const& account, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) override;
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const override;
Expected<Bytes, HostFunctionError>
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) override;
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
mptokenKeylet(MPTID const& mptid, AccountID const& holder) override;
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const override;
Expected<Bytes, HostFunctionError>
nftOfferKeylet(AccountID const& account, std::uint32_t seq) override;
nftOfferKeylet(AccountID const& account, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
offerKeylet(AccountID const& account, std::uint32_t seq) override;
offerKeylet(AccountID const& account, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
oracleKeylet(AccountID const& account, std::uint32_t docId) override;
oracleKeylet(AccountID const& account, std::uint32_t docId) const override;
Expected<Bytes, HostFunctionError>
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) override;
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) override;
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
signersKeylet(AccountID const& account) override;
signersKeylet(AccountID const& account) const override;
Expected<Bytes, HostFunctionError>
ticketKeylet(AccountID const& account, std::uint32_t seq) override;
ticketKeylet(AccountID const& account, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
vaultKeylet(AccountID const& account, std::uint32_t seq) override;
vaultKeylet(AccountID const& account, std::uint32_t seq) const override;
Expected<Bytes, HostFunctionError>
getNFT(AccountID const& account, uint256 const& nftId) override;
getNFT(AccountID const& account, uint256 const& nftId) const override;
Expected<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId) override;
getNFTIssuer(uint256 const& nftId) const override;
Expected<std::uint32_t, HostFunctionError>
getNFTTaxon(uint256 const& nftId) override;
getNFTTaxon(uint256 const& nftId) const override;
Expected<int32_t, HostFunctionError>
getNFTFlags(uint256 const& nftId) override;
getNFTFlags(uint256 const& nftId) const override;
Expected<int32_t, HostFunctionError>
getNFTTransferFee(uint256 const& nftId) override;
getNFTTransferFee(uint256 const& nftId) const override;
Expected<std::uint32_t, HostFunctionError>
getNFTSerial(uint256 const& nftId) override;
getNFTSerial(uint256 const& nftId) const override;
Expected<int32_t, HostFunctionError>
trace(std::string_view const& msg, Slice const& data, bool asHex) override;
trace(std::string_view const& msg, Slice const& data, bool asHex) const override;
Expected<int32_t, HostFunctionError>
traceNum(std::string_view const& msg, int64_t data) override;
traceNum(std::string_view const& msg, int64_t data) const override;
Expected<int32_t, HostFunctionError>
traceAccount(std::string_view const& msg, AccountID const& account) override;
traceAccount(std::string_view const& msg, AccountID const& account) const override;
Expected<int32_t, HostFunctionError>
traceFloat(std::string_view const& msg, Slice const& data) override;
traceFloat(std::string_view const& msg, Slice const& data) const override;
Expected<int32_t, HostFunctionError>
traceAmount(std::string_view const& msg, STAmount const& amount) override;
traceAmount(std::string_view const& msg, STAmount const& amount) const override;
Expected<Bytes, HostFunctionError>
floatFromInt(int64_t x, int32_t mode) override;
floatFromInt(int64_t x, int32_t mode) const override;
Expected<Bytes, HostFunctionError>
floatFromUint(uint64_t x, int32_t mode) override;
floatFromUint(uint64_t x, int32_t mode) const override;
Expected<Bytes, HostFunctionError>
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) override;
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const override;
Expected<int32_t, HostFunctionError>
floatCompare(Slice const& x, Slice const& y) override;
floatCompare(Slice const& x, Slice const& y) const override;
Expected<Bytes, HostFunctionError>
floatAdd(Slice const& x, Slice const& y, int32_t mode) override;
floatAdd(Slice const& x, Slice const& y, int32_t mode) const override;
Expected<Bytes, HostFunctionError>
floatSubtract(Slice const& x, Slice const& y, int32_t mode) override;
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const override;
Expected<Bytes, HostFunctionError>
floatMultiply(Slice const& x, Slice const& y, int32_t mode) override;
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const override;
Expected<Bytes, HostFunctionError>
floatDivide(Slice const& x, Slice const& y, int32_t mode) override;
floatDivide(Slice const& x, Slice const& y, int32_t mode) const override;
Expected<Bytes, HostFunctionError>
floatRoot(Slice const& x, int32_t n, int32_t mode) override;
floatRoot(Slice const& x, int32_t n, int32_t mode) const override;
Expected<Bytes, HostFunctionError>
floatPower(Slice const& x, int32_t n, int32_t mode) override;
floatPower(Slice const& x, int32_t n, int32_t mode) const override;
Expected<Bytes, HostFunctionError>
floatLog(Slice const& x, int32_t mode) override;
floatLog(Slice const& x, int32_t mode) const override;
};
namespace wasm_float {

View File

@@ -11,6 +11,8 @@
#include <string>
#include <vector>
// #define WASM_PERF_TESTS 1
namespace bft = boost::function_types;
namespace xrpl {
@@ -173,6 +175,8 @@ wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
// wasmParamsHlp(v, std::forward<Types>(args)...);
// }
#ifdef WASM_PERF_TESTS
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::uint8_t const* dt, std::int32_t sz, Types&&... args)
@@ -219,6 +223,8 @@ wasmParamsHlp(std::vector<WasmParam>& v, std::string const& p, Types&&... args)
std::forward<Types>(args)...);
}
#endif
inline void
wasmParamsHlp(std::vector<WasmParam>& v)
{

View File

@@ -24,7 +24,7 @@ class WasmiEngine;
class WasmEngine
{
std::unique_ptr<WasmiEngine> const impl;
std::unique_ptr<WasmiEngine> const impl_;
WasmEngine();
@@ -43,20 +43,20 @@ public:
Expected<WasmResult<int32_t>, TER>
run(Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName = {},
std::vector<WasmParam> const& params = {},
std::shared_ptr<ImportVec> const& imports = {},
std::shared_ptr<HostFunctions> const& hfs = {},
ImportVec const& imports = {},
int64_t gasLimit = -1,
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
NotTEC
check(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params = {},
std::shared_ptr<ImportVec> const& imports = {},
std::shared_ptr<HostFunctions> const& hfs = {},
ImportVec const& imports = {},
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
// Host functions helper functionality
@@ -69,13 +69,13 @@ public:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<ImportVec>
ImportVec
createWasmImport(HostFunctions& hfs);
Expected<EscrowResult, TER>
runEscrowWasm(
Bytes const& wasmCode,
std::shared_ptr<HostFunctions> const& hfs,
HostFunctions& hfs,
std::string_view funcName = ESCROW_FUNCTION_NAME,
std::vector<WasmParam> const& params = {},
int64_t gasLimit = -1);
@@ -83,7 +83,7 @@ runEscrowWasm(
NotTEC
preflightEscrowWasm(
Bytes const& wasmCode,
std::shared_ptr<HostFunctions> const& hfs,
HostFunctions& hfs,
std::string_view funcName = ESCROW_FUNCTION_NAME,
std::vector<WasmParam> const& params = {});

View File

@@ -144,12 +144,7 @@ public:
ModuleWrapper(ModuleWrapper&& o);
ModuleWrapper&
operator=(ModuleWrapper&& o);
ModuleWrapper(
StorePtr& s,
Bytes const& wasmBin,
bool instantiate,
std::shared_ptr<ImportVec> const& imports,
beast::Journal j);
ModuleWrapper(StorePtr& s, Bytes const& wasmBin, bool instantiate, ImportVec const& imports, beast::Journal j);
~ModuleWrapper() = default;
operator bool() const;
@@ -174,7 +169,7 @@ public:
private:
WasmExternVec
buildImports(StorePtr& s, std::shared_ptr<ImportVec> const& imports);
buildImports(StorePtr& s, ImportVec const& imports);
};
class WasmiEngine
@@ -186,10 +181,6 @@ class WasmiEngine
std::mutex m_; // 1 instance mutex
// to ensure lifetime during next executions with the same module
std::shared_ptr<ImportVec> imports_;
std::shared_ptr<HostFunctions> hfs_;
public:
WasmiEngine();
~WasmiEngine() = default;
@@ -199,24 +190,24 @@ public:
Expected<WasmResult<int32_t>, TER>
run(Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::shared_ptr<ImportVec> const& imports,
std::shared_ptr<HostFunctions> const& hfs,
ImportVec const& imports,
int64_t gas,
beast::Journal j);
NotTEC
check(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::shared_ptr<ImportVec> const& imports,
std::shared_ptr<HostFunctions> const& hfs,
ImportVec const& imports,
beast::Journal j);
std::int64_t
getGas();
getGas() const;
// Host functions helper functionality
wasm_trap_t*
@@ -227,7 +218,7 @@ public:
private:
InstanceWrapper const&
getRT(int m = 0, int i = 0);
getRT(int m = 0, int i = 0) const;
wmem
getMem() const;
@@ -236,13 +227,24 @@ private:
allocate(int32_t size);
Expected<WasmResult<int32_t>, TER>
runHlp(Bytes const& wasmCode, std::string_view funcName, std::vector<WasmParam> const& params, int64_t gas);
runHlp(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
ImportVec const& imports,
int64_t gas);
NotTEC
checkHlp(Bytes const& wasmCode, std::string_view funcName, std::vector<WasmParam> const& params);
checkHlp(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
ImportVec const& imports);
int
addModule(Bytes const& wasmCode, bool instantiate, int64_t gas);
addModule(Bytes const& wasmCode, bool instantiate, ImportVec const& imports, int64_t gas);
void
clearModules();
@@ -255,7 +257,7 @@ private:
makeModule(Bytes const& wasmCode, WasmExternVec const& imports = {});
FuncInfo
getFunc(std::string_view funcName);
getFunc(std::string_view funcName) const;
std::vector<wasm_val_t>
convertParams(std::vector<WasmParam> const& params);

View File

@@ -25,7 +25,7 @@ WasmHostFunctionsImpl::updateData(Slice const& data)
// =========================================================
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey)
WasmHostFunctionsImpl::checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const
{
if (!publicKeyType(pubkey))
return Unexpected(HostFunctionError::INVALID_PARAMS);
@@ -35,7 +35,7 @@ WasmHostFunctionsImpl::checkSignature(Slice const& message, Slice const& signatu
}
Expected<Hash, HostFunctionError>
WasmHostFunctionsImpl::computeSha512HalfHash(Slice const& data)
WasmHostFunctionsImpl::computeSha512HalfHash(Slice const& data) const
{
auto const hash = sha512Half(data);
return hash;

View File

@@ -480,67 +480,67 @@ floatLogImpl(Slice const& x, int32_t mode)
// =========================================================
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatFromInt(int64_t x, int32_t mode)
WasmHostFunctionsImpl::floatFromInt(int64_t x, int32_t mode) const
{
return wasm_float::floatFromIntImpl(x, mode);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatFromUint(uint64_t x, int32_t mode)
WasmHostFunctionsImpl::floatFromUint(uint64_t x, int32_t mode) const
{
return wasm_float::floatFromUintImpl(x, mode);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatSet(int64_t mantissa, int32_t exponent, int32_t mode)
WasmHostFunctionsImpl::floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const
{
return wasm_float::floatSetImpl(mantissa, exponent, mode);
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::floatCompare(Slice const& x, Slice const& y)
WasmHostFunctionsImpl::floatCompare(Slice const& x, Slice const& y) const
{
return wasm_float::floatCompareImpl(x, y);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatAdd(Slice const& x, Slice const& y, int32_t mode)
WasmHostFunctionsImpl::floatAdd(Slice const& x, Slice const& y, int32_t mode) const
{
return wasm_float::floatAddImpl(x, y, mode);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatSubtract(Slice const& x, Slice const& y, int32_t mode)
WasmHostFunctionsImpl::floatSubtract(Slice const& x, Slice const& y, int32_t mode) const
{
return wasm_float::floatSubtractImpl(x, y, mode);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatMultiply(Slice const& x, Slice const& y, int32_t mode)
WasmHostFunctionsImpl::floatMultiply(Slice const& x, Slice const& y, int32_t mode) const
{
return wasm_float::floatMultiplyImpl(x, y, mode);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatDivide(Slice const& x, Slice const& y, int32_t mode)
WasmHostFunctionsImpl::floatDivide(Slice const& x, Slice const& y, int32_t mode) const
{
return wasm_float::floatDivideImpl(x, y, mode);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatRoot(Slice const& x, int32_t n, int32_t mode)
WasmHostFunctionsImpl::floatRoot(Slice const& x, int32_t n, int32_t mode) const
{
return wasm_float::floatRootImpl(x, n, mode);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatPower(Slice const& x, int32_t n, int32_t mode)
WasmHostFunctionsImpl::floatPower(Slice const& x, int32_t n, int32_t mode) const
{
return wasm_float::floatPowerImpl(x, n, mode);
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::floatLog(Slice const& x, int32_t mode)
WasmHostFunctionsImpl::floatLog(Slice const& x, int32_t mode) const
{
return wasm_float::floatLogImpl(x, mode);
}

View File

@@ -231,7 +231,7 @@ WasmHostFunctionsImpl::cacheLedgerObj(uint256 const& objId, int32_t cacheIdx)
if (cacheIdx == 0)
{
for (cacheIdx = 0; cacheIdx < MAX_CACHE; ++cacheIdx)
if (!cache[cacheIdx])
if (!cache_[cacheIdx])
break;
}
else
@@ -242,8 +242,8 @@ WasmHostFunctionsImpl::cacheLedgerObj(uint256 const& objId, int32_t cacheIdx)
if (cacheIdx >= MAX_CACHE)
return Unexpected(HostFunctionError::SLOTS_FULL);
cache[cacheIdx] = ctx.view().read(keylet);
if (!cache[cacheIdx])
cache_[cacheIdx] = ctx_.view().read(keylet);
if (!cache_[cacheIdx])
return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND);
return cacheIdx + 1; // return 1-based index
}
@@ -251,13 +251,13 @@ WasmHostFunctionsImpl::cacheLedgerObj(uint256 const& objId, int32_t cacheIdx)
// Subsection: top level getters
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getTxField(SField const& fname)
WasmHostFunctionsImpl::getTxField(SField const& fname) const
{
return detail::getAnyFieldData(ctx.tx.peekAtPField(fname));
return detail::getAnyFieldData(ctx_.tx.peekAtPField(fname));
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getCurrentLedgerObjField(SField const& fname)
WasmHostFunctionsImpl::getCurrentLedgerObjField(SField const& fname) const
{
auto const sle = getCurrentLedgerObj();
if (!sle.has_value())
@@ -266,20 +266,20 @@ WasmHostFunctionsImpl::getCurrentLedgerObjField(SField const& fname)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getLedgerObjField(int32_t cacheIdx, SField const& fname)
WasmHostFunctionsImpl::getLedgerObjField(int32_t cacheIdx, SField const& fname) const
{
auto const normalizedIdx = normalizeCacheIndex(cacheIdx);
if (!normalizedIdx.has_value())
return Unexpected(normalizedIdx.error());
return detail::getAnyFieldData(cache[normalizedIdx.value()]->peekAtPField(fname));
return detail::getAnyFieldData(cache_[normalizedIdx.value()]->peekAtPField(fname));
}
// Subsection: nested getters
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getTxNestedField(Slice const& locator)
WasmHostFunctionsImpl::getTxNestedField(Slice const& locator) const
{
auto const r = detail::locateField(ctx.tx, locator);
auto const r = detail::locateField(ctx_.tx, locator);
if (!r)
return Unexpected(r.error());
@@ -287,7 +287,7 @@ WasmHostFunctionsImpl::getTxNestedField(Slice const& locator)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator)
WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator) const
{
auto const sle = getCurrentLedgerObj();
if (!sle.has_value())
@@ -301,13 +301,13 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator)
WasmHostFunctionsImpl::getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const
{
auto const normalizedIdx = normalizeCacheIndex(cacheIdx);
if (!normalizedIdx.has_value())
return Unexpected(normalizedIdx.error());
auto const r = detail::locateField(*cache[normalizedIdx.value()], locator);
auto const r = detail::locateField(*cache_[normalizedIdx.value()], locator);
if (!r)
return Unexpected(r.error());
@@ -317,12 +317,12 @@ WasmHostFunctionsImpl::getLedgerObjNestedField(int32_t cacheIdx, Slice const& lo
// Subsection: array length getters
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getTxArrayLen(SField const& fname)
WasmHostFunctionsImpl::getTxArrayLen(SField const& fname) const
{
if (fname.fieldType != STI_ARRAY && fname.fieldType != STI_VECTOR256)
return Unexpected(HostFunctionError::NO_ARRAY);
auto const* field = ctx.tx.peekAtPField(fname);
auto const* field = ctx_.tx.peekAtPField(fname);
if (detail::noField(field))
return Unexpected(HostFunctionError::FIELD_NOT_FOUND);
@@ -330,7 +330,7 @@ WasmHostFunctionsImpl::getTxArrayLen(SField const& fname)
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getCurrentLedgerObjArrayLen(SField const& fname)
WasmHostFunctionsImpl::getCurrentLedgerObjArrayLen(SField const& fname) const
{
if (fname.fieldType != STI_ARRAY && fname.fieldType != STI_VECTOR256)
return Unexpected(HostFunctionError::NO_ARRAY);
@@ -347,7 +347,7 @@ WasmHostFunctionsImpl::getCurrentLedgerObjArrayLen(SField const& fname)
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname)
WasmHostFunctionsImpl::getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const
{
if (fname.fieldType != STI_ARRAY && fname.fieldType != STI_VECTOR256)
return Unexpected(HostFunctionError::NO_ARRAY);
@@ -356,7 +356,7 @@ WasmHostFunctionsImpl::getLedgerObjArrayLen(int32_t cacheIdx, SField const& fnam
if (!normalizedIdx.has_value())
return Unexpected(normalizedIdx.error());
auto const* field = cache[normalizedIdx.value()]->peekAtPField(fname);
auto const* field = cache_[normalizedIdx.value()]->peekAtPField(fname);
if (detail::noField(field))
return Unexpected(HostFunctionError::FIELD_NOT_FOUND);
@@ -366,9 +366,9 @@ WasmHostFunctionsImpl::getLedgerObjArrayLen(int32_t cacheIdx, SField const& fnam
// Subsection: nested array length getters
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator)
WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator) const
{
auto const r = detail::locateField(ctx.tx, locator);
auto const r = detail::locateField(ctx_.tx, locator);
if (!r)
return Unexpected(r.error());
@@ -377,7 +377,7 @@ WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator)
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator)
WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator) const
{
auto const sle = getCurrentLedgerObj();
if (!sle.has_value())
@@ -391,13 +391,13 @@ WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator)
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator)
WasmHostFunctionsImpl::getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const
{
auto const normalizedIdx = normalizeCacheIndex(cacheIdx);
if (!normalizedIdx.has_value())
return Unexpected(normalizedIdx.error());
auto const r = detail::locateField(*cache[normalizedIdx.value()], locator);
auto const r = detail::locateField(*cache_[normalizedIdx.value()], locator);
if (!r)
return Unexpected(r.error());

View File

@@ -6,7 +6,7 @@
namespace xrpl {
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::accountKeylet(AccountID const& account)
WasmHostFunctionsImpl::accountKeylet(AccountID const& account) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -15,7 +15,7 @@ WasmHostFunctionsImpl::accountKeylet(AccountID const& account)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::ammKeylet(Asset const& issue1, Asset const& issue2)
WasmHostFunctionsImpl::ammKeylet(Asset const& issue1, Asset const& issue2) const
{
if (issue1 == issue2)
return Unexpected(HostFunctionError::INVALID_PARAMS);
@@ -29,7 +29,7 @@ WasmHostFunctionsImpl::ammKeylet(Asset const& issue1, Asset const& issue2)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::checkKeylet(AccountID const& account, std::uint32_t seq)
WasmHostFunctionsImpl::checkKeylet(AccountID const& account, std::uint32_t seq) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -39,6 +39,7 @@ WasmHostFunctionsImpl::checkKeylet(AccountID const& account, std::uint32_t seq)
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType)
const
{
if (!subject || !issuer)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -52,7 +53,7 @@ WasmHostFunctionsImpl::credentialKeylet(AccountID const& subject, AccountID cons
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::didKeylet(AccountID const& account)
WasmHostFunctionsImpl::didKeylet(AccountID const& account) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -61,7 +62,7 @@ WasmHostFunctionsImpl::didKeylet(AccountID const& account)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::delegateKeylet(AccountID const& account, AccountID const& authorize)
WasmHostFunctionsImpl::delegateKeylet(AccountID const& account, AccountID const& authorize) const
{
if (!account || !authorize)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -72,7 +73,7 @@ WasmHostFunctionsImpl::delegateKeylet(AccountID const& account, AccountID const&
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::depositPreauthKeylet(AccountID const& account, AccountID const& authorize)
WasmHostFunctionsImpl::depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const
{
if (!account || !authorize)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -83,7 +84,7 @@ WasmHostFunctionsImpl::depositPreauthKeylet(AccountID const& account, AccountID
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::escrowKeylet(AccountID const& account, std::uint32_t seq)
WasmHostFunctionsImpl::escrowKeylet(AccountID const& account, std::uint32_t seq) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -92,7 +93,7 @@ WasmHostFunctionsImpl::escrowKeylet(AccountID const& account, std::uint32_t seq)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency)
WasmHostFunctionsImpl::lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const
{
if (!account1 || !account2)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -106,7 +107,7 @@ WasmHostFunctionsImpl::lineKeylet(AccountID const& account1, AccountID const& ac
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq)
WasmHostFunctionsImpl::mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const
{
if (!issuer)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -116,7 +117,7 @@ WasmHostFunctionsImpl::mptIssuanceKeylet(AccountID const& issuer, std::uint32_t
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::mptokenKeylet(MPTID const& mptid, AccountID const& holder)
WasmHostFunctionsImpl::mptokenKeylet(MPTID const& mptid, AccountID const& holder) const
{
if (!mptid)
return Unexpected(HostFunctionError::INVALID_PARAMS);
@@ -128,7 +129,7 @@ WasmHostFunctionsImpl::mptokenKeylet(MPTID const& mptid, AccountID const& holder
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::nftOfferKeylet(AccountID const& account, std::uint32_t seq)
WasmHostFunctionsImpl::nftOfferKeylet(AccountID const& account, std::uint32_t seq) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -137,7 +138,7 @@ WasmHostFunctionsImpl::nftOfferKeylet(AccountID const& account, std::uint32_t se
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::offerKeylet(AccountID const& account, std::uint32_t seq)
WasmHostFunctionsImpl::offerKeylet(AccountID const& account, std::uint32_t seq) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -146,7 +147,7 @@ WasmHostFunctionsImpl::offerKeylet(AccountID const& account, std::uint32_t seq)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::oracleKeylet(AccountID const& account, std::uint32_t documentId)
WasmHostFunctionsImpl::oracleKeylet(AccountID const& account, std::uint32_t documentId) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -155,7 +156,7 @@ WasmHostFunctionsImpl::oracleKeylet(AccountID const& account, std::uint32_t docu
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq)
WasmHostFunctionsImpl::paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const
{
if (!account || !destination)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -166,7 +167,7 @@ WasmHostFunctionsImpl::paychanKeylet(AccountID const& account, AccountID const&
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::permissionedDomainKeylet(AccountID const& account, std::uint32_t seq)
WasmHostFunctionsImpl::permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -175,7 +176,7 @@ WasmHostFunctionsImpl::permissionedDomainKeylet(AccountID const& account, std::u
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::signersKeylet(AccountID const& account)
WasmHostFunctionsImpl::signersKeylet(AccountID const& account) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -184,7 +185,7 @@ WasmHostFunctionsImpl::signersKeylet(AccountID const& account)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::ticketKeylet(AccountID const& account, std::uint32_t seq)
WasmHostFunctionsImpl::ticketKeylet(AccountID const& account, std::uint32_t seq) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -193,7 +194,7 @@ WasmHostFunctionsImpl::ticketKeylet(AccountID const& account, std::uint32_t seq)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::vaultKeylet(AccountID const& account, std::uint32_t seq)
WasmHostFunctionsImpl::vaultKeylet(AccountID const& account, std::uint32_t seq) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);

View File

@@ -10,41 +10,41 @@ namespace xrpl {
// =========================================================
Expected<std::uint32_t, HostFunctionError>
WasmHostFunctionsImpl::getLedgerSqn()
WasmHostFunctionsImpl::getLedgerSqn() const
{
return ctx.view().seq();
return ctx_.view().seq();
}
Expected<std::uint32_t, HostFunctionError>
WasmHostFunctionsImpl::getParentLedgerTime()
WasmHostFunctionsImpl::getParentLedgerTime() const
{
return ctx.view().parentCloseTime().time_since_epoch().count();
return ctx_.view().parentCloseTime().time_since_epoch().count();
}
Expected<Hash, HostFunctionError>
WasmHostFunctionsImpl::getParentLedgerHash()
WasmHostFunctionsImpl::getParentLedgerHash() const
{
return ctx.view().header().parentHash;
return ctx_.view().header().parentHash;
}
Expected<std::uint32_t, HostFunctionError>
WasmHostFunctionsImpl::getBaseFee()
WasmHostFunctionsImpl::getBaseFee() const
{
return ctx.view().fees().base.drops();
return ctx_.view().fees().base.drops();
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::isAmendmentEnabled(uint256 const& amendmentId)
WasmHostFunctionsImpl::isAmendmentEnabled(uint256 const& amendmentId) const
{
return ctx.view().rules().enabled(amendmentId);
return ctx_.view().rules().enabled(amendmentId);
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::isAmendmentEnabled(std::string_view const& amendmentName)
WasmHostFunctionsImpl::isAmendmentEnabled(std::string_view const& amendmentName) const
{
auto const& table = ctx.app.getAmendmentTable();
auto const& table = ctx_.app.getAmendmentTable();
auto const amendment = table.find(std::string(amendmentName));
return ctx.view().rules().enabled(amendment);
return ctx_.view().rules().enabled(amendment);
}
} // namespace xrpl

View File

@@ -11,7 +11,7 @@ namespace xrpl {
// =========================================================
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId)
WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId) const
{
if (!account)
return Unexpected(HostFunctionError::INVALID_ACCOUNT);
@@ -19,7 +19,7 @@ WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId)
if (!nftId)
return Unexpected(HostFunctionError::INVALID_PARAMS);
auto obj = nft::findToken(ctx.view(), account, nftId);
auto obj = nft::findToken(ctx_.view(), account, nftId);
if (!obj)
return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND);
@@ -32,7 +32,7 @@ WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId)
}
Expected<Bytes, HostFunctionError>
WasmHostFunctionsImpl::getNFTIssuer(uint256 const& nftId)
WasmHostFunctionsImpl::getNFTIssuer(uint256 const& nftId) const
{
auto const issuer = nft::getIssuer(nftId);
if (!issuer)
@@ -42,25 +42,25 @@ WasmHostFunctionsImpl::getNFTIssuer(uint256 const& nftId)
}
Expected<std::uint32_t, HostFunctionError>
WasmHostFunctionsImpl::getNFTTaxon(uint256 const& nftId)
WasmHostFunctionsImpl::getNFTTaxon(uint256 const& nftId) const
{
return nft::toUInt32(nft::getTaxon(nftId));
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getNFTFlags(uint256 const& nftId)
WasmHostFunctionsImpl::getNFTFlags(uint256 const& nftId) const
{
return nft::getFlags(nftId);
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::getNFTTransferFee(uint256 const& nftId)
WasmHostFunctionsImpl::getNFTTransferFee(uint256 const& nftId) const
{
return nft::getTransferFee(nftId);
}
Expected<std::uint32_t, HostFunctionError>
WasmHostFunctionsImpl::getNFTSerial(uint256 const& nftId)
WasmHostFunctionsImpl::getNFTSerial(uint256 const& nftId) const
{
return nft::getSerial(nftId);
}

View File

@@ -10,7 +10,7 @@
namespace xrpl {
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::trace(std::string_view const& msg, Slice const& data, bool asHex)
WasmHostFunctionsImpl::trace(std::string_view const& msg, Slice const& data, bool asHex) const
{
if (!asHex)
{
@@ -30,28 +30,28 @@ WasmHostFunctionsImpl::trace(std::string_view const& msg, Slice const& data, boo
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::traceNum(std::string_view const& msg, int64_t data)
WasmHostFunctionsImpl::traceNum(std::string_view const& msg, int64_t data) const
{
log(msg, [data] { return data; });
return 0;
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::traceAccount(std::string_view const& msg, AccountID const& account)
WasmHostFunctionsImpl::traceAccount(std::string_view const& msg, AccountID const& account) const
{
log(msg, [&account] { return toBase58(account); });
return 0;
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::traceFloat(std::string_view const& msg, Slice const& data)
WasmHostFunctionsImpl::traceFloat(std::string_view const& msg, Slice const& data) const
{
log(msg, [&data] { return wasm_float::floatToString(data); });
return 0;
}
Expected<int32_t, HostFunctionError>
WasmHostFunctionsImpl::traceAmount(std::string_view const& msg, STAmount const& amount)
WasmHostFunctionsImpl::traceAmount(std::string_view const& msg, STAmount const& amount) const
{
log(msg, [&amount] { return amount.getFullText(); });
return 0;

View File

@@ -89,21 +89,21 @@ setCommonHostFunctions(HostFunctions* hfs, ImportVec& i)
// clang-format on
}
std::shared_ptr<ImportVec>
ImportVec
createWasmImport(HostFunctions& hfs)
{
std::shared_ptr<ImportVec> i(std::make_shared<ImportVec>());
ImportVec import;
setCommonHostFunctions(&hfs, *i);
WASM_IMPORT_FUNC2(*i, updateData, "update_data", &hfs, 1000);
setCommonHostFunctions(&hfs, import);
WASM_IMPORT_FUNC2(import, updateData, "update_data", &hfs, 1000);
return i;
return import;
}
Expected<EscrowResult, TER>
runEscrowWasm(
Bytes const& wasmCode,
std::shared_ptr<HostFunctions> const& hfs,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
int64_t gasLimit)
@@ -112,7 +112,7 @@ runEscrowWasm(
auto& vm = WasmEngine::instance();
// vm.initMaxPages(MAX_PAGES);
auto const ret = vm.run(wasmCode, funcName, params, createWasmImport(*hfs), hfs, gasLimit, hfs->getJournal());
auto const ret = vm.run(wasmCode, hfs, funcName, params, createWasmImport(hfs), gasLimit, hfs.getJournal());
// std::cout << "runEscrowWasm, mod size: " << wasmCode.size()
// << ", gasLimit: " << gasLimit << ", funcName: " << funcName;
@@ -134,7 +134,7 @@ runEscrowWasm(
NotTEC
preflightEscrowWasm(
Bytes const& wasmCode,
std::shared_ptr<HostFunctions> const& hfs,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params)
{
@@ -142,14 +142,14 @@ preflightEscrowWasm(
auto& vm = WasmEngine::instance();
// vm.initMaxPages(MAX_PAGES);
auto const ret = vm.check(wasmCode, funcName, params, createWasmImport(*hfs), hfs, hfs->getJournal());
auto const ret = vm.check(wasmCode, hfs, funcName, params, createWasmImport(hfs), hfs.getJournal());
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WasmEngine::WasmEngine() : impl(std::make_unique<WasmiEngine>())
WasmEngine::WasmEngine() : impl_(std::make_unique<WasmiEngine>())
{
}
@@ -163,39 +163,39 @@ WasmEngine::instance()
Expected<WasmResult<int32_t>, TER>
WasmEngine::run(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::shared_ptr<ImportVec> const& imports,
std::shared_ptr<HostFunctions> const& hfs,
ImportVec const& imports,
int64_t gasLimit,
beast::Journal j)
{
return impl->run(wasmCode, funcName, params, imports, hfs, gasLimit, j);
return impl_->run(wasmCode, hfs, funcName, params, imports, gasLimit, j);
}
NotTEC
WasmEngine::check(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::shared_ptr<ImportVec> const& imports,
std::shared_ptr<HostFunctions> const& hfs,
ImportVec const& imports,
beast::Journal j)
{
return impl->check(wasmCode, funcName, params, imports, hfs, j);
return impl_->check(wasmCode, hfs, funcName, params, imports, j);
}
void*
WasmEngine::newTrap(std::string const& msg)
{
return impl->newTrap(msg);
return impl_->newTrap(msg);
}
// LCOV_EXCL_START
beast::Journal
WasmEngine::getJournal() const
{
return impl->getJournal();
return impl_->getJournal();
}
// LCOV_EXCL_STOP

View File

@@ -232,7 +232,7 @@ ModuleWrapper::ModuleWrapper(
StorePtr& s,
Bytes const& wasmBin,
bool instantiate,
std::shared_ptr<ImportVec> const& imports,
ImportVec const& imports,
beast::Journal j)
: module_(init(s, wasmBin, j)), j_(j)
{
@@ -319,14 +319,14 @@ makeImpReturn(WasmImportFunc const& imp)
}
WasmExternVec
ModuleWrapper::buildImports(StorePtr& s, std::shared_ptr<ImportVec> const& imports)
ModuleWrapper::buildImports(StorePtr& s, ImportVec const& imports)
{
WasmImporttypeVec importTypes;
wasm_module_imports(module_.get(), &importTypes.vec_);
if (!importTypes.vec_.size)
return {};
if (!imports)
if (imports.empty())
throw std::runtime_error("Missing imports");
WasmExternVec wimports(importTypes.vec_.size);
@@ -350,7 +350,7 @@ ModuleWrapper::buildImports(StorePtr& s, std::shared_ptr<ImportVec> const& impor
// continue;
bool impSet = false;
for (auto const& obj : *imports)
for (auto const& obj : imports)
{
auto const& imp = obj.second;
if (imp.name != fieldName)
@@ -500,7 +500,7 @@ WasmiEngine::WasmiEngine() : engine_(init()), store_(nullptr, &wasm_store_delete
}
int
WasmiEngine::addModule(Bytes const& wasmCode, bool instantiate, int64_t gas)
WasmiEngine::addModule(Bytes const& wasmCode, bool instantiate, ImportVec const& imports, int64_t gas)
{
moduleWrap_.reset();
store_.reset(); // to free the memory before creating new store
@@ -518,7 +518,7 @@ WasmiEngine::addModule(Bytes const& wasmCode, bool instantiate, int64_t gas)
// LCOV_EXCL_STOP
}
moduleWrap_ = std::make_unique<ModuleWrapper>(store_, wasmCode, instantiate, imports_, j_);
moduleWrap_ = std::make_unique<ModuleWrapper>(store_, wasmCode, instantiate, imports, j_);
if (!moduleWrap_)
throw std::runtime_error("can't create module wrapper"); // LCOV_EXCL_LINE
@@ -533,7 +533,7 @@ WasmiEngine::addModule(Bytes const& wasmCode, bool instantiate, int64_t gas)
// }
FuncInfo
WasmiEngine::getFunc(std::string_view funcName)
WasmiEngine::getFunc(std::string_view funcName) const
{
return moduleWrap_->getFunc(funcName);
}
@@ -554,7 +554,10 @@ WasmiEngine::convertParams(std::vector<WasmParam> const& params)
case WT_I64:
v.push_back(WASM_I64_VAL(p.of.i64));
break;
// LCOV_EXCL_STOP
// LCOV_EXCL_STOP
#ifdef WASM_PERF_TESTS
case WT_U8V: {
auto mem = getMem();
if (!mem.s)
@@ -566,6 +569,9 @@ WasmiEngine::convertParams(std::vector<WasmParam> const& params)
v.push_back(WASM_I32_VAL(sz));
}
break;
#endif
// LCOV_EXCL_START
default:
throw std::runtime_error("unknown parameter type: " + std::to_string(p.type));
@@ -693,6 +699,9 @@ WasmiEngine::call(FuncInfo const& f, std::vector<wasm_val_t>& in, std::int64_t p
return call<NR>(f, in, std::forward<Types>(args)...);
}
#ifdef WASM_PERF_TESTS
// passing vector only for tests
template <int NR, class... Types>
WasmiResult
WasmiEngine::call(FuncInfo const& f, std::vector<wasm_val_t>& in, uint8_t const* d, int32_t sz, Types&&... args)
@@ -709,6 +718,8 @@ WasmiEngine::call(FuncInfo const& f, std::vector<wasm_val_t>& in, uint8_t const*
return call<NR>(f, in, std::forward<Types>(args)...);
}
#endif
template <int NR, class... Types>
WasmiResult
WasmiEngine::call(FuncInfo const& f, std::vector<wasm_val_t>& in, Bytes const& p, Types&&... args)
@@ -729,26 +740,19 @@ checkImports(ImportVec const& imports, HostFunctions* hfs)
Expected<WasmResult<int32_t>, TER>
WasmiEngine::run(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::shared_ptr<ImportVec> const& imports,
std::shared_ptr<HostFunctions> const& hfs,
ImportVec const& imports,
int64_t gas,
beast::Journal j)
{
j_ = j;
if (!wasmCode.empty())
{ // save values for reuse
imports_ = imports;
hfs_ = hfs;
}
try
{
if (imports_)
checkImports(*imports_, hfs.get());
return runHlp(wasmCode, funcName, params, gas);
checkImports(imports, &hfs);
return runHlp(wasmCode, hfs, funcName, params, imports, gas);
}
catch (std::exception const& e)
{
@@ -764,22 +768,35 @@ WasmiEngine::run(
}
Expected<WasmResult<int32_t>, TER>
WasmiEngine::runHlp(Bytes const& wasmCode, std::string_view funcName, std::vector<WasmParam> const& params, int64_t gas)
WasmiEngine::runHlp(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
ImportVec const& imports,
int64_t gas)
{
// currently only 1 module support, possible parallel UT run
std::lock_guard<decltype(m_)> lg(m_);
// Create and instantiate the module.
#ifndef WASM_PERF_TESTS
if (wasmCode.empty())
throw std::runtime_error("empty module");
if (!hfs.checkSelf())
throw std::runtime_error("hfs isn't clean");
#else
// re-using module only for perf tests
if (!wasmCode.empty())
#endif
{
[[maybe_unused]] int const m = addModule(wasmCode, true, gas);
// Create and instantiate the module.
[[maybe_unused]] int const m = addModule(wasmCode, true, imports, gas);
}
if (!moduleWrap_ || !moduleWrap_->instanceWrap_)
throw std::runtime_error("no instance"); // LCOV_EXCL_LINE
if (hfs_)
hfs_->setRT(&getRT());
hfs.setRT(&getRT());
// Call main
auto const f = getFunc(!funcName.empty() ? funcName : "_start");
@@ -820,25 +837,18 @@ WasmiEngine::runHlp(Bytes const& wasmCode, std::string_view funcName, std::vecto
NotTEC
WasmiEngine::check(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::shared_ptr<ImportVec> const& imports,
std::shared_ptr<HostFunctions> const& hfs,
ImportVec const& imports,
beast::Journal j)
{
j_ = j;
if (!wasmCode.empty())
{
imports_ = imports;
hfs_ = hfs;
}
try
{
if (imports_)
checkImports(*imports_, hfs_.get());
return checkHlp(wasmCode, funcName, params);
checkImports(imports, &hfs);
return checkHlp(wasmCode, hfs, funcName, params, imports);
}
catch (std::exception const& e)
{
@@ -855,7 +865,12 @@ WasmiEngine::check(
}
NotTEC
WasmiEngine::checkHlp(Bytes const& wasmCode, std::string_view funcName, std::vector<WasmParam> const& params)
WasmiEngine::checkHlp(
Bytes const& wasmCode,
HostFunctions& hfs,
std::string_view funcName,
std::vector<WasmParam> const& params,
ImportVec const& imports)
{
// currently only 1 module support, possible parallel UT run
std::lock_guard<decltype(m_)> lg(m_);
@@ -864,7 +879,7 @@ WasmiEngine::checkHlp(Bytes const& wasmCode, std::string_view funcName, std::vec
if (wasmCode.empty())
throw std::runtime_error("empty nodule");
int const m = addModule(wasmCode, false, -1);
int const m = addModule(wasmCode, false, imports, -1);
if ((m < 0) || !moduleWrap_)
throw std::runtime_error("no module"); // LCOV_EXCL_LINE
@@ -881,7 +896,7 @@ WasmiEngine::checkHlp(Bytes const& wasmCode, std::string_view funcName, std::vec
// LCOV_EXCL_START
std::int64_t
WasmiEngine::getGas()
WasmiEngine::getGas() const
{
return moduleWrap_ ? moduleWrap_->getGas() : -1;
}
@@ -894,7 +909,7 @@ WasmiEngine::getMem() const
}
InstanceWrapper const&
WasmiEngine::getRT(int m, int i)
WasmiEngine::getRT(int m, int i) const
{
if (!moduleWrap_)
throw std::runtime_error("no module");
@@ -904,6 +919,9 @@ WasmiEngine::getRT(int m, int i)
int32_t
WasmiEngine::allocate(int32_t sz)
{
#ifndef WASM_PERF_TESTS
throw std::runtime_error("allocate not implemented"); // LCOV_EXCL_LINE
#else
if (sz <= 0)
throw std::runtime_error("can't allocate memory, " + std::to_string(sz) + " bytes");
@@ -918,6 +936,7 @@ WasmiEngine::allocate(int32_t sz)
throw std::runtime_error("invalid memory allocation, " + std::to_string(sz) + " bytes");
return p;
#endif
}
wasm_trap_t*