Switch to WAMR (#5416)

* Switch to WAMR
This commit is contained in:
Olek
2025-05-01 18:02:06 -04:00
committed by GitHub
parent f03b5883bd
commit bb9bc764bc
18 changed files with 2454 additions and 829 deletions

View File

@@ -17,730 +17,118 @@
*/
//==============================================================================
#include <xrpld/app/misc/WasmVM.h>
#include <xrpld/app/misc/WamrVM.h>
#include <xrpld/app/misc/WasmHostFuncWrapper.h>
#include "xrpl/protocol/AccountID.h"
#include "xrpl/protocol/LedgerFormats.h"
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <memory>
namespace ripple {
WasmEdge_Result
getLedgerSqn(
void* data,
const WasmEdge_CallingFrameContext*,
const WasmEdge_Value*,
WasmEdge_Value* out)
{
out[0] = WasmEdge_ValueGenI32(((HostFunctions*)data)->getLedgerSqn());
return WasmEdge_Result_Success;
}
WasmEdge_Result
getParentLedgerTime(
void* data,
const WasmEdge_CallingFrameContext*,
const WasmEdge_Value*,
WasmEdge_Value* out)
{
out[0] =
WasmEdge_ValueGenI32(((HostFunctions*)data)->getParentLedgerTime());
return WasmEdge_Result_Success;
}
Expected<Bytes, WasmEdge_Result>
getParameterData(
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
size_t index)
{
auto fnameOffset = (uint32_t)WasmEdge_ValueGetI32(in[index]);
auto fnameLen = (uint32_t)WasmEdge_ValueGetI32(in[index + 1]);
Bytes fname(fnameLen, char{0});
WasmEdge_MemoryInstanceContext* mem =
WasmEdge_CallingFrameGetMemoryInstance(fm, 0);
WasmEdge_Result Res = WasmEdge_MemoryInstanceGetData(
mem, (uint8_t*)(fname.data()), fnameOffset, fnameLen);
if (WasmEdge_ResultOK(Res))
{
return fname;
}
else
{
return Unexpected<WasmEdge_Result>(Res);
}
}
Expected<std::string, WasmEdge_Result>
getFieldName(
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
size_t index)
{
auto dataRes = getParameterData(fm, in, index);
if (dataRes)
{
return std::string(dataRes.value().begin(), dataRes->end());
}
else
{
return Unexpected<WasmEdge_Result>(dataRes.error());
}
}
Expected<WasmEdge_Value, WasmEdge_Result>
setData(const WasmEdge_CallingFrameContext* fm, Bytes const& data)
{
auto alloc = [fm](int32_t dataLen) -> int32_t {
WasmEdge_String allocFunc = WasmEdge_StringCreateByCString("allocate");
auto mod = WasmEdge_CallingFrameGetModuleInstance(fm);
WasmEdge_FunctionInstanceContext* func =
WasmEdge_ModuleInstanceFindFunction(mod, allocFunc);
WasmEdge_Value allocParams[1] = {
WasmEdge_ValueGenI32(dataLen)}; // 4 for prepend the data size
WasmEdge_Value allocReturns[1];
auto executor = WasmEdge_CallingFrameGetExecutor(fm);
auto res = WasmEdge_ExecutorInvoke(
executor, func, allocParams, 1, allocReturns, 1);
if (WasmEdge_ResultOK(res))
{
return WasmEdge_ValueGetI32(allocReturns[0]);
}
else
{
return 0;
}
};
auto dataLen = (int32_t)data.size();
auto dataPtr = alloc(dataLen);
auto retPtr = alloc(8);
if (dataPtr && retPtr)
{
auto mem = WasmEdge_CallingFrameGetMemoryInstance(fm, 0);
auto res =
WasmEdge_MemoryInstanceSetData(mem, data.data(), dataPtr, dataLen);
if (WasmEdge_ResultOK(res))
{
unsigned char intBuf[8]; // little-endian
for (size_t i = 0; i < 4; ++i)
{
intBuf[i] = (dataPtr >> (i * 8)) & 0xFF;
}
for (size_t i = 0; i < 4; ++i)
{
intBuf[i + 4] = (dataLen >> (i * 8)) & 0xFF;
}
res = WasmEdge_MemoryInstanceSetData(mem, intBuf, retPtr, 8);
if (WasmEdge_ResultOK(res))
{
return WasmEdge_ValueGenI32(retPtr);
}
}
}
return Unexpected<WasmEdge_Result>(WasmEdge_Result_Fail);
}
WasmEdge_Result
getTxField(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto fname = getFieldName(fm, in, 0);
if (!fname)
return fname.error();
auto fieldData = ((HostFunctions*)data)->getTxField(fname.value());
if (!fieldData)
return WasmEdge_Result_Fail;
auto pointer = setData(fm, fieldData.value());
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32((int)fieldData.value().size());
return WasmEdge_Result_Success;
}
WasmEdge_Result
getLedgerEntryField(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto type = WasmEdge_ValueGetI32(in[0]);
auto lkData = getParameterData(fm, in, 1);
if (!lkData)
return lkData.error();
auto fname = getFieldName(fm, in, 3);
if (!fname)
return fname.error();
auto fieldData =
((HostFunctions*)data)
->getLedgerEntryField(type, lkData.value(), fname.value());
if (!fieldData)
return WasmEdge_Result_Fail;
auto pointer = setData(fm, fieldData.value());
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32((int)fieldData.value().size());
return WasmEdge_Result_Success;
}
WasmEdge_Result
getCurrentLedgerEntryField(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto fname = getFieldName(fm, in, 0);
if (!fname)
return fname.error();
auto fieldData =
((HostFunctions*)data)->getCurrentLedgerEntryField(fname.value());
if (!fieldData)
return WasmEdge_Result_Fail;
auto pointer = setData(fm, fieldData.value());
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32((int)fieldData.value().size());
return WasmEdge_Result_Success;
}
WasmEdge_Result
getNFT(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto account = getFieldName(fm, in, 0);
if (!account)
return account.error();
auto nftId = getFieldName(fm, in, 2);
if (!nftId)
return nftId.error();
auto nftURI =
((HostFunctions*)data)->getNFT(account.value(), nftId.value());
if (!nftURI)
return WasmEdge_Result_Fail;
auto pointer = setData(fm, nftURI.value());
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
return WasmEdge_Result_Success;
}
WasmEdge_Result
accountKeylet(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto account = getFieldName(fm, in, 0);
if (!account)
return account.error();
auto keylet = ((HostFunctions*)data)->accountKeylet(account.value());
if (!keylet)
return WasmEdge_Result_Fail;
auto pointer = setData(fm, keylet.value());
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
return WasmEdge_Result_Success;
}
WasmEdge_Result
credentialKeylet(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto subject = getFieldName(fm, in, 0);
if (!subject)
return subject.error();
auto issuer = getFieldName(fm, in, 2);
if (!issuer)
return issuer.error();
auto credentialType = getFieldName(fm, in, 4);
if (!credentialType)
return credentialType.error();
auto keylet =
((HostFunctions*)data)
->credentialKeylet(
subject.value(), issuer.value(), credentialType.value());
if (!keylet)
return WasmEdge_Result_Fail;
auto pointer = setData(fm, keylet.value());
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
return WasmEdge_Result_Success;
}
WasmEdge_Result
escrowKeylet(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto account = getFieldName(fm, in, 0);
if (!account)
return account.error();
auto sequence = WasmEdge_ValueGetI32(in[2]);
auto keylet =
((HostFunctions*)data)->escrowKeylet(account.value(), sequence);
if (!keylet)
return WasmEdge_Result_Fail;
auto pointer = setData(fm, keylet.value());
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
return WasmEdge_Result_Success;
}
WasmEdge_Result
oracleKeylet(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto account = getFieldName(fm, in, 0);
if (!account)
return account.error();
auto documentId = WasmEdge_ValueGetI32(in[2]);
auto keylet =
((HostFunctions*)data)->escrowKeylet(account.value(), documentId);
if (!keylet)
return WasmEdge_Result_Fail;
auto pointer = setData(fm, keylet.value());
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
return WasmEdge_Result_Success;
}
WasmEdge_Result
updateData(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto fname = getParameterData(fm, in, 0);
if (!fname)
return fname.error();
if (((HostFunctions*)data)->updateData(fname.value()))
return WasmEdge_Result_Success;
else
return WasmEdge_Result_Fail;
}
WasmEdge_Result
computeSha512HalfHash(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto fname = getParameterData(fm, in, 0);
if (!fname)
return fname.error();
auto hres = ((HostFunctions*)data)->computeSha512HalfHash(fname.value());
Bytes digest{hres.begin(), hres.end()};
auto pointer = setData(fm, digest);
if (!pointer)
return pointer.error();
out[0] = pointer.value();
// out[1] = WasmEdge_ValueGenI32(32);
return WasmEdge_Result_Success;
}
WasmEdge_Result
print(
void* data,
const WasmEdge_CallingFrameContext* fm,
const WasmEdge_Value* in,
WasmEdge_Value* out)
{
auto f = getParameterData(fm, in, 0);
if (!f)
return f.error();
std::string s(f.value().begin(), f.value().end());
std::cout << s << std::endl;
return WasmEdge_Result_Success;
}
Expected<EscrowResult, TER>
runEscrowWasm(
std::vector<uint8_t> const& wasmCode,
std::string const& funcName,
Bytes const& wasmCode,
std::string_view funcName,
HostFunctions* hfs,
uint64_t gasLimit)
{
// WasmEdge_LogOff();
// TODO deletes
// create VM and set cost limit
WasmEdge_ConfigureContext* conf = WasmEdge_ConfigureCreate();
WasmEdge_ConfigureStatisticsSetInstructionCounting(conf, true);
WasmEdge_ConfigureStatisticsSetCostMeasuring(conf, true);
WasmEdge_ConfigureSetMaxMemoryPage(conf, MAX_PAGES);
auto& vm = WasmEngine::instance();
vm.initGas(gasLimit);
vm.initMaxPages(MAX_PAGES);
WasmEdge_VMContext* VMCxt = WasmEdge_VMCreate(conf, NULL);
WasmEdge_StatisticsContext* StatCxt =
WasmEdge_VMGetStatisticsContext(VMCxt);
WasmEdge_StatisticsSetCostLimit(StatCxt, gasLimit);
std::vector<WasmImportFunc> imports;
{ // register host function
// module
WasmEdge_String libName = WasmEdge_StringCreateByCString("host_lib");
WasmEdge_ModuleInstanceContext* hostMod =
WasmEdge_ModuleInstanceCreate(libName);
WasmEdge_StringDelete(libName);
WASM_IMPORT_FUNC(imports, getLedgerSqn, hfs)
WASM_IMPORT_FUNC(imports, getParentLedgerTime, hfs)
WASM_IMPORT_FUNC(imports, getTxField, hfs)
WASM_IMPORT_FUNC(imports, getLedgerEntryField, hfs)
WASM_IMPORT_FUNC(imports, getCurrentLedgerEntryField, hfs)
WASM_IMPORT_FUNC(imports, getNFT, hfs)
WASM_IMPORT_FUNC(imports, accountKeylet, hfs)
WASM_IMPORT_FUNC(imports, credentialKeylet, hfs)
WASM_IMPORT_FUNC(imports, escrowKeylet, hfs)
WASM_IMPORT_FUNC(imports, oracleKeylet, hfs)
WASM_IMPORT_FUNC(imports, updateData, hfs)
WASM_IMPORT_FUNC(imports, computeSha512HalfHash, hfs)
WASM_IMPORT_FUNC(imports, print, hfs)
// getLedgerSqn
{
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(NULL, 0, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, getLedgerSqn, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
std::int64_t const sgas = gasLimit; // vm.getGas();
auto ret = vm.run(wasmCode, funcName, imports);
if (!ret.has_value())
return Unexpected<TER>(ret.error());
std::int64_t const egas = vm.getGas();
std::uint64_t const spent = static_cast<std::uint64_t>(sgas - egas);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("getLedgerSqn");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
// WasmEdge_FunctionInstanceDelete(hostFunc);
}
// getParentLedgerTime
{
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(NULL, 0, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, getParentLedgerTime, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("getParentLedgerTime");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
// WasmEdge_FunctionInstanceDelete(hostFunc);
}
// getTxField
{
WasmEdge_ValType inputList[2] = {
WasmEdge_ValTypeGenI32(), WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 2, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, getTxField, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("getTxField");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// getLedgerEntryField
{
WasmEdge_ValType inputList[5] = {
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 5, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, getLedgerEntryField, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("getLedgerEntryField");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// getCurrentLedgerEntryField
{
WasmEdge_ValType inputList[2] = {
WasmEdge_ValTypeGenI32(), WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 2, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, getCurrentLedgerEntryField, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("getCurrentLedgerEntryField");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// getNFT
{
WasmEdge_ValType inputList[4] = {
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 2, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(hostFuncType, getNFT, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName = WasmEdge_StringCreateByCString("getNFT");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// updateData
{
WasmEdge_ValType inputList[2] = {
WasmEdge_ValTypeGenI32(), WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 2, NULL, 0);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, updateData, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("updateData");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// computeSha512HalfHash
{
WasmEdge_ValType inputList[2] = {
WasmEdge_ValTypeGenI32(), WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 2, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, computeSha512HalfHash, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("computeSha512HalfHash");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// accountKeylet
{
WasmEdge_ValType inputList[2] = {
WasmEdge_ValTypeGenI32(), WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 2, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, accountKeylet, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("accountKeylet");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// credentialKeylet
{
WasmEdge_ValType inputList[6] = {
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 6, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, credentialKeylet, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("credentialKeylet");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// escrowKeylet
{
WasmEdge_ValType inputList[3] = {
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 3, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, escrowKeylet, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("escrowKeylet");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// oracleKeylet
{
WasmEdge_ValType inputList[3] = {
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32(),
WasmEdge_ValTypeGenI32()};
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 3, returnList, 1);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(
hostFuncType, oracleKeylet, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName =
WasmEdge_StringCreateByCString("oracleKeylet");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
// print
{
WasmEdge_ValType inputList[2] = {
WasmEdge_ValTypeGenI32(), WasmEdge_ValTypeGenI32()};
WasmEdge_FunctionTypeContext* hostFuncType =
WasmEdge_FunctionTypeCreate(inputList, 2, NULL, 0);
WasmEdge_FunctionInstanceContext* hostFunc =
WasmEdge_FunctionInstanceCreate(hostFuncType, print, hfs, 100);
// WasmEdge_FunctionTypeDelete(hostFuncType);
// WasmEdge_FunctionInstanceDelete(hostFunc);
WasmEdge_String fName = WasmEdge_StringCreateByCString("print");
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
// WasmEdge_StringDelete(fName);
}
WasmEdge_Result regRe =
WasmEdge_VMRegisterModuleFromImport(VMCxt, hostMod);
if (!WasmEdge_ResultOK(regRe))
{
printf("host func reg error\n");
return Unexpected<TER>(tecFAILED_PROCESSING);
}
}
WasmEdge_Result loadRes =
WasmEdge_VMLoadWasmFromBuffer(VMCxt, wasmCode.data(), wasmCode.size());
if (!WasmEdge_ResultOK(loadRes))
{
printf("load error, %p, %d\n", wasmCode.data(), wasmCode.size());
return Unexpected<TER>(tecFAILED_PROCESSING);
}
WasmEdge_Result validateRes = WasmEdge_VMValidate(VMCxt);
if (!WasmEdge_ResultOK(validateRes))
{
printf("validate error\n");
return Unexpected<TER>(tecFAILED_PROCESSING);
}
WasmEdge_Result instantiateRes = WasmEdge_VMInstantiate(VMCxt);
if (!WasmEdge_ResultOK(instantiateRes))
{
printf("instantiate error\n");
return Unexpected<TER>(tecFAILED_PROCESSING);
}
WasmEdge_Value funcReturns[1];
WasmEdge_String func = WasmEdge_StringCreateByCString(funcName.c_str());
WasmEdge_Result funcRes =
WasmEdge_VMExecute(VMCxt, func, NULL, 0, funcReturns, 1);
bool ok = WasmEdge_ResultOK(funcRes);
EscrowResult re;
if (ok)
{
auto sc = WasmEdge_VMGetStatisticsContext(VMCxt);
re.cost = WasmEdge_StatisticsGetTotalCost(sc);
// WasmEdge_StatisticsGetTotalCost, WasmEdge_StatisticsGetInstrCount
auto result = WasmEdge_ValueGetI32(funcReturns[0]);
if (result != 0)
re.result = true;
else
re.result = false;
}
else
{
printf("Error message: %s\n", WasmEdge_ResultGetMessage(funcRes));
}
WasmEdge_VMDelete(VMCxt);
WasmEdge_StringDelete(func);
// delete other obj allocated
if (ok)
return re;
else
return Unexpected<TER>(tecFAILED_PROCESSING);
return EscrowResult{static_cast<bool>(ret.value()), spent};
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WasmEngine::WasmEngine() : impl(std::make_unique<WamrEngine>())
{
}
WasmEngine&
WasmEngine::instance()
{
static WasmEngine e;
return e;
}
Expected<int32_t, TER>
WasmEngine::run(
wbytes const& wasmCode,
std::string_view funcName,
std::vector<WasmImportFunc> const& imports,
std::vector<WasmParam> const& params)
{
return impl->run(wasmCode, funcName, imports, params);
}
std::int64_t
WasmEngine::initGas(std::int64_t def)
{
return impl->initGas(def);
}
std::int32_t
WasmEngine::initMaxPages(std::int32_t def)
{
return impl->initMaxPages(def);
}
// gas = 1'000'000'000LL
std::int64_t
WasmEngine::setGas(std::int64_t gas)
{
return impl->setGas(gas);
}
std::int64_t
WasmEngine::getGas()
{
return impl->getGas();
}
wmem
WasmEngine::getMem() const
{
return impl->getMem();
}
int32_t
WasmEngine::allocate(int32_t size)
{
return impl->allocate(size);
}
void*
WasmEngine::newTrap(std::string_view msg)
{
return impl->newTrap(msg);
}
} // namespace ripple