mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-23 23:20:33 +00:00
Merge branch 'ripple/se/wasmi-tests' into ripple/se/fees
This commit is contained in:
@@ -252,10 +252,7 @@ constexpr std::uint8_t kVaultMaximumIouScale = 18;
|
||||
constexpr std::uint8_t kMaxAssetCheckDepth = 5;
|
||||
|
||||
/** Maximum length of a Data field in Escrow object that can be updated by WASM code. */
|
||||
std::size_t constexpr maxWasmDataLength = 4 * 1024; // 4KB
|
||||
|
||||
/** Maximum length of parameters passed from WASM code to host functions. */
|
||||
std::size_t constexpr maxWasmParamLength = 1024; // 1KB
|
||||
constexpr std::size_t kMaxWasmDataLength = 1 * 1024; // 1KB
|
||||
|
||||
/** A ledger index. */
|
||||
using LedgerIndex = std::uint32_t;
|
||||
|
||||
@@ -8,43 +8,13 @@
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/tx/wasm/ParamsHelper.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
enum class HostFunctionError : int32_t {
|
||||
INTERNAL = -1,
|
||||
FieldNotFound = -2,
|
||||
BufferTooSmall = -3,
|
||||
NoArray = -4,
|
||||
NotLeafField = -5,
|
||||
LocatorMalformed = -6,
|
||||
SlotOutRange = -7,
|
||||
SlotsFull = -8,
|
||||
EmptySlot = -9,
|
||||
LedgerObjNotFound = -10,
|
||||
DECODING = -11,
|
||||
DataFieldTooLarge = -12,
|
||||
PointerOutOfBounds = -13,
|
||||
NoMemExported = -14,
|
||||
InvalidParams = -15,
|
||||
InvalidAccount = -16,
|
||||
InvalidField = -17,
|
||||
IndexOutOfBounds = -18,
|
||||
FloatInputMalformed = -19,
|
||||
FloatComputationError = -20,
|
||||
NoRuntime = -21,
|
||||
OutOfGas = -22,
|
||||
};
|
||||
|
||||
using FloatPair = std::pair<int64_t, int32_t>;
|
||||
|
||||
inline int32_t
|
||||
HfErrorToInt(HostFunctionError e)
|
||||
{
|
||||
return static_cast<int32_t>(e);
|
||||
}
|
||||
|
||||
namespace wasm_float {
|
||||
|
||||
std::string
|
||||
@@ -95,32 +65,45 @@ floatPowerImpl(Slice const& x, int32_t n, int32_t mode);
|
||||
} // namespace wasm_float
|
||||
|
||||
// Intended to work only through wasm runtime. Don't call them directly, except with unit tests
|
||||
struct HostFunctions
|
||||
class HostFunctions
|
||||
{
|
||||
beast::Journal j;
|
||||
protected:
|
||||
RTOptRef rt_;
|
||||
beast::Journal j_;
|
||||
|
||||
HostFunctions(beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : j(j)
|
||||
public:
|
||||
HostFunctions(beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : j_(j)
|
||||
{
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
virtual void
|
||||
setRT(void*)
|
||||
void
|
||||
setRT(WasmRuntimeWrapper& rt)
|
||||
{
|
||||
rt_ = rt;
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual void*
|
||||
void
|
||||
resetRT()
|
||||
{
|
||||
rt_ = std::nullopt;
|
||||
}
|
||||
|
||||
[[nodiscard]] WasmRuntimeWrapper&
|
||||
getRT() const
|
||||
{
|
||||
return nullptr;
|
||||
if (!rt_)
|
||||
Throw<std::logic_error>("Wasm runtime not set");
|
||||
return rt_->get();
|
||||
}
|
||||
|
||||
[[nodiscard]] beast::Journal
|
||||
getJournal() const
|
||||
{
|
||||
return j;
|
||||
return j_;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
|
||||
[[nodiscard]] virtual bool
|
||||
checkSelf() const
|
||||
{
|
||||
@@ -130,402 +113,404 @@ struct HostFunctions
|
||||
virtual Expected<std::uint32_t, HostFunctionError>
|
||||
getLedgerSqn() const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<std::uint32_t, HostFunctionError>
|
||||
getParentLedgerTime() const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Hash, HostFunctionError>
|
||||
getParentLedgerHash() const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<uint32_t, HostFunctionError>
|
||||
getBaseFee() const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
isAmendmentEnabled(uint256 const& amendmentId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
isAmendmentEnabled(std::string_view const& amendmentName) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
cacheLedgerObj(uint256 const& objId, int32_t cacheIdx)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getTxField(SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getCurrentLedgerObjField(SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getLedgerObjField(int32_t cacheIdx, SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getTxNestedField(Slice const& locator) const
|
||||
getTxNestedField(FieldLocator const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getCurrentLedgerObjNestedField(Slice const& locator) const
|
||||
getCurrentLedgerObjNestedField(FieldLocator const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const
|
||||
getLedgerObjNestedField(int32_t cacheIdx, FieldLocator const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getTxArrayLen(SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getCurrentLedgerObjArrayLen(SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getTxNestedArrayLen(Slice const& locator) const
|
||||
getTxNestedArrayLen(FieldLocator const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const
|
||||
getCurrentLedgerObjNestedArrayLen(FieldLocator const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const
|
||||
getLedgerObjNestedArrayLen(int32_t cacheIdx, FieldLocator const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
updateData(Slice const& data)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Hash, HostFunctionError>
|
||||
computeSha512HalfHash(Slice const& data) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
accountKeylet(AccountID const& account) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
ammKeylet(Asset const& issue1, Asset const& issue2) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
checkKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType)
|
||||
const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
didKeylet(AccountID const& account) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
delegateKeylet(AccountID const& account, AccountID const& authorize) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
escrowKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
nftOfferKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
offerKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
oracleKeylet(AccountID const& account, std::uint32_t docId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
signersKeylet(AccountID const& account) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
ticketKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
vaultKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getNFT(AccountID const& account, uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getNFTIssuer(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<std::uint32_t, HostFunctionError>
|
||||
getNFTTaxon(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getNFTFlags(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getNFTTransferFee(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<std::uint32_t, HostFunctionError>
|
||||
getNFTSerial(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
trace(std::string_view const& msg, Slice const& data, bool asHex) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
traceNum(std::string_view const& msg, int64_t data) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
traceAccount(std::string_view const& msg, AccountID const& account) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
traceFloat(std::string_view const& msg, Slice const& data) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
traceAmount(std::string_view const& msg, STAmount const& amount) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromInt(int64_t x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromUint(uint64_t x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromSTAmount(STAmount const& x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromSTNumber(STNumber const& x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int64_t, HostFunctionError>
|
||||
floatToInt(Slice const& x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<FloatPair, HostFunctionError>
|
||||
floatToMantExp(Slice const& x) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromMantExp(int64_t mantissa, int32_t exponent, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
floatCompare(Slice const& x, Slice const& y) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatAdd(Slice const& x, Slice const& y, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatDivide(Slice const& x, Slice const& y, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatRoot(Slice const& x, int32_t n, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatPower(Slice const& x, int32_t n, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
return Unexpected(HostFunctionError::Internal);
|
||||
}
|
||||
|
||||
virtual ~HostFunctions() = default;
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
|
||||
using HFRef = std::reference_wrapper<HostFunctions>;
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -18,8 +18,7 @@ class WasmHostFunctionsImpl : public HostFunctions
|
||||
|
||||
std::optional<Bytes> data_;
|
||||
|
||||
void* rt_ = nullptr;
|
||||
|
||||
public:
|
||||
Expected<std::shared_ptr<SLE const>, HostFunctionError>
|
||||
getCurrentLedgerObj() const
|
||||
{
|
||||
@@ -65,18 +64,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
setRT(void* rt) override
|
||||
{
|
||||
rt_ = rt;
|
||||
}
|
||||
|
||||
void*
|
||||
getRT() const override
|
||||
{
|
||||
return rt_;
|
||||
}
|
||||
|
||||
bool
|
||||
checkSelf() const override
|
||||
{
|
||||
@@ -121,13 +108,13 @@ public:
|
||||
getLedgerObjField(int32_t cacheIdx, SField const& fname) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getTxNestedField(Slice const& locator) const override;
|
||||
getTxNestedField(FieldLocator const& locator) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getCurrentLedgerObjNestedField(Slice const& locator) const override;
|
||||
getCurrentLedgerObjNestedField(FieldLocator const& locator) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const override;
|
||||
getLedgerObjNestedField(int32_t cacheIdx, FieldLocator const& locator) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getTxArrayLen(SField const& fname) const override;
|
||||
@@ -139,13 +126,13 @@ public:
|
||||
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getTxNestedArrayLen(Slice const& locator) const override;
|
||||
getTxNestedArrayLen(FieldLocator const& locator) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const override;
|
||||
getCurrentLedgerObjNestedArrayLen(FieldLocator const& locator) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const override;
|
||||
getLedgerObjNestedArrayLen(int32_t cacheIdx, FieldLocator const& locator) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
updateData(Slice const& data) override;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/wasm/ParamsHelper.h>
|
||||
#include <xrpl/tx/wasm/WasmImportsHelper.h>
|
||||
|
||||
#include <wasm.h>
|
||||
|
||||
@@ -8,110 +8,86 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
#define WASM_CB_PARAMS_LIST void *env, wasm_val_vec_t const *params, wasm_val_vec_t *results
|
||||
#define WASM_SECONDARY_CB_PARAMS_LIST \
|
||||
HostFunctions &hf, wasm_val_vec_t const *params, wasm_val_vec_t *results
|
||||
|
||||
wasm_trap_t* HostFuncMain_wrap(WASM_CB_PARAMS_LIST);
|
||||
|
||||
using getLedgerSqn_proto = int32_t(uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerSqn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getLedgerSqn_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getParentLedgerTime_proto = int32_t(uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getParentLedgerTime_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getParentLedgerTime_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getParentLedgerHash_proto = int32_t(uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getParentLedgerHash_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getParentLedgerHash_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getBaseFee_proto = int32_t(uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getBaseFee_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getBaseFee_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using isAmendmentEnabled_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
isAmendmentEnabled_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* isAmendmentEnabled_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using cacheLedgerObj_proto = int32_t(uint8_t const*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
cacheLedgerObj_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* cacheLedgerObj_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getTxField_proto = int32_t(int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getTxField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getTxField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getCurrentLedgerObjField_proto = int32_t(int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getCurrentLedgerObjField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getCurrentLedgerObjField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getLedgerObjField_proto = int32_t(int32_t, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerObjField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getLedgerObjField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getTxNestedField_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getTxNestedField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getTxNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getCurrentLedgerObjNestedField_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getCurrentLedgerObjNestedField_wrap(
|
||||
void* env,
|
||||
wasm_val_vec_t const* params,
|
||||
wasm_val_vec_t* results);
|
||||
wasm_trap_t* getCurrentLedgerObjNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getLedgerObjNestedField_proto = int32_t(int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerObjNestedField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getLedgerObjNestedField_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getTxArrayLen_proto = int32_t(int32_t);
|
||||
wasm_trap_t*
|
||||
getTxArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getTxArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getCurrentLedgerObjArrayLen_proto = int32_t(int32_t);
|
||||
wasm_trap_t*
|
||||
getCurrentLedgerObjArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getCurrentLedgerObjArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getLedgerObjArrayLen_proto = int32_t(int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerObjArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getLedgerObjArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getTxNestedArrayLen_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getTxNestedArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getTxNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getCurrentLedgerObjNestedArrayLen_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getCurrentLedgerObjNestedArrayLen_wrap(
|
||||
void* env,
|
||||
wasm_val_vec_t const* params,
|
||||
wasm_val_vec_t* results);
|
||||
wasm_trap_t* getCurrentLedgerObjNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getLedgerObjNestedArrayLen_proto = int32_t(int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerObjNestedArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getLedgerObjNestedArrayLen_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using updateData_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
updateData_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* updateData_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using checkSignature_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
checkSignature_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* checkSignature_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using computeSha512HalfHash_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
computeSha512HalfHash_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* computeSha512HalfHash_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using accountKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
accountKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* accountKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using ammKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
ammKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* ammKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using checkKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
checkKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* checkKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using credentialKeylet_proto = int32_t(
|
||||
uint8_t const*,
|
||||
@@ -122,27 +98,22 @@ using credentialKeylet_proto = int32_t(
|
||||
int32_t,
|
||||
uint8_t*,
|
||||
int32_t);
|
||||
wasm_trap_t*
|
||||
credentialKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* credentialKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using delegateKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
delegateKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* delegateKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using depositPreauthKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
depositPreauthKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* depositPreauthKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using didKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
didKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* didKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using escrowKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
escrowKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* escrowKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using lineKeylet_proto = int32_t(
|
||||
uint8_t const*,
|
||||
@@ -153,33 +124,27 @@ using lineKeylet_proto = int32_t(
|
||||
int32_t,
|
||||
uint8_t*,
|
||||
int32_t);
|
||||
wasm_trap_t*
|
||||
lineKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* lineKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using mptIssuanceKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
mptIssuanceKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* mptIssuanceKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using mptokenKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
mptokenKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* mptokenKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using nftOfferKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
nftOfferKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* nftOfferKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using offerKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
offerKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* offerKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using oracleKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
oracleKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* oracleKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using paychanKeylet_proto = int32_t(
|
||||
uint8_t const*,
|
||||
@@ -190,130 +155,100 @@ using paychanKeylet_proto = int32_t(
|
||||
int32_t,
|
||||
uint8_t*,
|
||||
int32_t);
|
||||
wasm_trap_t*
|
||||
paychanKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* paychanKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using permissionedDomainKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
permissionedDomainKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* permissionedDomainKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using signersKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
signersKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* signersKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using ticketKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
ticketKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* ticketKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using vaultKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
vaultKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* vaultKeylet_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getNFT_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getNFT_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getNFTIssuer_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTIssuer_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getNFTIssuer_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getNFTTaxon_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTTaxon_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getNFTTaxon_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getNFTFlags_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTFlags_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getNFTFlags_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getNFTTransferFee_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTTransferFee_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getNFTTransferFee_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using getNFTSerial_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTSerial_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* getNFTSerial_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using trace_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* trace_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using traceNum_proto = int32_t(uint8_t const*, int32_t, int64_t);
|
||||
wasm_trap_t*
|
||||
traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* traceNum_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using traceAccount_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
traceAccount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* traceAccount_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using traceFloat_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
traceFloat_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* traceFloat_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using traceAmount_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
traceAmount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* traceAmount_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatFromInt_proto = int32_t(int64_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromInt_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatFromInt_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatFromUint_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromUint_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatFromUint_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatFromSTAmount_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromSTAmount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatFromSTAmount_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatFromSTNumber_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromSTNumber_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatFromSTNumber_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatToInt_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatToInt_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatToInt_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatToMantExp_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
floatToMantExp_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatToMantExp_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatFromMantExp_proto = int32_t(int64_t, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromMantExp_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatFromMantExp_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatCompare_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
floatCompare_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatCompare_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatAdd_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatAdd_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatAdd_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatSubtract_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatSubtract_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatSubtract_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatMultiply_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatMultiply_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatMultiply_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatDivide_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatDivide_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatDivide_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatRoot_proto = int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatRoot_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatRoot_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
using floatPower_proto = int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatPower_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
wasm_trap_t* floatPower_wrap(WASM_SECONDARY_CB_PARAMS_LIST);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,245 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
|
||||
#include <boost/function_types/function_arity.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
#include <bit>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace bft = boost::function_types;
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename>
|
||||
inline constexpr bool wasmDependentFalse = false;
|
||||
|
||||
using Bytes = std::vector<std::uint8_t>;
|
||||
using Hash = xrpl::uint256;
|
||||
|
||||
struct Wmem
|
||||
{
|
||||
std::uint8_t* p = nullptr;
|
||||
std::size_t s = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct WasmResult
|
||||
{
|
||||
T result;
|
||||
int64_t cost;
|
||||
};
|
||||
using EscrowResult = WasmResult<int32_t>;
|
||||
|
||||
struct WasmRuntimeWrapper
|
||||
{
|
||||
virtual ~WasmRuntimeWrapper() = default;
|
||||
|
||||
virtual Wmem
|
||||
getMem() = 0;
|
||||
|
||||
virtual std::int64_t
|
||||
getGas() = 0;
|
||||
|
||||
virtual std::int64_t
|
||||
setGas(std::int64_t gas) = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum class WasmTypes { WtI32, WtI64 };
|
||||
|
||||
struct WasmImportFunc
|
||||
{
|
||||
std::string_view name;
|
||||
std::optional<WasmTypes> result;
|
||||
std::vector<WasmTypes> params;
|
||||
// void* udata = nullptr;
|
||||
// wasm_func_callback_with_env_t
|
||||
void* wrap = nullptr;
|
||||
uint32_t gas = 0;
|
||||
};
|
||||
|
||||
using WasmUserData = std::pair<void*, WasmImportFunc>;
|
||||
using ImportVec = std::unordered_map<std::string_view, WasmUserData>;
|
||||
|
||||
#define WASM_IMPORT_FUNC(v, f, ...) \
|
||||
WasmImpFunc<f##_proto>(v, #f, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
|
||||
|
||||
// n - string literal name, must have static lifetime
|
||||
#define WASM_IMPORT_FUNC2(v, f, n, ...) \
|
||||
WasmImpFunc<f##_proto>(v, n, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
|
||||
|
||||
template <int N, int C, typename Mpl>
|
||||
void
|
||||
WasmImpArgs(WasmImportFunc& e)
|
||||
{
|
||||
if constexpr (N < C)
|
||||
{
|
||||
using at = typename boost::mpl::at_c<Mpl, N>::type;
|
||||
if constexpr (std::is_pointer_v<at>)
|
||||
{
|
||||
e.params.push_back(WasmTypes::WtI32);
|
||||
}
|
||||
else if constexpr (std::is_same_v<at, std::int32_t>)
|
||||
{
|
||||
e.params.push_back(WasmTypes::WtI32);
|
||||
}
|
||||
else if constexpr (std::is_same_v<at, std::int64_t>)
|
||||
{
|
||||
e.params.push_back(WasmTypes::WtI64);
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(std::is_pointer_v<at>, "Unsupported argument type");
|
||||
}
|
||||
|
||||
return WasmImpArgs<N + 1, C, Mpl>(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
template <typename Rt>
|
||||
void
|
||||
WasmImpRet(WasmImportFunc& e)
|
||||
{
|
||||
if constexpr (std::is_pointer_v<Rt>)
|
||||
{
|
||||
e.result = WasmTypes::WtI32;
|
||||
}
|
||||
else if constexpr (std::is_same_v<Rt, std::int32_t>)
|
||||
{
|
||||
e.result = WasmTypes::WtI32;
|
||||
}
|
||||
else if constexpr (std::is_same_v<Rt, std::int64_t>)
|
||||
{
|
||||
e.result = WasmTypes::WtI64;
|
||||
}
|
||||
else if constexpr (std::is_void_v<Rt>)
|
||||
{
|
||||
e.result.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(wasmDependentFalse<Rt>, "Unsupported return type");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void
|
||||
WasmImpFuncHelper(WasmImportFunc& e)
|
||||
{
|
||||
using rt = typename bft::result_type<F>::type;
|
||||
using pt = typename bft::parameter_types<F>::type;
|
||||
// typename boost::mpl::at_c<mpl, N>::type
|
||||
|
||||
WasmImpRet<rt>(e);
|
||||
WasmImpArgs<0, bft::function_arity<F>::value, pt>(e);
|
||||
// WasmImpWrap(e, std::forward<F>(f));
|
||||
}
|
||||
|
||||
// imp_name - string literal, must have static lifetime
|
||||
template <typename F>
|
||||
void
|
||||
WasmImpFunc(
|
||||
ImportVec& v,
|
||||
std::string_view impName,
|
||||
void* fWrap,
|
||||
void* data = nullptr,
|
||||
uint32_t gas = 0)
|
||||
{
|
||||
WasmImportFunc e;
|
||||
e.name = impName;
|
||||
e.wrap = fWrap;
|
||||
e.gas = gas;
|
||||
WasmImpFuncHelper<F>(e);
|
||||
v.emplace(impName, std::make_pair(data, std::move(e)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct WasmParam
|
||||
{
|
||||
// We are not supporting float/double
|
||||
|
||||
WasmTypes type = WasmTypes::WtI32;
|
||||
union
|
||||
{
|
||||
std::int32_t i32;
|
||||
std::int64_t i64 = 0;
|
||||
} of;
|
||||
};
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::int32_t p, Types&&... args)
|
||||
{
|
||||
v.push_back({.type = WasmTypes::WtI32, .of = {.i32 = p}});
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
|
||||
{
|
||||
v.push_back({.type = WasmTypes::WtI64, .of = {.i64 = p}});
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline std::vector<WasmParam>
|
||||
wasmParams(Types&&... args)
|
||||
{
|
||||
std::vector<WasmParam> v;
|
||||
v.reserve(sizeof...(args));
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename T, size_t Size = sizeof(T)>
|
||||
constexpr T
|
||||
adjustWasmEndianessHlp(T x)
|
||||
{
|
||||
static_assert(std::is_integral_v<T>, "Only integral types");
|
||||
if constexpr (Size > 1)
|
||||
{
|
||||
using U = std::make_unsigned_t<T>;
|
||||
U u = static_cast<U>(x);
|
||||
U const low = (u & 0xFF) << ((Size - 1) << 3);
|
||||
u = adjustWasmEndianessHlp<U, Size - 1>(u >> 8);
|
||||
return static_cast<T>(low | u);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename T, size_t Size = sizeof(T)>
|
||||
constexpr T
|
||||
adjustWasmEndianess(T x)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
static_assert(std::is_integral_v<T>, "Only integral types");
|
||||
if constexpr (std::endian::native == std::endian::big)
|
||||
{
|
||||
return adjustWasmEndianessHlp(x);
|
||||
}
|
||||
return x;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
211
include/xrpl/tx/wasm/WasmCommon.h
Normal file
211
include/xrpl/tx/wasm/WasmCommon.h
Normal file
@@ -0,0 +1,211 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
using Bytes = std::vector<std::uint8_t>;
|
||||
using Hash = xrpl::uint256;
|
||||
using FloatPair = std::pair<int64_t, int32_t>;
|
||||
|
||||
enum class HostFunctionError : int32_t {
|
||||
Internal = -1,
|
||||
FieldNotFound = -2,
|
||||
BufferTooSmall = -3,
|
||||
NoArray = -4,
|
||||
NotLeafField = -5,
|
||||
LocatorMalformed = -6,
|
||||
SlotOutRange = -7,
|
||||
SlotsFull = -8,
|
||||
EmptySlot = -9,
|
||||
LedgerObjNotFound = -10,
|
||||
Decoding = -11,
|
||||
DataFieldTooLarge = -12,
|
||||
PointerOutOfBounds = -13,
|
||||
NoMemExported = -14,
|
||||
InvalidParams = -15,
|
||||
InvalidAccount = -16,
|
||||
InvalidField = -17,
|
||||
IndexOutOfBounds = -18,
|
||||
FloatInputMalformed = -19,
|
||||
FloatComputationError = -20,
|
||||
NoRuntime = -21,
|
||||
OutOfGas = -22,
|
||||
OutOfTransferLimit = -23,
|
||||
};
|
||||
|
||||
enum class WasmTypes { WtI32, WtI64 };
|
||||
|
||||
struct Wmem
|
||||
{
|
||||
std::uint8_t* p = nullptr;
|
||||
std::size_t s = 0;
|
||||
|
||||
Wmem() = default;
|
||||
Wmem(void* ptr, std::size_t size) : p(reinterpret_cast<std::uint8_t*>(ptr)), s(size)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct WasmResult
|
||||
{
|
||||
T result;
|
||||
int64_t cost;
|
||||
};
|
||||
using EscrowResult = WasmResult<int32_t>;
|
||||
|
||||
class FieldLocator
|
||||
{
|
||||
int32_t const* ptr_ = nullptr;
|
||||
uint32_t size_ = 0;
|
||||
std::vector<int32_t> buf_;
|
||||
|
||||
public:
|
||||
FieldLocator(std::vector<int32_t>&& buf)
|
||||
: ptr_(&buf[0]), size_(buf.size()), buf_(std::move(buf))
|
||||
{
|
||||
}
|
||||
|
||||
FieldLocator(int32_t const* ptr, uint32_t const size) : ptr_(ptr), size_(size)
|
||||
{
|
||||
}
|
||||
|
||||
FieldLocator(FieldLocator const&) = delete;
|
||||
FieldLocator&
|
||||
operator=(FieldLocator const&) = delete;
|
||||
FieldLocator(FieldLocator&&) = default;
|
||||
FieldLocator&
|
||||
operator=(FieldLocator&&) = default;
|
||||
|
||||
int32_t
|
||||
operator[](unsigned i) const
|
||||
{
|
||||
if (i >= size_)
|
||||
Throw<std::runtime_error>("index out of bounds");
|
||||
return ptr_[i];
|
||||
}
|
||||
|
||||
[[nodiscard]] uint32_t
|
||||
size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
[[nodiscard]] int32_t const*
|
||||
data() const
|
||||
{
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
empty() const
|
||||
{
|
||||
return size_ == 0;
|
||||
}
|
||||
};
|
||||
|
||||
class WasmRuntimeWrapper
|
||||
{
|
||||
public:
|
||||
virtual ~WasmRuntimeWrapper() = default;
|
||||
|
||||
virtual Wmem
|
||||
getMem() = 0;
|
||||
|
||||
virtual std::int64_t
|
||||
getGas() = 0;
|
||||
|
||||
virtual std::int64_t
|
||||
setGas(std::int64_t gas) = 0;
|
||||
};
|
||||
using RTOptRef = std::optional<std::reference_wrapper<WasmRuntimeWrapper>>;
|
||||
|
||||
struct WasmParam
|
||||
{
|
||||
// We are not supporting float/double
|
||||
|
||||
WasmTypes type = WasmTypes::WtI32;
|
||||
union
|
||||
{
|
||||
std::int32_t i32;
|
||||
std::int64_t i64 = 0;
|
||||
} of;
|
||||
};
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::int32_t p, Types&&... args)
|
||||
{
|
||||
v.push_back({.type = WasmTypes::WtI32, .of = {.i32 = p}});
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
|
||||
{
|
||||
v.push_back({.type = WasmTypes::WtI64, .of = {.i64 = p}});
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline std::vector<WasmParam>
|
||||
wasmParams(Types&&... args)
|
||||
{
|
||||
std::vector<WasmParam> v;
|
||||
v.reserve(sizeof...(args));
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename T, size_t Size = sizeof(T)>
|
||||
constexpr T
|
||||
adjustWasmEndianessHlp(T x)
|
||||
{
|
||||
static_assert(std::is_integral_v<T>, "Only integral types");
|
||||
if constexpr (Size > 1)
|
||||
{
|
||||
using U = std::make_unsigned_t<T>;
|
||||
U u = static_cast<U>(x);
|
||||
U const low = (u & 0xFF) << ((Size - 1) << 3);
|
||||
u = adjustWasmEndianessHlp<U, Size - 1>(u >> 8);
|
||||
return static_cast<T>(low | u);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename T, size_t Size = sizeof(T)>
|
||||
constexpr T
|
||||
adjustWasmEndianess(T x)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
static_assert(std::is_integral_v<T>, "Only integral types");
|
||||
if constexpr (std::endian::native == std::endian::big)
|
||||
{
|
||||
return adjustWasmEndianessHlp(x);
|
||||
}
|
||||
return x;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
constexpr int32_t
|
||||
hfErrorToInt(HostFunctionError e)
|
||||
{
|
||||
return static_cast<int32_t>(e);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
128
include/xrpl/tx/wasm/WasmImportsHelper.h
Normal file
128
include/xrpl/tx/wasm/WasmImportsHelper.h
Normal file
@@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/tx/wasm/HostFunc.h>
|
||||
|
||||
#include <boost/function_types/function_arity.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
#include <wasm.h>
|
||||
|
||||
namespace bft = boost::function_types;
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
using wasmSecondaryCbFuncType =
|
||||
wasm_trap_t*(HostFunctions&, wasm_val_vec_t const*, wasm_val_vec_t*);
|
||||
|
||||
struct WasmImportFunc
|
||||
{
|
||||
std::string_view name;
|
||||
std::optional<WasmTypes> result;
|
||||
std::vector<WasmTypes> params;
|
||||
|
||||
wasmSecondaryCbFuncType* wrap = nullptr;
|
||||
uint32_t gas = 0;
|
||||
};
|
||||
|
||||
using WasmUserData = std::pair<HFRef, WasmImportFunc>;
|
||||
// string - import function name
|
||||
using ImportVec = std::unordered_map<std::string_view, WasmUserData>;
|
||||
|
||||
template <int N, int C, typename Mpl>
|
||||
void
|
||||
WasmImpArgs(WasmImportFunc& e)
|
||||
{
|
||||
if constexpr (N < C)
|
||||
{
|
||||
using at = typename boost::mpl::at_c<Mpl, N>::type;
|
||||
if constexpr (std::is_pointer_v<at>)
|
||||
{
|
||||
e.params.push_back(WasmTypes::WtI32);
|
||||
}
|
||||
else if constexpr (std::is_same_v<at, std::int32_t>)
|
||||
{
|
||||
e.params.push_back(WasmTypes::WtI32);
|
||||
}
|
||||
else if constexpr (std::is_same_v<at, std::int64_t>)
|
||||
{
|
||||
e.params.push_back(WasmTypes::WtI64);
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(std::is_pointer_v<at>, "Unsupported argument type");
|
||||
}
|
||||
|
||||
return WasmImpArgs<N + 1, C, Mpl>(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
template <typename>
|
||||
inline constexpr bool wasmDependentFalse = false;
|
||||
|
||||
template <typename Rt>
|
||||
void
|
||||
WasmImpRet(WasmImportFunc& e)
|
||||
{
|
||||
if constexpr (std::is_pointer_v<Rt>)
|
||||
{
|
||||
e.result = WasmTypes::WtI32;
|
||||
}
|
||||
else if constexpr (std::is_same_v<Rt, std::int32_t>)
|
||||
{
|
||||
e.result = WasmTypes::WtI32;
|
||||
}
|
||||
else if constexpr (std::is_same_v<Rt, std::int64_t>)
|
||||
{
|
||||
e.result = WasmTypes::WtI64;
|
||||
}
|
||||
else if constexpr (std::is_void_v<Rt>)
|
||||
{
|
||||
e.result.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(wasmDependentFalse<Rt>, "Unsupported return type");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void
|
||||
WasmImpFuncHelper(WasmImportFunc& e)
|
||||
{
|
||||
using rt = typename bft::result_type<F>::type;
|
||||
using pt = typename bft::parameter_types<F>::type;
|
||||
// typename boost::mpl::at_c<mpl, N>::type
|
||||
|
||||
WasmImpRet<rt>(e);
|
||||
WasmImpArgs<0, bft::function_arity<F>::value, pt>(e);
|
||||
// WasmImpWrap(e, std::forward<F>(f));
|
||||
}
|
||||
|
||||
// imp_name - string literal, must have static lifetime
|
||||
template <typename F>
|
||||
void
|
||||
WasmImpFunc(
|
||||
ImportVec& v,
|
||||
std::string_view impName,
|
||||
wasmSecondaryCbFuncType* fWrap,
|
||||
HostFunctions& hf,
|
||||
uint32_t gas = 0)
|
||||
{
|
||||
WasmImportFunc e;
|
||||
e.name = impName;
|
||||
e.wrap = fWrap;
|
||||
e.gas = gas;
|
||||
WasmImpFuncHelper<F>(e);
|
||||
v.emplace(impName, std::make_pair(HFRef(hf), std::move(e)));
|
||||
}
|
||||
|
||||
#define WASM_IMPORT_FUNC(v, f, ...) WasmImpFunc<f##_proto>(v, #f, &f##_wrap, ##__VA_ARGS__)
|
||||
|
||||
// n - string literal name, must have static lifetime
|
||||
#define WASM_IMPORT_FUNC2(v, f, n, ...) WasmImpFunc<f##_proto>(v, n, &f##_wrap, ##__VA_ARGS__)
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/wasm/HostFunc.h>
|
||||
#include <xrpl/tx/wasm/WasmImportsHelper.h>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/tx/wasm/WasmVM.h>
|
||||
|
||||
#include <wasm.h>
|
||||
@@ -139,13 +140,13 @@ using StorePtr = std::unique_ptr<wasm_store_t, decltype(&wasm_store_delete)>;
|
||||
|
||||
using FuncInfo = std::pair<wasm_func_t const*, wasm_functype_t const*>;
|
||||
|
||||
struct InstanceWrapper
|
||||
class InstanceWrapper
|
||||
{
|
||||
wasm_store_t* store = nullptr;
|
||||
WasmExternVec exports;
|
||||
mutable int memIdx = -1;
|
||||
InstancePtr instance;
|
||||
beast::Journal j = beast::Journal(beast::Journal::getNullSink());
|
||||
wasm_store_t* store_ = nullptr;
|
||||
WasmExternVec exports_;
|
||||
mutable int memIdx_ = -1;
|
||||
InstancePtr instance_;
|
||||
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
|
||||
|
||||
private:
|
||||
static InstancePtr
|
||||
@@ -157,13 +158,19 @@ private:
|
||||
beast::Journal j);
|
||||
|
||||
public:
|
||||
InstanceWrapper();
|
||||
InstanceWrapper() : instance_(nullptr, &wasm_instance_delete) {};
|
||||
|
||||
InstanceWrapper(InstanceWrapper const&) = delete;
|
||||
|
||||
InstanceWrapper(InstanceWrapper&& o);
|
||||
InstanceWrapper(InstanceWrapper&& o) : instance_(nullptr, &wasm_instance_delete)
|
||||
{
|
||||
*this = std::move(o); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
InstanceWrapper(StorePtr& s, ModulePtr& m, WasmExternVec const& imports, beast::Journal j);
|
||||
InstanceWrapper(StorePtr& s, ModulePtr& m, WasmExternVec const& imports, beast::Journal j)
|
||||
: store_(s.get()), instance_(init(s, m, exports_, imports, j)), j_(j)
|
||||
{
|
||||
}
|
||||
|
||||
InstanceWrapper&
|
||||
operator=(InstanceWrapper&& o);
|
||||
@@ -171,7 +178,10 @@ public:
|
||||
InstanceWrapper&
|
||||
operator=(InstanceWrapper const&) = delete;
|
||||
|
||||
operator bool() const;
|
||||
operator bool() const
|
||||
{
|
||||
return static_cast<bool>(instance_);
|
||||
}
|
||||
|
||||
FuncInfo
|
||||
getFunc(std::string_view funcName, WasmExporttypeVec const& exportTypes) const;
|
||||
@@ -186,20 +196,25 @@ public:
|
||||
setGas(std::int64_t) const;
|
||||
};
|
||||
|
||||
struct ModuleWrapper
|
||||
class ModuleWrapper
|
||||
{
|
||||
ModulePtr module;
|
||||
InstanceWrapper instanceWrap;
|
||||
WasmExporttypeVec exportTypes;
|
||||
beast::Journal j = beast::Journal(beast::Journal::getNullSink());
|
||||
|
||||
private:
|
||||
static ModulePtr
|
||||
init(StorePtr& s, Bytes const& wasmBin, beast::Journal j);
|
||||
ModulePtr module_;
|
||||
InstanceWrapper instanceWrap_;
|
||||
WasmExporttypeVec exportTypes_;
|
||||
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
|
||||
|
||||
public:
|
||||
ModuleWrapper();
|
||||
ModuleWrapper(ModuleWrapper&& o);
|
||||
// LCOV_EXCL_START
|
||||
ModuleWrapper() : module_(nullptr, &wasm_module_delete)
|
||||
{
|
||||
}
|
||||
|
||||
ModuleWrapper(ModuleWrapper&& o) : module_(nullptr, &wasm_module_delete)
|
||||
{
|
||||
*this = std::move(o);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
ModuleWrapper&
|
||||
operator=(ModuleWrapper&& o);
|
||||
ModuleWrapper(
|
||||
@@ -210,27 +225,55 @@ public:
|
||||
beast::Journal j);
|
||||
~ModuleWrapper() = default;
|
||||
|
||||
operator bool() const;
|
||||
operator bool() const
|
||||
{
|
||||
return instanceWrap_;
|
||||
}
|
||||
|
||||
FuncInfo
|
||||
getFunc(std::string_view funcName) const;
|
||||
getFunc(std::string_view funcName) const
|
||||
{
|
||||
return instanceWrap_.getFunc(funcName, exportTypes_);
|
||||
}
|
||||
|
||||
wasm_functype_t*
|
||||
getFuncType(std::string_view funcName) const;
|
||||
|
||||
Wmem
|
||||
getMem() const;
|
||||
getMem() const
|
||||
{
|
||||
return instanceWrap_.getMem();
|
||||
}
|
||||
|
||||
InstanceWrapper&
|
||||
getInstance(int i = 0);
|
||||
getInstance(int i = 0)
|
||||
{
|
||||
return instanceWrap_;
|
||||
}
|
||||
|
||||
InstanceWrapper const&
|
||||
getInstance(int i = 0) const
|
||||
{
|
||||
return instanceWrap_;
|
||||
}
|
||||
|
||||
int
|
||||
addInstance(StorePtr& s, WasmExternVec const& imports);
|
||||
addInstance(StorePtr& s, WasmExternVec const& imports)
|
||||
{
|
||||
instanceWrap_ = {s, module_, imports, j_};
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::int64_t
|
||||
getGas() const;
|
||||
getGas() const
|
||||
{
|
||||
return instanceWrap_ ? instanceWrap_.getGas() : -1;
|
||||
}
|
||||
|
||||
private:
|
||||
static ModulePtr
|
||||
init(StorePtr& s, Bytes const& wasmBin, beast::Journal j);
|
||||
|
||||
WasmExternVec
|
||||
buildImports(StorePtr& s, ImportVec const& imports) const;
|
||||
};
|
||||
@@ -245,7 +288,10 @@ class WasmiEngine
|
||||
std::mutex m_; // 1 instance mutex
|
||||
|
||||
public:
|
||||
WasmiEngine();
|
||||
WasmiEngine() : engine_(init()), store_(nullptr, &wasm_store_delete)
|
||||
{
|
||||
}
|
||||
|
||||
~WasmiEngine() = default;
|
||||
|
||||
static EnginePtr
|
||||
@@ -270,21 +316,37 @@ public:
|
||||
beast::Journal j);
|
||||
|
||||
[[nodiscard]] std::int64_t
|
||||
getGas() const;
|
||||
getGas() const
|
||||
{
|
||||
return moduleWrap_ ? moduleWrap_->getGas() : -1; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// Host functions helper functionality
|
||||
wasm_trap_t*
|
||||
newTrap(std::string const& msg);
|
||||
|
||||
// LCOV_EXCL_START
|
||||
[[nodiscard]] beast::Journal
|
||||
getJournal() const;
|
||||
getJournal() const
|
||||
{
|
||||
return j_;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
private:
|
||||
[[nodiscard]] InstanceWrapper&
|
||||
getRT(int m = 0, int i = 0) const;
|
||||
getRT(int m = 0, int i = 0) const
|
||||
{
|
||||
if (!moduleWrap_)
|
||||
Throw<std::runtime_error>("no module");
|
||||
return moduleWrap_->getInstance(i);
|
||||
}
|
||||
|
||||
[[nodiscard]] Wmem
|
||||
getMem() const;
|
||||
getMem() const
|
||||
{
|
||||
return moduleWrap_ ? moduleWrap_->getMem() : Wmem();
|
||||
}
|
||||
|
||||
Expected<WasmResult<int32_t>, TER>
|
||||
runHlp(
|
||||
@@ -319,7 +381,10 @@ private:
|
||||
makeModule(Bytes const& wasmCode, WasmExternVec const& imports = {});
|
||||
|
||||
[[nodiscard]] FuncInfo
|
||||
getFunc(std::string_view funcName) const;
|
||||
getFunc(std::string_view funcName) const
|
||||
{
|
||||
return moduleWrap_->getFunc(funcName);
|
||||
}
|
||||
|
||||
static std::vector<wasm_val_t>
|
||||
convertParams(std::vector<WasmParam> const& params);
|
||||
|
||||
Reference in New Issue
Block a user