Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

decouple wavm runtime from being required & initial support for platform specific wasm runtimes #7919

Merged
merged 5 commits into from
Sep 16, 2019
Merged
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
21 changes: 14 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ if(APPLE AND UNIX AND "${OPENSSL_ROOT_DIR}" STREQUAL "")
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl")
endif()

# WASM runtimes to enable. Each runtime in this list will have:
# * definition EOSIO_<RUNTIME>_RUNTIME_ENABLED defined in public libchain interface
# * ctest entries with --runtime
list(APPEND EOSIO_WASM_RUNTIMES wabt) #always enable wabt; it works everywhere and parts of eosio still assume it's always available
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
list(APPEND EOSIO_WASM_RUNTIMES wavm)
# WAVM requires LLVM, but move the check up here to a central location so that the EosioTester.cmakes
# can be created with the exact version found
find_package(LLVM REQUIRED CONFIG)
if(LLVM_VERSION_MAJOR VERSION_LESS 7 OR LLVM_VERSION_MAJOR VERSION_GREATER 9)
message(FATAL_ERROR "EOSIO requires an LLVM version 7.0 to 9.0")
endif()
endif()

if(UNIX)
if(APPLE)
set(whole_archive_flag "-force_load")
Expand All @@ -82,13 +96,6 @@ set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
# the pthread dependency through fc.
find_package(Boost 1.67 REQUIRED COMPONENTS program_options unit_test_framework)

# WAVM requires LLVM, but move the check up here to a central location so that the EosioTester.cmakes
# can be created with the exact version found
find_package(LLVM REQUIRED CONFIG)
if(LLVM_VERSION_MAJOR VERSION_LESS 7 OR LLVM_VERSION_MAJOR VERSION_GREATER 9)
message(FATAL_ERROR "EOSIO requires an LLVM version 7.0 to 9.0")
endif()

if( APPLE AND UNIX )
# Apple Specific Options Here
message( STATUS "Configuring EOSIO on macOS" )
Expand Down
8 changes: 5 additions & 3 deletions CMakeModules/EosioTester.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ if( GPERFTOOLS_FOUND )
list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc )
endif()

find_package(LLVM @LLVM_VERSION@ EXACT REQUIRED CONFIG)
llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native DebugInfoDWARF orcjit)
link_directories(${LLVM_LIBRARY_DIR})
if(NOT "@LLVM_FOUND@" STREQUAL "")
find_package(LLVM @LLVM_VERSION@ EXACT REQUIRED CONFIG)
llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native DebugInfoDWARF orcjit)
link_directories(${LLVM_LIBRARY_DIR})
endif()

set( CMAKE_CXX_STANDARD 17 )
set( CMAKE_CXX_EXTENSIONS ON )
Expand Down
8 changes: 5 additions & 3 deletions CMakeModules/EosioTesterBuild.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ if( GPERFTOOLS_FOUND )
list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc )
endif()

find_package(LLVM @LLVM_VERSION@ EXACT REQUIRED CONFIG)
llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native DebugInfoDWARF orcjit)
link_directories(${LLVM_LIBRARY_DIR})
if(NOT "@LLVM_FOUND@" STREQUAL "")
find_package(LLVM @LLVM_VERSION@ EXACT REQUIRED CONFIG)
llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native DebugInfoDWARF orcjit)
link_directories(${LLVM_LIBRARY_DIR})
endif()

set( CMAKE_CXX_STANDARD 17 )
set( CMAKE_CXX_EXTENSIONS ON )
Expand Down
12 changes: 11 additions & 1 deletion libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ else()
endif()
endif()

if("wavm" IN_LIST EOSIO_WASM_RUNTIMES)
set(CHAIN_WAVM_SOURCES "webassembly/wavm.cpp")
endif()

## SORT .cpp by most likely to change / break compile
add_library( eosio_chain
merkle.cpp
Expand Down Expand Up @@ -50,7 +54,7 @@ add_library( eosio_chain
asset.cpp
snapshot.cpp

webassembly/wavm.cpp
${CHAIN_WAVM_SOURCES}
webassembly/wabt.cpp

# get_config.cpp
Expand Down Expand Up @@ -81,6 +85,12 @@ target_include_directories( eosio_chain
"${CMAKE_BINARY_DIR}/libraries/wabt"
)

foreach(RUNTIME ${EOSIO_WASM_RUNTIMES})
string(TOUPPER "${RUNTIME}" RUNTIMEUC)
string(REPLACE "-" "_" RUNTIMEUC ${RUNTIMEUC})
target_compile_definitions(eosio_chain PUBLIC "EOSIO_${RUNTIMEUC}_RUNTIME_ENABLED")
endforeach()

install( TARGETS eosio_chain
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
Expand Down
14 changes: 11 additions & 3 deletions libraries/chain/include/eosio/chain/wasm_interface_private.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ namespace eosio { namespace chain {
struct by_last_block_num;

wasm_interface_impl(wasm_interface::vm_type vm, const chainbase::database& d) : db(d) {
#ifdef EOSIO_WAVM_RUNTIME_ENABLED
if(vm == wasm_interface::vm_type::wavm)
runtime_interface = std::make_unique<webassembly::wavm::wavm_runtime>();
else if(vm == wasm_interface::vm_type::wabt)
#endif
if(vm == wasm_interface::vm_type::wabt)
runtime_interface = std::make_unique<webassembly::wabt_runtime::wabt_runtime>();
else
EOS_THROW(wasm_exception, "wasm_interface_impl fall through");
if(!runtime_interface)
EOS_THROW(wasm_exception, "${r} wasm runtime not supported on this platform and/or configuration", ("r", vm));
swatanabe-b1 marked this conversation as resolved.
Show resolved Hide resolved
}

~wasm_interface_impl() {
Expand Down Expand Up @@ -166,6 +168,12 @@ namespace eosio { namespace chain {
const chainbase::database& db;
};

#define _ADD_PAREN_1(...) ((__VA_ARGS__)) _ADD_PAREN_2
#define _ADD_PAREN_2(...) ((__VA_ARGS__)) _ADD_PAREN_1
#define _ADD_PAREN_1_END
#define _ADD_PAREN_2_END
#define _WRAPPED_SEQ(SEQ) BOOST_PP_CAT(_ADD_PAREN_1 SEQ, _END)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are reserved identifiers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if @b1bart has any thoughts on why there are named that way

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bad habit I suppose. feel free to rename them and properly undefine them it is merely a nod to the idea that they are "internal".

#define _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
_REGISTER_WAVM_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
_REGISTER_WABT_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)
Expand Down
240 changes: 123 additions & 117 deletions libraries/chain/include/eosio/chain/webassembly/wavm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,119 @@ struct running_instance_context {
};
extern running_instance_context the_running_instance_context;

template<typename T>
struct wasm_to_value_type;

template<>
struct wasm_to_value_type<F32> {
static constexpr auto value = ValueType::f32;
};

template<>
struct wasm_to_value_type<F64> {
static constexpr auto value = ValueType::f64;
};
template<>
struct wasm_to_value_type<I32> {
static constexpr auto value = ValueType::i32;
};
template<>
struct wasm_to_value_type<I64> {
static constexpr auto value = ValueType::i64;
};

template<typename T>
constexpr auto wasm_to_value_type_v = wasm_to_value_type<T>::value;

template<typename T>
struct wasm_to_rvalue_type;
template<>
struct wasm_to_rvalue_type<F32> {
static constexpr auto value = ResultType::f32;
};
template<>
struct wasm_to_rvalue_type<F64> {
static constexpr auto value = ResultType::f64;
};
template<>
struct wasm_to_rvalue_type<I32> {
static constexpr auto value = ResultType::i32;
};
template<>
struct wasm_to_rvalue_type<I64> {
static constexpr auto value = ResultType::i64;
};
template<>
struct wasm_to_rvalue_type<void> {
static constexpr auto value = ResultType::none;
};
template<>
struct wasm_to_rvalue_type<const name&> {
static constexpr auto value = ResultType::i64;
};
template<>
struct wasm_to_rvalue_type<name> {
static constexpr auto value = ResultType::i64;
};

template<>
struct wasm_to_rvalue_type<char*> {
static constexpr auto value = ResultType::i32;
};

template<>
struct wasm_to_rvalue_type<fc::time_point_sec> {
static constexpr auto value = ResultType::i32;
};


template<typename T>
constexpr auto wasm_to_rvalue_type_v = wasm_to_rvalue_type<T>::value;

template<typename T>
struct is_reference_from_value {
static constexpr bool value = false;
};

template<>
struct is_reference_from_value<name> {
static constexpr bool value = true;
};

template<>
struct is_reference_from_value<fc::time_point_sec> {
static constexpr bool value = true;
};

template<typename T>
constexpr bool is_reference_from_value_v = is_reference_from_value<T>::value;



struct void_type {
};

/**
* Forward declaration of provider for FunctionType given a desired C ABI signature
*/
template<typename>
struct wasm_function_type_provider;

/**
* specialization to destructure return and arguments
*/
template<typename Ret, typename ...Args>
struct wasm_function_type_provider<Ret(Args...)> {
static const FunctionType *type() {
return FunctionType::get(wasm_to_rvalue_type_v<Ret>, {wasm_to_value_type_v<Args> ...});
}
};

#define __INTRINSIC_NAME(LABEL, SUFFIX) LABEL##SUFFIX
#define _INTRINSIC_NAME(LABEL, SUFFIX) __INTRINSIC_NAME(LABEL,SUFFIX)

#ifdef EOSIO_WAVM_RUNTIME_ENABLED

/**
* class to represent an in-wasm-memory array
* it is a hint to the transcriber that the next parameter will
Expand Down Expand Up @@ -174,114 +287,6 @@ inline auto convert_wasm_to_native(native_to_wasm_t<T> val) {
return T(val);
}

template<typename T>
struct wasm_to_value_type;

template<>
struct wasm_to_value_type<F32> {
static constexpr auto value = ValueType::f32;
};

template<>
struct wasm_to_value_type<F64> {
static constexpr auto value = ValueType::f64;
};
template<>
struct wasm_to_value_type<I32> {
static constexpr auto value = ValueType::i32;
};
template<>
struct wasm_to_value_type<I64> {
static constexpr auto value = ValueType::i64;
};

template<typename T>
constexpr auto wasm_to_value_type_v = wasm_to_value_type<T>::value;

template<typename T>
struct wasm_to_rvalue_type;
template<>
struct wasm_to_rvalue_type<F32> {
static constexpr auto value = ResultType::f32;
};
template<>
struct wasm_to_rvalue_type<F64> {
static constexpr auto value = ResultType::f64;
};
template<>
struct wasm_to_rvalue_type<I32> {
static constexpr auto value = ResultType::i32;
};
template<>
struct wasm_to_rvalue_type<I64> {
static constexpr auto value = ResultType::i64;
};
template<>
struct wasm_to_rvalue_type<void> {
static constexpr auto value = ResultType::none;
};
template<>
struct wasm_to_rvalue_type<const name&> {
static constexpr auto value = ResultType::i64;
};
template<>
struct wasm_to_rvalue_type<name> {
static constexpr auto value = ResultType::i64;
};

template<>
struct wasm_to_rvalue_type<char*> {
static constexpr auto value = ResultType::i32;
};

template<>
struct wasm_to_rvalue_type<fc::time_point_sec> {
static constexpr auto value = ResultType::i32;
};


template<typename T>
constexpr auto wasm_to_rvalue_type_v = wasm_to_rvalue_type<T>::value;

template<typename T>
struct is_reference_from_value {
static constexpr bool value = false;
};

template<>
struct is_reference_from_value<name> {
static constexpr bool value = true;
};

template<>
struct is_reference_from_value<fc::time_point_sec> {
static constexpr bool value = true;
};

template<typename T>
constexpr bool is_reference_from_value_v = is_reference_from_value<T>::value;



struct void_type {
};

/**
* Forward declaration of provider for FunctionType given a desired C ABI signature
*/
template<typename>
struct wasm_function_type_provider;

/**
* specialization to destructure return and arguments
*/
template<typename Ret, typename ...Args>
struct wasm_function_type_provider<Ret(Args...)> {
static const FunctionType *type() {
return FunctionType::get(wasm_to_rvalue_type_v<Ret>, {wasm_to_value_type_v<Args> ...});
}
};

/**
* Forward declaration of the invoker type which transcribes arguments to/from a native method
* and injects the appropriate checks
Expand Down Expand Up @@ -698,21 +703,22 @@ struct intrinsic_function_invoker_wrapper<WasmSig, Ret (Cls::*)(Params...) const
using type = intrinsic_function_invoker<WasmSig, Ret, Ret (Cls::*)(Params...) const volatile, Cls, Params...>;
};

#define _ADD_PAREN_1(...) ((__VA_ARGS__)) _ADD_PAREN_2
#define _ADD_PAREN_2(...) ((__VA_ARGS__)) _ADD_PAREN_1
#define _ADD_PAREN_1_END
#define _ADD_PAREN_2_END
#define _WRAPPED_SEQ(SEQ) BOOST_PP_CAT(_ADD_PAREN_1 SEQ, _END)
#define _REGISTER_WAVM_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
static Intrinsics::Function _INTRINSIC_NAME(__intrinsic_fn, __COUNTER__) (\
MOD "." NAME,\
eosio::chain::webassembly::wavm::wasm_function_type_provider<WASM_SIG>::type(),\
(void *)eosio::chain::webassembly::wavm::intrinsic_function_invoker_wrapper<WASM_SIG, SIG>::type::fn<&CLS::METHOD>()\
);

#define __INTRINSIC_NAME(LABEL, SUFFIX) LABEL##SUFFIX
#define _INTRINSIC_NAME(LABEL, SUFFIX) __INTRINSIC_NAME(LABEL,SUFFIX)
#else

#define _REGISTER_WAVM_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
static Intrinsics::Function _INTRINSIC_NAME(__intrinsic_fn, __COUNTER__) (\
MOD "." NAME,\
eosio::chain::webassembly::wavm::wasm_function_type_provider<WASM_SIG>::type(),\
(void *)eosio::chain::webassembly::wavm::intrinsic_function_invoker_wrapper<WASM_SIG, SIG>::type::fn<&CLS::METHOD>()\
);\
nullptr\
);

#endif

} } } }// eosio::chain::webassembly::wavm
Loading