diff --git a/CMakeLists.txt b/CMakeLists.txt index f26266ec320..66cae2ee1ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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_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") @@ -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" ) diff --git a/CMakeModules/EosioTester.cmake.in b/CMakeModules/EosioTester.cmake.in index 47ef8b44383..f0e45ee5c4a 100644 --- a/CMakeModules/EosioTester.cmake.in +++ b/CMakeModules/EosioTester.cmake.in @@ -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 ) diff --git a/CMakeModules/EosioTesterBuild.cmake.in b/CMakeModules/EosioTesterBuild.cmake.in index 118db06e1fa..954b0cd645d 100644 --- a/CMakeModules/EosioTesterBuild.cmake.in +++ b/CMakeModules/EosioTesterBuild.cmake.in @@ -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 ) diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index 66a357946ff..91bf9bb37fb 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -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 @@ -50,7 +54,7 @@ add_library( eosio_chain asset.cpp snapshot.cpp - webassembly/wavm.cpp + ${CHAIN_WAVM_SOURCES} webassembly/wabt.cpp # get_config.cpp @@ -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} diff --git a/libraries/chain/include/eosio/chain/wasm_interface_private.hpp b/libraries/chain/include/eosio/chain/wasm_interface_private.hpp index 973e0a67efa..21d83383a52 100644 --- a/libraries/chain/include/eosio/chain/wasm_interface_private.hpp +++ b/libraries/chain/include/eosio/chain/wasm_interface_private.hpp @@ -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(); - else if(vm == wasm_interface::vm_type::wabt) +#endif + if(vm == wasm_interface::vm_type::wabt) runtime_interface = std::make_unique(); - 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)); } ~wasm_interface_impl() { @@ -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) + #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) diff --git a/libraries/chain/include/eosio/chain/webassembly/wavm.hpp b/libraries/chain/include/eosio/chain/webassembly/wavm.hpp index a19c0b3662b..01c41c8ce75 100644 --- a/libraries/chain/include/eosio/chain/webassembly/wavm.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/wavm.hpp @@ -32,6 +32,119 @@ struct running_instance_context { }; extern running_instance_context the_running_instance_context; +template +struct wasm_to_value_type; + +template<> +struct wasm_to_value_type { + static constexpr auto value = ValueType::f32; +}; + +template<> +struct wasm_to_value_type { + static constexpr auto value = ValueType::f64; +}; +template<> +struct wasm_to_value_type { + static constexpr auto value = ValueType::i32; +}; +template<> +struct wasm_to_value_type { + static constexpr auto value = ValueType::i64; +}; + +template +constexpr auto wasm_to_value_type_v = wasm_to_value_type::value; + +template +struct wasm_to_rvalue_type; +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::f32; +}; +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::f64; +}; +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::i32; +}; +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::i64; +}; +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::none; +}; +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::i64; +}; +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::i64; +}; + +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::i32; +}; + +template<> +struct wasm_to_rvalue_type { + static constexpr auto value = ResultType::i32; +}; + + +template +constexpr auto wasm_to_rvalue_type_v = wasm_to_rvalue_type::value; + +template +struct is_reference_from_value { + static constexpr bool value = false; +}; + +template<> +struct is_reference_from_value { + static constexpr bool value = true; +}; + +template<> +struct is_reference_from_value { + static constexpr bool value = true; +}; + +template +constexpr bool is_reference_from_value_v = is_reference_from_value::value; + + + +struct void_type { +}; + +/** + * Forward declaration of provider for FunctionType given a desired C ABI signature + */ +template +struct wasm_function_type_provider; + +/** + * specialization to destructure return and arguments + */ +template +struct wasm_function_type_provider { + static const FunctionType *type() { + return FunctionType::get(wasm_to_rvalue_type_v, {wasm_to_value_type_v ...}); + } +}; + +#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 @@ -174,114 +287,6 @@ inline auto convert_wasm_to_native(native_to_wasm_t val) { return T(val); } -template -struct wasm_to_value_type; - -template<> -struct wasm_to_value_type { - static constexpr auto value = ValueType::f32; -}; - -template<> -struct wasm_to_value_type { - static constexpr auto value = ValueType::f64; -}; -template<> -struct wasm_to_value_type { - static constexpr auto value = ValueType::i32; -}; -template<> -struct wasm_to_value_type { - static constexpr auto value = ValueType::i64; -}; - -template -constexpr auto wasm_to_value_type_v = wasm_to_value_type::value; - -template -struct wasm_to_rvalue_type; -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::f32; -}; -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::f64; -}; -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::i32; -}; -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::i64; -}; -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::none; -}; -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::i64; -}; -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::i64; -}; - -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::i32; -}; - -template<> -struct wasm_to_rvalue_type { - static constexpr auto value = ResultType::i32; -}; - - -template -constexpr auto wasm_to_rvalue_type_v = wasm_to_rvalue_type::value; - -template -struct is_reference_from_value { - static constexpr bool value = false; -}; - -template<> -struct is_reference_from_value { - static constexpr bool value = true; -}; - -template<> -struct is_reference_from_value { - static constexpr bool value = true; -}; - -template -constexpr bool is_reference_from_value_v = is_reference_from_value::value; - - - -struct void_type { -}; - -/** - * Forward declaration of provider for FunctionType given a desired C ABI signature - */ -template -struct wasm_function_type_provider; - -/** - * specialization to destructure return and arguments - */ -template -struct wasm_function_type_provider { - static const FunctionType *type() { - return FunctionType::get(wasm_to_rvalue_type_v, {wasm_to_value_type_v ...}); - } -}; - /** * Forward declaration of the invoker type which transcribes arguments to/from a native method * and injects the appropriate checks @@ -698,21 +703,22 @@ struct intrinsic_function_invoker_wrapper; }; -#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::type(),\ + (void *)eosio::chain::webassembly::wavm::intrinsic_function_invoker_wrapper::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::type(),\ - (void *)eosio::chain::webassembly::wavm::intrinsic_function_invoker_wrapper::type::fn<&CLS::METHOD>()\ - );\ + nullptr\ + ); +#endif } } } }// eosio::chain::webassembly::wavm diff --git a/libraries/wasm-jit/Include/Runtime/Intrinsics.h b/libraries/wasm-jit/Include/Runtime/Intrinsics.h index fa3e6f2b8a0..e5d37f3b7d9 100644 --- a/libraries/wasm-jit/Include/Runtime/Intrinsics.h +++ b/libraries/wasm-jit/Include/Runtime/Intrinsics.h @@ -17,78 +17,6 @@ namespace Intrinsics private: const char* name; }; - - // The base class of Intrinsic globals. - struct Global - { - Runtime::GlobalInstance* global; - - RUNTIME_API Global(const char* inName,IR::GlobalType inType); - RUNTIME_API ~Global(); - - RUNTIME_API void reset(); - - protected: - void* value; - private: - const char* name; - IR::GlobalType globalType; - }; - - // A partially specialized template for Intrinsic globals: - // Provides access via implicit coercion to a value, and for mutable globals an assignment operator. - template - struct GenericGlobal : Global - { - typedef typename IR::ValueTypeInfo::Value Value; - - GenericGlobal(const char* inName,Value inValue) - : Global(inName,IR::GlobalType(type,isMutable)) { *(Value*)value = inValue; } - - operator Value() const { return *(Value*)value; } - void operator=(Value newValue) { *(Value*)value = newValue; } - }; - template - struct GenericGlobal : Global - { - typedef typename IR::ValueTypeInfo::Value Value; - - GenericGlobal(const char* inName,Value inValue) - : Global(inName,IR::GlobalType(type,false)) { *(Value*)value = inValue; } - - operator Value() const { return *(Value*)value; } - - void reset(Value inValue) - { - Global::reset(); - *(Value*)value = inValue; - } - }; - - // Intrinsic memories and tables - struct Memory - { - RUNTIME_API Memory(const char* inName,const IR::MemoryType& inType); - RUNTIME_API ~Memory(); - - operator Runtime::MemoryInstance*() const { return memory; } - - private: - const char* name; - Runtime::MemoryInstance* const memory; - }; - - struct Table - { - RUNTIME_API Table(const char* inName,const IR::TableType& inType); - RUNTIME_API ~Table(); - - operator Runtime::TableInstance*() const { return table; } - - private: - const char* name; - Runtime::TableInstance* const table; - }; // Finds an intrinsic object by name and type. RUNTIME_API Runtime::ObjectInstance* find(const std::string& name,const IR::ObjectType& type); diff --git a/libraries/wasm-jit/Source/Runtime/CMakeLists.txt b/libraries/wasm-jit/Source/Runtime/CMakeLists.txt index b8016437563..96291858da3 100644 --- a/libraries/wasm-jit/Source/Runtime/CMakeLists.txt +++ b/libraries/wasm-jit/Source/Runtime/CMakeLists.txt @@ -8,19 +8,26 @@ endif() set(Sources Intrinsics.cpp Linker.cpp - LLVMEmitIR.cpp - LLVMJIT.cpp LLVMJIT.h - Memory.cpp - ModuleInstance.cpp ObjectGC.cpp - Runtime.cpp RuntimePrivate.h - Table.cpp Threads.cpp WAVMIntrinsics.cpp - ${LLVM_SHIM_FILE} ) + +if("wavm" IN_LIST EOSIO_WASM_RUNTIMES) + list(APPEND Sources + LLVMEmitIR.cpp + LLVMJIT.cpp + Memory.cpp + ModuleInstance.cpp + Runtime.cpp + Table.cpp + ${LLVM_SHIM_FILE} + ) + llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native DebugInfoDWARF orcjit) +endif() + set(PublicHeaders ${WAVM_INCLUDE_DIR}/Runtime/Intrinsics.h ${WAVM_INCLUDE_DIR}/Runtime/Linker.h @@ -39,7 +46,6 @@ add_definitions(-DRUNTIME_API=DLL_EXPORT) target_include_directories( Runtime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../chain/include ) # Link against the LLVM libraries -llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native DebugInfoDWARF orcjit) target_link_libraries(Runtime Platform Logging IR ${LLVM_LIBS}) install(TARGETS Runtime diff --git a/libraries/wasm-jit/Source/Runtime/Intrinsics.cpp b/libraries/wasm-jit/Source/Runtime/Intrinsics.cpp index f62fb477adb..11f5dc3a3f1 100644 --- a/libraries/wasm-jit/Source/Runtime/Intrinsics.cpp +++ b/libraries/wasm-jit/Source/Runtime/Intrinsics.cpp @@ -11,9 +11,6 @@ namespace Intrinsics struct Singleton { std::map functionMap; - std::map variableMap; - std::map memoryMap; - std::map tableMap; Platform::Mutex* mutex; Singleton(): mutex(Platform::createMutex()) {} @@ -51,71 +48,6 @@ namespace Intrinsics delete function; } - Global::Global(const char* inName,IR::GlobalType inType) - : name(inName) - , globalType(inType) - { - global = Runtime::createGlobal(inType,Runtime::Value((I64)0)); - value = &global->value; - { - Platform::Lock lock(Singleton::get().mutex); - Singleton::get().variableMap[getDecoratedName(inName,inType)] = this; - } - } - - Global::~Global() - { - { - Platform::Lock Lock(Singleton::get().mutex); - Singleton::get().variableMap.erase(Singleton::get().variableMap.find(getDecoratedName(name,global->type))); - } - delete global; - } - - void Global::reset() - { - global = Runtime::createGlobal(globalType,Runtime::Value((I64)0)); - value = &global->value; - } - - Table::Table(const char* inName,const IR::TableType& type) - : name(inName) - , table(Runtime::createTable(type)) - { - if(!table) { Errors::fatal("failed to create intrinsic table"); } - - Platform::Lock lock(Singleton::get().mutex); - Singleton::get().tableMap[getDecoratedName(inName,type)] = this; - } - - Table::~Table() - { - { - Platform::Lock Lock(Singleton::get().mutex); - Singleton::get().tableMap.erase(Singleton::get().tableMap.find(getDecoratedName(name,table->type))); - } - delete table; - } - - Memory::Memory(const char* inName,const IR::MemoryType& type) - : name(inName) - , memory(Runtime::createMemory(type)) - { - if(!memory) { Errors::fatal("failed to create intrinsic memory"); } - - Platform::Lock lock(Singleton::get().mutex); - Singleton::get().memoryMap[getDecoratedName(inName,type)] = this; - } - - Memory::~Memory() - { - { - Platform::Lock Lock(Singleton::get().mutex); - Singleton::get().memoryMap.erase(Singleton::get().memoryMap.find(getDecoratedName(name,memory->type))); - } - delete memory; - } - Runtime::ObjectInstance* find(const std::string& name,const IR::ObjectType& type) { std::string decoratedName = getDecoratedName(name,type); @@ -131,20 +63,17 @@ namespace Intrinsics } case IR::ObjectKind::table: { - auto keyValue = Singleton::get().tableMap.find(decoratedName); - result = keyValue == Singleton::get().tableMap.end() ? nullptr : asObject((Runtime::TableInstance*)*keyValue->second); + result = nullptr; break; } case IR::ObjectKind::memory: { - auto keyValue = Singleton::get().memoryMap.find(decoratedName); - result = keyValue == Singleton::get().memoryMap.end() ? nullptr : asObject((Runtime::MemoryInstance*)*keyValue->second); + result = nullptr; break; } case IR::ObjectKind::global: { - auto keyValue = Singleton::get().variableMap.find(decoratedName); - result = keyValue == Singleton::get().variableMap.end() ? nullptr : asObject(keyValue->second->global); + result = nullptr; break; } default: Errors::unreachable(); @@ -158,9 +87,6 @@ namespace Intrinsics Platform::Lock lock(Singleton::get().mutex); std::vector result; for(auto mapIt : Singleton::get().functionMap) { result.push_back(mapIt.second->function); } - for(auto mapIt : Singleton::get().tableMap) { result.push_back((Runtime::TableInstance*)*mapIt.second); } - for(auto mapIt : Singleton::get().memoryMap) { result.push_back((Runtime::MemoryInstance*)*mapIt.second); } - for(auto mapIt : Singleton::get().variableMap) { result.push_back(mapIt.second->global); } return result; } } diff --git a/libraries/wasm-jit/Source/Runtime/Linker.cpp b/libraries/wasm-jit/Source/Runtime/Linker.cpp index 5675e44e36e..0e73cefbdad 100644 --- a/libraries/wasm-jit/Source/Runtime/Linker.cpp +++ b/libraries/wasm-jit/Source/Runtime/Linker.cpp @@ -12,6 +12,20 @@ namespace Runtime { RUNTIME_API IntrinsicResolver IntrinsicResolver::singleton; + bool isA(ObjectInstance* object,const ObjectType& type) + { + if(type.kind != object->kind) { return false; } + + switch(type.kind) + { + case ObjectKind::function: return asFunctionType(type) == asFunction(object)->type; + case ObjectKind::global: return asGlobalType(type) == asGlobal(object)->type; + case ObjectKind::table: return isSubset(asTableType(type),asTable(object)->type); + case ObjectKind::memory: return isSubset(asMemoryType(type),asMemory(object)->type); + default: Errors::unreachable(); + } + } + bool IntrinsicResolver::resolve(const std::string& moduleName,const std::string& exportName,ObjectType type,ObjectInstance*& outObject) { // Make sure the wavmIntrinsics module can't be directly imported. diff --git a/libraries/wasm-jit/Source/Runtime/Runtime.cpp b/libraries/wasm-jit/Source/Runtime/Runtime.cpp index 7508a6caf87..2de03ef7801 100644 --- a/libraries/wasm-jit/Source/Runtime/Runtime.cpp +++ b/libraries/wasm-jit/Source/Runtime/Runtime.cpp @@ -40,20 +40,6 @@ namespace Runtime throw Exception {cause,describeCallStack(callStack)}; } - bool isA(ObjectInstance* object,const ObjectType& type) - { - if(type.kind != object->kind) { return false; } - - switch(type.kind) - { - case ObjectKind::function: return asFunctionType(type) == asFunction(object)->type; - case ObjectKind::global: return asGlobalType(type) == asGlobal(object)->type; - case ObjectKind::table: return isSubset(asTableType(type),asTable(object)->type); - case ObjectKind::memory: return isSubset(asMemoryType(type),asMemory(object)->type); - default: Errors::unreachable(); - } - } - [[noreturn]] void handleHardwareTrap(Platform::HardwareTrapType trapType,Platform::CallStack&& trapCallStack,Uptr trapOperand) { std::cerr << "handle hardware trap\n"; diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index aa846083147..87b069f95a1 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -197,7 +197,7 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip ("protocol-features-dir", bpo::value()->default_value("protocol_features"), "the location of the protocol_features directory (absolute path or relative to application config dir)") ("checkpoint", bpo::value>()->composing(), "Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints.") - ("wasm-runtime", bpo::value()->value_name("wavm/wabt"), "Override default WASM runtime") + ("wasm-runtime", bpo::value()->value_name("runtime"), "Override default WASM runtime") ("abi-serializer-max-time-ms", bpo::value()->default_value(config::default_abi_serializer_max_time_ms), "Override default maximum ABI serialization time allowed in ms") ("chain-state-db-size-mb", bpo::value()->default_value(config::default_state_size / (1024 * 1024)), "Maximum size (in MiB) of the chain state database") diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 7ff6ade4f20..26b859b5a53 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -56,23 +56,25 @@ foreach(TEST_SUITE ${UNIT_TESTS}) # create an independent target for each test s if (NOT "" STREQUAL "${SUITE_NAME}") # ignore empty lines execute_process(COMMAND bash -c "echo ${SUITE_NAME} | sed -e 's/s$//' | sed -e 's/_test$//'" OUTPUT_VARIABLE TRIMMED_SUITE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE) # trim "_test" or "_tests" from the end of ${SUITE_NAME} # to run unit_test with all log from blockchain displayed, put "--verbose" after "--", i.e. "unit_test -- --verbose" - add_test(NAME ${TRIMMED_SUITE_NAME}_unit_test_wavm COMMAND unit_test --run_test=${SUITE_NAME} --report_level=detailed --color_output --catch_system_errors=no -- --wavm) - add_test(NAME ${TRIMMED_SUITE_NAME}_unit_test_wabt COMMAND unit_test --run_test=${SUITE_NAME} --report_level=detailed --color_output -- --wabt) - # build list of tests to run during coverage testing - if(NOT "" STREQUAL "${ctest_tests}") - set(ctest_tests "${ctest_tests}|${TRIMMED_SUITE_NAME}_unit_test_wavm|${TRIMMED_SUITE_NAME}_unit_test_wabt") - else() - set(ctest_tests "${TRIMMED_SUITE_NAME}_unit_test_wavm|${TRIMMED_SUITE_NAME}_unit_test_wabt") - endif() + foreach(RUNTIME ${EOSIO_WASM_RUNTIMES}) + add_test(NAME ${TRIMMED_SUITE_NAME}_unit_test_${RUNTIME} COMMAND unit_test --run_test=${SUITE_NAME} --report_level=detailed --color_output --catch_system_errors=no -- --${RUNTIME}) + # build list of tests to run during coverage testing + if(ctest_tests) + string(APPEND ctest_tests "|") + endif() + string(APPEND ctest_tests ${TRIMMED_SUITE_NAME}_unit_test_$RUNTIME) + endforeach() endif() endforeach(TEST_SUITE) set(ctest_tests "'${ctest_tests}' -j8") # surround test list string in apostrophies # The following tests are known to take the longest, bump up their cost (priority) so that they'll run first # even on fresh first time test runs before ctest auto-detects costs -set_tests_properties(api_unit_test_wavm api_unit_test_wabt PROPERTIES COST 5000) -set_tests_properties(wasm_unit_test_wavm wasm_unit_test_wabt PROPERTIES COST 4000) -set_tests_properties(delay_unit_test_wavm delay_unit_test_wabt PROPERTIES COST 3000) +foreach(RUNTIME ${EOSIO_WASM_RUNTIMES}) + set_tests_properties(api_unit_test_${RUNTIME} PROPERTIES COST 5000) + set_tests_properties(wasm_unit_test_${RUNTIME} PROPERTIES COST 4000) + set_tests_properties(delay_unit_test_${RUNTIME} PROPERTIES COST 3000) +endforeach() ### COVERAGE TESTING ### if(ENABLE_COVERAGE_TESTING)