Skip to content

Commit

Permalink
Fix wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
learnforpractice committed Oct 24, 2018
1 parent 2a83870 commit ac5872c
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 325 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

#if defined(_WAVM)
#include <eosio/chain/webassembly/wavm.hpp>
#elif defined(_BINARYEN)
#include <eosio/chain/webassembly/binaryen.hpp>
#elif defined(_WABT)
#include <eosio/chain/webassembly/wabt.hpp>
#else
Expand Down
16 changes: 9 additions & 7 deletions libraries/chain/include/eosio/chain/webassembly/wabt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
#include <eosio/chain/webassembly/common.hpp>
#include <eosio/chain/webassembly/runtime_interface.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/apply_context.hpp>
//#include <eosio/chain/apply_context.hpp>
#include <softfloat_types.h>

//wabt includes
#include <src/binary-reader.h>
#include <src/common.h>
#include <src/interp.h>

#include <eosiolib_native/vm_api.h>

namespace eosio { namespace chain { namespace webassembly { namespace wabt_runtime {

using namespace fc;
Expand Down Expand Up @@ -372,7 +374,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<array_ptr<T>, size_t, Inputs...>>
size_t length = args.at((uint32_t)offset).get_i32();
T* base = array_ptr_impl<T>(vars, ptr, length);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(vars.ctx.control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned array of const values" );
std::vector<std::remove_const_t<T> > copy(length > 0 ? length : 1);
T* copy_ptr = &copy[0];
Expand All @@ -389,7 +391,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<array_ptr<T>, size_t, Inputs...>>
size_t length = args.at((uint32_t)offset).get_i32();
T* base = array_ptr_impl<T>(vars, ptr, length);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(vars.ctx.control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned array of values" );
std::vector<std::remove_const_t<T> > copy(length > 0 ? length : 1);
T* copy_ptr = &copy[0];
Expand Down Expand Up @@ -503,7 +505,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>> {
uint32_t ptr = args.at((uint32_t)offset).get_i32();
T* base = array_ptr_impl<T>(vars, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(vars.ctx.control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned const pointer" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
Expand All @@ -518,7 +520,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>> {
uint32_t ptr = args.at((uint32_t)offset).get_i32();
T* base = array_ptr_impl<T>(vars, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(vars.ctx.control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned pointer" );
T copy;
memcpy( (void*)&copy, (void*)base, sizeof(T) );
Expand Down Expand Up @@ -608,7 +610,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>> {
EOS_ASSERT(ptr != 0, binaryen_exception, "references cannot be created for null pointers");
T* base = array_ptr_impl<T>(vars, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(vars.ctx.control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned const reference" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
Expand All @@ -625,7 +627,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>> {
EOS_ASSERT(ptr != 0, binaryen_exception, "references cannot be created for null pointers");
T* base = array_ptr_impl<T>(vars, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(vars.ctx.control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned reference" );
T copy;
memcpy( (void*)&copy, (void*)base, sizeof(T) );
Expand Down
25 changes: 13 additions & 12 deletions libraries/chain/include/eosio/chain/webassembly/wavm.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#pragma once

#include <eosio/chain/webassembly/common.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/webassembly/runtime_interface.hpp>
#include <eosio/chain/apply_context.hpp>
//#include <eosio/chain/apply_context.hpp>
#include <softfloat.hpp>
#include "Runtime/Runtime.h"
#include "IR/Types.h"

#include <eosiolib_native/vm_api.h>

namespace eosio { namespace chain { namespace webassembly { namespace wavm {

Expand Down Expand Up @@ -50,14 +51,14 @@ template<typename T>
inline array_ptr<T> array_ptr_impl (running_instance_context& ctx, U32 ptr, size_t length)
{
MemoryInstance* mem = ctx.memory;
if (!mem)
if (!mem)
Runtime::causeException(Exception::Cause::accessViolation);

size_t mem_total = IR::numBytesPerPage * Runtime::getMemoryNumPages(mem);
if (ptr >= mem_total || length > (mem_total - ptr) / sizeof(T))
Runtime::causeException(Exception::Cause::accessViolation);
// T* ret_ptr = (T*)(getMemoryBaseAddress(mem) + ptr);

// T* ret_ptr = (T*)(getMemoryBaseAddress(mem) + ptr);

return array_ptr<T>((T*)(getMemoryBaseAddress(mem) + ptr));
}
Expand Down Expand Up @@ -384,7 +385,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<array_ptr<T>, size_t, Inputs...>,
const auto length = size_t(size);
T* base = array_ptr_impl<T>(ctx, (U32)ptr, length);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(ctx.apply_ctx->control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned array of const values" );
std::vector<std::remove_const_t<T> > copy(length > 0 ? length : 1);
T* copy_ptr = &copy[0];
Expand All @@ -400,12 +401,12 @@ struct intrinsic_invoker_impl<Ret, std::tuple<array_ptr<T>, size_t, Inputs...>,
const auto length = size_t(size);
T* base = array_ptr_impl<T>(ctx, (U32)ptr, length);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(ctx.apply_ctx->control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned array of values" );
std::vector<std::remove_const_t<T> > copy(length > 0 ? length : 1);
T* copy_ptr = &copy[0];
memcpy( (void*)copy_ptr, (void*)base, length * sizeof(T) );
Ret ret = Then(ctx, static_cast<array_ptr<T>>(copy_ptr), length, rest..., translated...);
Ret ret = Then(ctx, static_cast<array_ptr<T>>(copy_ptr), length, rest..., translated...);
memcpy( (void*)base, (void*)copy_ptr, length * sizeof(T) );
return ret;
}
Expand Down Expand Up @@ -512,7 +513,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>, std::tuple<Transl
static auto translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) -> std::enable_if_t<std::is_const<U>::value, Ret> {
T* base = array_ptr_impl<T>(ctx, (U32)ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(ctx.apply_ctx->control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned const pointer" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
Expand All @@ -526,7 +527,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>, std::tuple<Transl
static auto translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) -> std::enable_if_t<!std::is_const<U>::value, Ret> {
T* base = array_ptr_impl<T>(ctx, (U32)ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
if(ctx.apply_ctx->control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned pointer" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
Expand Down Expand Up @@ -593,7 +594,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>, std::tuple<Transl
Runtime::causeException(Exception::Cause::accessViolation);
T &base = *(T*)(getMemoryBaseAddress(mem)+(U32)ptr);
if ( reinterpret_cast<uintptr_t>(&base) % alignof(T) != 0 ) {
if(ctx.apply_ctx->control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned const reference" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
Expand All @@ -612,7 +613,7 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>, std::tuple<Transl
Runtime::causeException(Exception::Cause::accessViolation);
T &base = *(T*)(getMemoryBaseAddress(mem)+(U32)ptr);
if ( reinterpret_cast<uintptr_t>(&base) % alignof(T) != 0 ) {
if(ctx.apply_ctx->control.contracts_console())
if(get_vm_api()->contracts_console())
wlog( "misaligned reference" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
Expand Down
46 changes: 37 additions & 9 deletions libraries/chain/webassembly/wabt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace eosio { namespace chain { namespace webassembly { namespace wabt_runtime {

//yep 🤮

static wabt_apply_instance_vars* static_wabt_vars;

using namespace wabt;
Expand All @@ -28,17 +28,16 @@ class wabt_instantiated_module : public wasm_instantiated_module_interface {
continue;
_initial_globals.emplace_back(_env->GetGlobal(i), _env->GetGlobal(i)->typed_value);
}

if(_env->GetMemoryCount())
_initial_memory_configuration = _env->GetMemory(0)->page_limits;
}

void apply(apply_context& context) override {
void apply(uint64_t receiver, uint64_t account, uint64_t act) override {
//reset mutable globals
for(const auto& mg : _initial_globals)
mg.first->typed_value = mg.second;

wabt_apply_instance_vars this_run_vars{nullptr, context};
wabt_apply_instance_vars this_run_vars{nullptr};
static_wabt_vars = &this_run_vars;

//reset memory to inital size & copy back in initial data
Expand All @@ -50,9 +49,9 @@ class wabt_instantiated_module : public wasm_instantiated_module_interface {
memcpy(memory->data.data(), _initial_memory.data(), _initial_memory.size());
}

_params[0].set_i64(uint64_t(context.receiver));
_params[1].set_i64(uint64_t(context.act.account));
_params[2].set_i64(uint64_t(context.act.name));
_params[0].set_i64(receiver);
_params[1].set_i64(account);
_params[2].set_i64(act);

ExecResult res = _executor.RunStartFunction(_instatiated_module);
EOS_ASSERT( res.result == interp::Result::Ok, wasm_execution_error, "wabt start function failure (${s})", ("s", ResultToString(res.result)) );
Expand All @@ -61,6 +60,35 @@ class wabt_instantiated_module : public wasm_instantiated_module_interface {
EOS_ASSERT( res.result == interp::Result::Ok, wasm_execution_error, "wabt execution failure (${s})", ("s", ResultToString(res.result)) );
}

uint64_t call(const std::string &entry_point, const std::vector <uint64_t> & _args) override {
//reset mutable globals
for(const auto& mg : _initial_globals) {
mg.first->typed_value = mg.second;
}

wabt_apply_instance_vars this_run_vars{nullptr};
static_wabt_vars = &this_run_vars;

//reset memory to inital size & copy back in initial data
if(_env->GetMemoryCount()) {
Memory* memory = this_run_vars.memory = _env->GetMemory(0);
memory->page_limits = _initial_memory_configuration;
memory->data.resize(_initial_memory_configuration.initial * WABT_PAGE_SIZE);
memset(memory->data.data(), 0, memory->data.size());
memcpy(memory->data.data(), _initial_memory.data(), _initial_memory.size());
}
TypedValues _params{_args.size(), TypedValue(Type::I64)};
for (int i=0;i<_args.size();i++) {
_params[i].set_i64(_args[i]);
}
ExecResult res = _executor.RunStartFunction(_instatiated_module);
EOS_ASSERT( res.result == interp::Result::Ok, wasm_execution_error, "wabt start function failure (${s})", ("s", ResultToString(res.result)) );

res = _executor.RunExportByName(_instatiated_module, entry_point, _params);
EOS_ASSERT( res.result == interp::Result::Ok, wasm_execution_error, "wabt execution failure (${s})", ("s", ResultToString(res.result)) );
return 1;
}

private:
std::unique_ptr<interp::Environment> _env;
DefinedModule* _instatiated_module; //this is owned by the Environment
Expand Down Expand Up @@ -92,7 +120,7 @@ std::unique_ptr<wasm_instantiated_module_interface> wabt_runtime::instantiate_mo

wabt::Result res = ReadBinaryInterp(env.get(), code_bytes, code_size, read_binary_options, &errors, &instantiated_module);
EOS_ASSERT( Succeeded(res), wasm_execution_error, "Error building wabt interp: ${e}", ("e", wabt::FormatErrorsToString(errors, Location::Type::Binary)) );

return std::make_unique<wabt_instantiated_module>(std::move(env), initial_memory, instantiated_module);
}

Expand Down
27 changes: 15 additions & 12 deletions libraries/chain/webassembly/wavm.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//#include <eosio/chain/apply_context.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/webassembly/wavm.hpp>
#include <eosio/chain/wasm_eosio_constraints.hpp>
#include <eosio/chain/wasm_eosio_injection.hpp>
#include <eosio/chain/apply_context.hpp>
#include <eosio/chain/exceptions.hpp>

#include "IR/Module.h"
#include "Platform/Platform.h"
Expand All @@ -16,6 +16,7 @@

using namespace IR;
using namespace Runtime;
using namespace eosio::chain;

namespace eosio { namespace chain { namespace webassembly { namespace wavm {

Expand All @@ -29,23 +30,24 @@ class wavm_instantiated_module : public wasm_instantiated_module_interface {
_module(std::move(module))
{}

void apply(apply_context& context) override {
vector<Value> args = {Value(uint64_t(context.receiver)),
Value(uint64_t(context.act.account)),
Value(uint64_t(context.act.name))};

call("apply", args, context);
void apply(uint64_t receiver, uint64_t account, uint64_t act) override {
vector<Value> args = {
Value(receiver),
Value(account),
Value(act)
};
call("apply", args);
}

uint64_t call(const string &entry_point, const vector <uint64_t> & _args, apply_context &context) override {
uint64_t call(const string &entry_point, const vector <uint64_t> & _args) override {
vector<Value> args;
for(auto& arg: _args) {
args.push_back(Value(uint64_t(arg)));
}
return call(entry_point, args, context);
return call(entry_point, args);
}
private:
uint64_t call(const string &entry_point, const vector <Value> &args, apply_context &context) {
uint64_t call(const string &entry_point, const vector <Value> &args) {
try {
FunctionInstance* call = asFunctionNullable(getInstanceExport(_instance,entry_point));
if( !call )
Expand All @@ -66,7 +68,7 @@ class wavm_instantiated_module : public wasm_instantiated_module_interface {
}

the_running_instance_context.memory = default_mem;
the_running_instance_context.apply_ctx = &context;
// the_running_instance_context.apply_ctx = &context;

resetGlobalInstances(_instance);
runInstanceStartFunc(_instance);
Expand All @@ -78,6 +80,7 @@ class wavm_instantiated_module : public wasm_instantiated_module_interface {
("cause", string(describeExceptionCause(e.cause)))
("callstack", e.callStack));
} FC_CAPTURE_AND_RETHROW()
return 0;
}


Expand Down
17 changes: 2 additions & 15 deletions libraries/vm/vm_wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,9 @@ endif (APPLE)

#set(LINK_FLAGS "${LINK_FLAGS} -export-symbols-regex '^vm_*'")


add_library(vm_wasm_binaryen SHARED
vm_wasm.cpp
binaryen.cpp
${COMMON_SOURCES})

target_compile_options(vm_wasm_binaryen PRIVATE -D_BINARYEN)
target_link_libraries(vm_wasm_binaryen PRIVATE wavm-shared binaryen softfloat builtins fc)

target_include_directories(vm_wasm_binaryen PRIVATE ${HEADERS})


add_library(vm_wasm_wavm STATIC
# vm_wasm.cpp
wavm.cpp
${CMAKE_SOURCE_DIR}/libraries/chain/webassembly/wavm.cpp
${COMMON_SOURCES})

target_compile_options(vm_wasm_wavm PRIVATE -D_WAVM)
Expand All @@ -54,7 +42,7 @@ target_include_directories(vm_wasm_wavm PRIVATE ${HEADERS})

add_library(vm_wasm_wabt SHARED
vm_wasm.cpp
wabt.cpp
${CMAKE_SOURCE_DIR}/libraries/chain/webassembly/wabt.cpp
${COMMON_SOURCES})

target_compile_options(vm_wasm_wabt PRIVATE -D_WABT)
Expand All @@ -67,7 +55,6 @@ target_include_directories(vm_wasm_wabt PRIVATE ${HEADERS}


set_target_properties(vm_wasm_wavm PROPERTIES LINK_FLAGS "${LINK_FLAGS}")
set_target_properties(vm_wasm_binaryen PROPERTIES LINK_FLAGS "${LINK_FLAGS}")
set_target_properties(vm_wasm_wabt PROPERTIES LINK_FLAGS "${LINK_FLAGS}")


Expand Down
4 changes: 0 additions & 4 deletions libraries/vm/vm_wasm/vm_wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ void vm_deinit() {
printf("vm_wasm vm_deinit\n");
}

struct vm_api* get_vm_api() {
return &s_api;
}

int vm_setcode(uint64_t account) {
size_t size = 0;
const char* code = get_vm_api()->get_code(account, &size);
Expand Down
Loading

0 comments on commit ac5872c

Please sign in to comment.