Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add scout host functions #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions src/scout/scout.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#include "src/interp/interp.h"

#include <memory>

#include <iostream>
#include <regex>

#include <fstream>
#include <iomanip>
#include <sstream>
#include <cctype>

using bytes = std::basic_string<uint8_t>;


bytes from_hex(std::string_view hex)
{
if (hex.length() % 2 == 1)
//throw std::length_error{"the length of the input is odd"};
printf("ERROR: the length of the input is odd\n");

bytes bs;
int b = 0;
for (size_t i = 0; i < hex.size(); ++i)
{
auto h = hex[i];
int v;
if (h >= '0' && h <= '9')
v = h - '0';
else if (h >= 'a' && h <= 'f')
v = h - 'a' + 10;
else if (h >= 'A' && h <= 'F')
v = h - 'A' + 10;
else
//throw std::out_of_range{"not a hex digit"};
printf("ERROR: not a hex digit\n");

if (i % 2 == 0)
b = v << 4;
else
bs.push_back(static_cast<uint8_t>(b | v));
}
return bs;
}




using namespace wabt;
using namespace wabt::interp;


void AppendScoutFuncs(wabt::interp::Environment* env, wabt::interp::HostModule* host_module_env) {


// TODO: read the file name from an argument
std::ifstream blockDataFile{"./test_block_data.hex"};
std::string blockdata_hex{std::istreambuf_iterator<char>{blockDataFile}, std::istreambuf_iterator<char>{}};

blockdata_hex.erase(
std::remove_if(blockdata_hex.begin(), blockdata_hex.end(), [](char x) { return std::isspace(x); }),
blockdata_hex.end());


// bytes is a basic_string
auto blockdata_bytes = std::make_shared<bytes>(from_hex(blockdata_hex));
//std::cout << "blockdata bytes length:" << blockdata_bytes->size() << std::endl;

const unsigned char* blockData = blockdata_bytes->data();

//int block_data_size = std::strlen((char*)blockData);
//std::cout << "blockData[] length:" << block_data_size << std::endl;
//printf("blockData: %s\n", blockData);

//for(int i=0; i < block_data_size; ++i)
// std::cout << std::hex << (int)blockData[i];
//std::cout << std::endl;


host_module_env->AppendFuncExport(
"eth2_loadPreStateRoot",
{{Type::I32}, {}},
// [env]( // TODO: use to load prestate root from memory
[](
const interp::HostFunc*,
const interp::FuncSignature*,
const interp::TypedValues& args,
interp::TypedValues& results
) {
// TODO: use env to load prestate root from wasm memory
//printf("eth2_loadPreStateRoot mem_pos: %llu\n", args[0].value.i32);
return interp::Result::Ok;
}
);

host_module_env->AppendFuncExport(
"eth2_savePostStateRoot",
{{Type::I32}, {}},
[env](
const interp::HostFunc*,
const interp::FuncSignature*,
const interp::TypedValues& args,
interp::TypedValues& results
) {
//printf("eth2_savePostStateRoot mem_pos: %llu\n", args[0].value.i32);

wabt::interp::Memory* mem = env->GetMemory(0);

unsigned char postStateData[32];
uint32_t ret_offset = args[0].value.i32;

uint8_t* mem_ptr = reinterpret_cast<uint8_t*>(&mem->data[ret_offset]);
uint8_t* mem_ptr_end = reinterpret_cast<uint8_t*>(&mem->data[ret_offset+32]);

//printf("eth2_savePostStateRoot copying memory...\n");
std::copy(mem_ptr, mem_ptr_end, postStateData);

/// print returned state root
char buffer [33];
buffer[32] = 0;
for(int j = 0; j < 16; j++)
sprintf(&buffer[2*j], "%02X", postStateData[j]);

//std::cout << "eth2_savePostStateRoot: " << std::hex << buffer << std::endl;
return interp::Result::Ok;
}
);

host_module_env->AppendFuncExport(
"eth2_blockDataSize",
{{}, {Type::I32}},
[blockdata_bytes](
const interp::HostFunc*,
const interp::FuncSignature*,
const interp::TypedValues& args,
interp::TypedValues& results
) {
//printf("eth2_blockDataSize\n");

int data_size = blockdata_bytes->size();

//printf("data_size: %d\n", data_size);

results[0].set_i32(data_size);

return interp::Result::Ok;
}
);

host_module_env->AppendFuncExport(
"eth2_blockDataCopy",
{{Type::I32, Type::I32, Type::I32}, {}},
[env, blockData](
const interp::HostFunc*,
const interp::FuncSignature*,
const interp::TypedValues& args,
interp::TypedValues&
) {
//printf("eth2_blockDataCopy.\n");

wabt::interp::Memory* mem = env->GetMemory(0);

// arg order: eth2_blockDataCopy(outOffset, srcOffset, length)
uint32_t out_offset = args[0].value.i32;
uint32_t src_offset = args[1].value.i32;
uint32_t copy_len = args[2].value.i32;

//printf("eth2_blockDataCopy out_offset: %d\n", args[0].value.i32);
//printf("eth2_blockDataCopy src_offset: %d\n", args[1].value.i32);
//printf("eth2_blockDataCopy copy_len: %d\n", args[2].value.i32);

std::copy(blockData+src_offset, blockData+copy_len, &mem->data[out_offset]);
//std::cout << "eth2_blockDataCopy wrote to mem." << std::endl;

/* *** debugging helper
// inspect written memory
unsigned char writtenToMem[32];
uint8_t* mem_ptr = reinterpret_cast<uint8_t*>(&mem->data[out_offset]);
uint8_t* mem_ptr_end = reinterpret_cast<uint8_t*>(&mem->data[out_offset+32]);
std::copy(mem_ptr, mem_ptr_end, writtenToMem);
char bufferWrittenMem [33];
bufferWrittenMem[32] = 0;
for(int j = 0; j < 16; j++)
sprintf(&bufferWrittenMem[2*j], "%02X", writtenToMem[j]);
std::cout << "eth2_blockDataCopy memory after writing:" << std::hex << bufferWrittenMem << std::endl;
*/

return interp::Result::Ok;
}
);

}
6 changes: 6 additions & 0 deletions src/tools/wasm-interp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include "src/wast-lexer.h"
#include "src/wast-parser.h"

#include "src/scout/scout.h"

using namespace wabt;
using namespace wabt::interp;

Expand Down Expand Up @@ -200,6 +202,10 @@ static void InitEnvironment(Environment* env) {
return true;
};
}

// append scout host functions
HostModule* env_for_scout = env->AppendHostModule("env");
AppendScoutFuncs(env, env_for_scout);
}

static wabt::Result ReadAndRunModule(const char* module_filename) {
Expand Down