提交 7ea3f14c 编写于 作者: B Bart Wyatt

move jit into its own isolated space (mostly)

上级 6b14e60f
......@@ -31,10 +31,19 @@ add_library( eosio_chain
${HEADERS}
transaction_metadata.cpp)
target_link_libraries( eosio_chain eos_utilities fc chainbase Logging IR WAST WASM Runtime )
target_link_libraries( eosio_chain eos_utilities fc chainbase Logging IR WAST WASM Runtime
"/usr/local/share/binaryen/lib/libwasm.a"
"/usr/local/share/binaryen/lib/libasmjs.a"
"/usr/local/share/binaryen/lib/libpasses.a"
"/usr/local/share/binaryen/lib/libcfg.a"
"/usr/local/share/binaryen/lib/libast.a"
"/usr/local/share/binaryen/lib/libemscripten-optimizer.a"
"/usr/local/share/binaryen/lib/libsupport.a"
)
target_include_directories( eosio_chain
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../wasm-jit/Include"
"${CMAKE_CURRENT_SOURCE_DIR}/../wasm-jit/Include" "/usr/local/share/binaryen/src"
)
if(MSVC)
......
......@@ -2,14 +2,13 @@
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/types.hpp>
namespace Runtime {
struct MemoryInstance;
}
namespace eosio { namespace chain {
class apply_context;
class intrinsics_accessor;
namespace webassembly { namespace common {
class intrinsics_accessor;
} }
/**
* @class wasm_cache
......@@ -115,7 +114,7 @@ namespace eosio { namespace chain {
private:
wasm_interface();
unique_ptr<struct wasm_interface_impl> my;
friend class eosio::chain::intrinsics_accessor;
friend class eosio::chain::webassembly::common::intrinsics_accessor;
};
} } // eosio::chain
#pragma once
#include <eosio/chain/wasm_interface.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
using namespace fc;
namespace eosio { namespace chain { namespace webassembly { namespace common {
using wasm_double = boost::multiprecision::cpp_dec_float_50;
struct wasm_context {
wasm_context(wasm_cache::entry &code, apply_context& ctx, uint32_t sbrk_bytes) : code(code), context(ctx)
{
}
eosio::chain::wasm_cache::entry& code;
apply_context& context;
uint32_t sbrk_bytes;
};
class intrinsics_accessor {
public:
static wasm_context &get_context(wasm_interface &wasm);
};
template<typename T>
struct class_from_wasm {
/**
* by default this is just constructing an object
* @param wasm - the wasm_interface to use
* @return
*/
static auto value(wasm_interface &wasm) {
return T(wasm);
}
};
template<>
struct class_from_wasm<apply_context> {
/**
* Don't construct a new apply_context, just return a reference to the existing ont
* @param wasm
* @return
*/
static auto &value(wasm_interface &wasm) {
return intrinsics_accessor::get_context(wasm).context;
}
};
/**
* class to represent an in-wasm-memory array
* it is a hint to the transcriber that the next parameter will
* be a size (data bytes length) and that the pair are validated together
* This triggers the template specialization of intrinsic_invoker_impl
* @tparam T
*/
template<typename T>
struct array_ptr {
explicit array_ptr (T * value) : value(value) {}
typename std::add_lvalue_reference<T>::type operator*() const {
return *value;
}
T *operator->() const noexcept {
return value;
}
template<typename U>
operator U *() const {
return static_cast<U *>(value);
}
T *value;
};
/**
* class to represent an in-wasm-memory char array that must be null terminated
*/
struct null_terminated_ptr {
explicit null_terminated_ptr(char* value) : value(value) {}
typename std::add_lvalue_reference<char>::type operator*() const {
return *value;
}
char *operator->() const noexcept {
return value;
}
template<typename U>
operator U *() const {
return static_cast<U *>(value);
}
char *value;
};
} } } } // eosio::chain
此差异已折叠。
......@@ -69,6 +69,8 @@ using boost::asio::io_service;
namespace eosio { namespace chain {
using namespace contracts;
using namespace webassembly;
using namespace webassembly::common;
/**
* Integration with the WASM Linker to resolve our intrinsics
......@@ -251,7 +253,10 @@ namespace eosio { namespace chain {
// find or create a new entry
auto iter = _cache.emplace(code_id, code_info(mem_end, std::move(mem_image))).first;
iter->second.instances.emplace_back(std::make_unique<wasm_cache::entry>(instance, module));
MemoryInstance* default_mem = Runtime::getDefaultMemory(instance);
uint32_t default_sbrk_bytes = default_mem ? Runtime::getMemoryNumPages(default_mem) << IR::numBytesPerPageLog2 : 0;
iter->second.instances.emplace_back(std::make_unique<wasm_cache::entry>(jit::entry{instance, module}, default_sbrk_bytes));
pending_result = optional_entry_ref(*iter->second.instances.back().get());
});
}
......@@ -286,12 +291,12 @@ namespace eosio { namespace chain {
void return_entry(const digest_type& code_id, wasm_cache::entry& entry) {
// sanitize by reseting the memory that may now be dirty
auto& info = (*fetch_info(code_id)).get();
if(getDefaultMemory(entry.instance)) {
char* memstart = &memoryRef<char>( getDefaultMemory(entry.instance), 0 );
if(getDefaultMemory(entry.jit.instance)) {
char* memstart = &memoryRef<char>( getDefaultMemory(entry.jit.instance), 0 );
memset( memstart + info.mem_end, 0, ((1<<16) - info.mem_end) );
memcpy( memstart, info.mem_image.data(), info.mem_end);
}
resetGlobalInstances(entry.instance);
resetGlobalInstances(entry.jit.instance);
// under a lock, put this entry back in the available instances side of the instances vector
with_lock(_cache_lock, [&,this](){
......@@ -336,7 +341,7 @@ namespace eosio { namespace chain {
void wasm_cache::checkin(const digest_type& code_id, entry& code ) {
MemoryInstance* default_mem = Runtime::getDefaultMemory(code.instance);
MemoryInstance* default_mem = Runtime::getDefaultMemory(code.jit.instance);
if(default_mem)
Runtime::shrinkMemory(default_mem, Runtime::getMemoryNumPages(default_mem) - 1);
_my->return_entry(code_id, code);
......@@ -362,15 +367,15 @@ namespace eosio { namespace chain {
void wasm_interface_impl::call(const string& entry_point, const vector<Value>& args, wasm_cache::entry& code, apply_context& context)
try {
FunctionInstance* call = asFunctionNullable(getInstanceExport(code.instance,entry_point) );
FunctionInstance* call = asFunctionNullable(getInstanceExport(code.jit.instance,entry_point) );
if( !call ) {
return;
}
FC_ASSERT( getFunctionType(call)->parameters.size() == args.size() );
auto context_guard = scoped_context(current_context, code, context);
runInstanceStartFunc(code.instance);
auto context_guard = scoped_context(current_context, code, context, code.default_sbrk_bytes);
runInstanceStartFunc(code.jit.instance);
Runtime::invokeFunction(call,args);
} catch( const Runtime::Exception& e ) {
FC_THROW_EXCEPTION(wasm_execution_error,
......@@ -402,6 +407,15 @@ namespace eosio { namespace chain {
my->call("error", args, code, context);
}
wasm_context& common::intrinsics_accessor::get_context(wasm_interface &wasm) {
FC_ASSERT(wasm.my->current_context.valid());
return *wasm.my->current_context;
}
const jit::entry& jit::entry::get(wasm_interface& wasm) {
return common::intrinsics_accessor::get_context(wasm).code.jit;
}
#if defined(assert)
#undef assert
#endif
......@@ -932,7 +946,7 @@ class memory_api : public context_aware_api {
constexpr uint32_t NBPPL2 = IR::numBytesPerPageLog2;
constexpr uint32_t MAX_MEM = 1024 * 1024;
MemoryInstance* default_mem = Runtime::getDefaultMemory(code.instance);
MemoryInstance* default_mem = Runtime::getDefaultMemory(code.jit.instance);
if(!default_mem)
throw eosio::chain::page_memory_error();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册