diff --git a/bazel/foreign_cc/BUILD b/bazel/foreign_cc/BUILD index 7ae723cf9970..69d2764c6f2a 100644 --- a/bazel/foreign_cc/BUILD +++ b/bazel/foreign_cc/BUILD @@ -276,7 +276,8 @@ envoy_cmake_external( static_libraries = select({ "//conditions:default": [ "libWAVM.a", - "WAVM/libWAVMUnwind.a", + "libWAVMUnwind.a", + "libWAVMgdtoa.a", ], }), deps = [":llvm"], diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index feac4763856b..ac25bc1b1c60 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -248,9 +248,9 @@ REPOSITORY_LOCATIONS = dict( urls = ["http://releases.llvm.org/6.0.1/llvm-6.0.1.src.tar.xz"], ), com_github_wavm_wavm = dict( - sha256 = "1acb11681657a0f32bb8c3d78117c742318c139d43eae70c6d34bbd9d9638135", - strip_prefix = "WAVM-95dbf08c8695b8941e7020c557d8612f9d2af895", - urls = ["https://github.com/WAVM/WAVM/archive/95dbf08c8695b8941e7020c557d8612f9d2af895.tar.gz"], + sha256 = "abebfba303958999ba82aa67075ea7ae1e38388632803d387c6aafbaf67f24c5", + strip_prefix = "WAVM-33f4240d44848c52a817730884572d3b4ae39733", + urls = ["https://github.com/WAVM/WAVM/archive/33f4240d44848c52a817730884572d3b4ae39733.tar.gz"], ), com_googlesource_chromium_v8 = dict( # This archive was created using https://storage.googleapis.com/envoyproxy-wee8/wee8-archive.sh diff --git a/examples/wasm/envoy_filter_http_wasm_example.wasm b/examples/wasm/envoy_filter_http_wasm_example.wasm index 0480cfc67fa2..780899284624 100644 Binary files a/examples/wasm/envoy_filter_http_wasm_example.wasm and b/examples/wasm/envoy_filter_http_wasm_example.wasm differ diff --git a/source/extensions/common/wasm/wavm/BUILD b/source/extensions/common/wasm/wavm/BUILD index f6e8bdb6a584..70ad7cc03270 100644 --- a/source/extensions/common/wasm/wavm/BUILD +++ b/source/extensions/common/wasm/wavm/BUILD @@ -13,13 +13,7 @@ envoy_cc_library( srcs = ["wavm.cc"], hdrs = ["wavm.h"], copts = [ - '-DEMSCRIPTEN_API=""', - '-DPLATFORM_API=""', - '-DRUNTIME_API=""', - '-DLOGGING_API=""', - '-DWASM_API=""', - '-DWASTPARSE_API=""', - '-DIR_API=""', + '-DWAVM_API=""', "-Wno-non-virtual-dtor", "-Wno-old-style-cast", ], diff --git a/source/extensions/common/wasm/wavm/wavm.cc b/source/extensions/common/wasm/wavm/wavm.cc index 83c26d09be98..bb55d9a03abd 100644 --- a/source/extensions/common/wasm/wavm/wavm.cc +++ b/source/extensions/common/wasm/wavm/wavm.cc @@ -25,12 +25,12 @@ #include "WAVM/Inline/IndexMap.h" #include "WAVM/Inline/IntrusiveSharedPtr.h" #include "WAVM/Inline/Lock.h" +#include "WAVM/Inline/Serialization.h" #include "WAVM/Platform/Mutex.h" #include "WAVM/Platform/Thread.h" #include "WAVM/Runtime/Intrinsics.h" #include "WAVM/Runtime/Linker.h" #include "WAVM/Runtime/Runtime.h" -#include "WAVM/Runtime/RuntimeData.h" #include "WAVM/WASM/WASM.h" #include "WAVM/WASTParse/WASTParse.h" #include "absl/container/node_hash_map.h" @@ -73,6 +73,7 @@ struct Wavm; namespace { struct WasmUntaggedValue : public WAVM::IR::UntaggedValue { + WasmUntaggedValue() = default; WasmUntaggedValue(I32 inI32) { i32 = inI32; } WasmUntaggedValue(I64 inI64) { i64 = inI64; } WasmUntaggedValue(U32 inU32) { u32 = inU32; } @@ -97,19 +98,6 @@ const Logger::Id wasmId = Logger::Id::wasm; }); \ } while (0) -#define CALL_WITH_CONTEXT_RETURN(_x, _context, _T, _member) \ - do { \ - SaveRestoreContext _saved_context(static_cast(_context)); \ - _T _return_value; \ - WAVM::Runtime::catchRuntimeExceptions([&] { _return_value = static_cast<_T>(_x[0]._member); }, \ - [&](WAVM::Runtime::Exception* exception) { \ - auto description = describeException(exception); \ - destroyException(exception); \ - throw WasmException(description); \ - }); \ - return _return_value; \ - } while (0) - class RootResolver : public WAVM::Runtime::Resolver, public Logger::Loggable { public: RootResolver(WAVM::Runtime::Compartment*) {} @@ -142,11 +130,16 @@ class RootResolver : public WAVM::Runtime::Resolver, public Logger::Loggableresolve(module_name, export_name, type, out_object)) { + return true; + } + } throw WasmException(fmt::format("Failed to load WASM module due to a missing import: {}.{} {}", module_name, export_name, asString(type))); } @@ -155,8 +148,11 @@ class RootResolver : public WAVM::Runtime::Resolver, public Logger::Loggable module_name_to_instance_map_; + std::vector resolvers_; }; const uint64_t WasmPageSize = 1 << 16; @@ -165,7 +161,8 @@ bool loadModule(const std::string& code, IR::Module& out_module) { // If the code starts with the WASM binary magic number, load it as a binary IR::Module. static const uint8_t WasmMagicNumber[4] = {0x00, 0x61, 0x73, 0x6d}; if (code.size() >= 4 && !memcmp(code.data(), WasmMagicNumber, 4)) { - return WASM::loadBinaryModule(code.data(), code.size(), out_module); + WAVM::Serialization::MemoryInputStream input(code.data(), code.size()); + return WASM::loadBinaryModule(input, out_module); } else { // Load it as a text IR::Module. std::vector parseErrors; @@ -194,7 +191,7 @@ struct WavmGlobal : Global, WavmGlobalBase { WavmGlobal(Common::Wasm::Wavm::Wavm* wavm, Intrinsics::Module& module, const std::string& name, T value) - : Intrinsics::GenericGlobal::type>(module, name.c_str(), + : Intrinsics::GenericGlobal::type>(&module, name.c_str(), ToNative(value)), wavm_(wavm) {} virtual ~WavmGlobal() {} @@ -220,7 +217,8 @@ struct Wavm : public WasmVm { bool cloneable() override { return true; }; std::unique_ptr clone() override; bool load(const std::string& code, bool allow_precompiled) override; - void setMemoryLayout(uint64_t, uint64_t, uint64_t) override {} + void setMemoryLayout(uint64_t stack_base, uint64_t heap_base, + uint64_t heap_base_pointer) override; void link(absl::string_view debug_name, bool needs_emscripten) override; void start(Context* context) override; uint64_t getMemorySize() override; @@ -263,7 +261,7 @@ struct Wavm : public WasmVm { WAVM::Runtime::ModuleRef module_ = nullptr; WAVM::Runtime::GCPointer module_instance_; WAVM::Runtime::Memory* memory_; - Emscripten::Instance* emscripten_instance_ = nullptr; + std::shared_ptr emscripten_instance_; WAVM::Runtime::GCPointer compartment_; WAVM::Runtime::GCPointer context_; absl::node_hash_map intrinsic_modules_; @@ -274,20 +272,18 @@ struct Wavm : public WasmVm { std::unordered_map, WavmGlobalBase*, PairHash> intrinsic_globals_; uint8_t* memory_base_ = nullptr; + uint32_t memory_stack_base_; + uint32_t memory_heap_base_; + uint32_t memory_heap_base_pointer_; }; Wavm::~Wavm() { module_instance_ = nullptr; - if (emscripten_instance_) { - emscripten_instance_->env = nullptr; - emscripten_instance_->global = nullptr; - emscripten_instance_->memory = nullptr; - delete emscripten_instance_; - } context_ = nullptr; intrinsic_module_instances_.clear(); intrinsic_modules_.clear(); envoyFunctions_.clear(); + emscripten_instance_ = nullptr; if (compartment_) { ASSERT(tryCollectCompartment(std::move(compartment_))); } @@ -335,17 +331,23 @@ bool Wavm::load(const std::string& code, bool allow_precompiled) { return true; } +void Wavm::setMemoryLayout(uint64_t stack_base, uint64_t heap_base, uint64_t heap_base_pointer) { + memory_stack_base_ = stack_base; + memory_heap_base_ = heap_base; + memory_heap_base_pointer_ = heap_base_pointer; +} + void Wavm::link(absl::string_view debug_name, bool needs_emscripten) { RootResolver rootResolver(compartment_); for (auto& p : intrinsic_modules_) { - auto instance = Intrinsics::instantiateModule(compartment_, intrinsic_modules_[p.first], + auto instance = Intrinsics::instantiateModule(compartment_, {&intrinsic_modules_[p.first]}, std::string(p.first)); intrinsic_module_instances_.emplace(p.first, instance); rootResolver.moduleNameToInstanceMap().set(p.first, instance); } if (needs_emscripten) { emscripten_instance_ = Emscripten::instantiate(compartment_, ir_module_); - rootResolver.moduleNameToInstanceMap().set("env", emscripten_instance_->env); + rootResolver.addResolver(&WAVM::Emscripten::getInstanceResolver(emscripten_instance_)); } WAVM::Runtime::LinkResult link_result = linkModule(ir_module_, rootResolver); module_instance_ = instantiateModule( @@ -373,10 +375,13 @@ void Wavm::makeModule(absl::string_view name) { } void Wavm::start(Context* context) { + if (emscripten_instance_) { + setMemory(memory_heap_base_pointer_, sizeof(uint32_t), &memory_heap_base_); + } try { auto f = getStartFunction(module_instance_); if (f) { - CALL_WITH_CONTEXT(invokeFunctionChecked(context_, f, {}), context); + CALL_WITH_CONTEXT(invokeFunction(context_, f, getFunctionType(f)), context); } if (emscripten_instance_) { @@ -387,7 +392,7 @@ void Wavm::start(Context* context) { f = asFunctionNullable(getInstanceExport(module_instance_, "__post_instantiate")); if (f) { - CALL_WITH_CONTEXT(invokeFunctionChecked(context_, f, {}), context); + CALL_WITH_CONTEXT(invokeFunction(context_, f, getFunctionType(f)), context); } f = asFunctionNullable(getInstanceExport(module_instance_, "main")); @@ -395,7 +400,7 @@ void Wavm::start(Context* context) { f = asFunctionNullable(getInstanceExport(module_instance_, "_main")); } if (f) { - CALL_WITH_CONTEXT(invokeFunctionChecked(context_, f, {}), context); + CALL_WITH_CONTEXT(invokeFunction(context_, f, getFunctionType(f)), context); } } catch (const std::exception& e) { std::cerr << "Caught exception \"" << e.what() << "\" in WASM\n"; @@ -477,7 +482,7 @@ void registerCallbackWavm(WasmVm* vm, absl::string_view module_name, absl::string_view function_name, R (*f)(Args...)) { auto wavm = static_cast(vm); wavm->envoyFunctions_.emplace_back(new Intrinsics::Function( - wavm->intrinsic_modules_[module_name], function_name.data(), reinterpret_cast(f), + &wavm->intrinsic_modules_[module_name], function_name.data(), reinterpret_cast(f), inferEnvoyFunctionType(f), IR::CallingConvention::intrinsic)); } @@ -589,9 +594,12 @@ void getFunctionWavmReturn(WasmVm* vm, absl::string_view function_name, } *function = [wavm, f](Context* context, Args... args) -> R { WasmUntaggedValue values[] = {args...}; + WasmUntaggedValue return_value; try { - CALL_WITH_CONTEXT_RETURN(invokeFunctionUnchecked(wavm->context_, f, &values[0]), context, - uint32_t, i32); + CALL_WITH_CONTEXT( + invokeFunction(wavm->context_, f, getFunctionType(f), &values[0], &return_value), + context); + return static_cast(return_value.i32); } catch (const std::exception& e) { std::cerr << "Caught exception \"" << e.what() << "\" in WASM\n"; throw; @@ -619,7 +627,7 @@ void getFunctionWavmReturn(WasmVm* vm, absl::string_view function_name, *function = [wavm, f](Context* context, Args... args) -> R { WasmUntaggedValue values[] = {args...}; try { - CALL_WITH_CONTEXT(invokeFunctionUnchecked(wavm->context_, f, &values[0]), context); + CALL_WITH_CONTEXT(invokeFunction(wavm->context_, f, getFunctionType(f), &values[0]), context); } catch (const std::exception& e) { std::cerr << "Caught exception \"" << e.what() << "\" in WASM\n"; throw; @@ -724,7 +732,7 @@ template void WavmGlobal::set(const T& t) { } template <> void WavmGlobal::set(const Word& t) { - setGlobalValue(wavm_->context_, global_, IR::Value(t.u64_)); + setGlobalValue(wavm_->context_, global_, IR::Value(t.u32())); } template diff --git a/test/extensions/access_loggers/wasm/test_data/logging.wasm b/test/extensions/access_loggers/wasm/test_data/logging.wasm index 00b1ecfc705b..4f37ce72e134 100644 Binary files a/test/extensions/access_loggers/wasm/test_data/logging.wasm and b/test/extensions/access_loggers/wasm/test_data/logging.wasm differ diff --git a/test/extensions/filters/http/wasm/test_data/async_call_cpp.wasm b/test/extensions/filters/http/wasm/test_data/async_call_cpp.wasm index e823aff52887..06689b2c3161 100644 Binary files a/test/extensions/filters/http/wasm/test_data/async_call_cpp.wasm and b/test/extensions/filters/http/wasm/test_data/async_call_cpp.wasm differ diff --git a/test/extensions/filters/http/wasm/test_data/grpc_call_cpp.wasm b/test/extensions/filters/http/wasm/test_data/grpc_call_cpp.wasm index ea32e2788d7a..260acf582e30 100644 Binary files a/test/extensions/filters/http/wasm/test_data/grpc_call_cpp.wasm and b/test/extensions/filters/http/wasm/test_data/grpc_call_cpp.wasm differ diff --git a/test/extensions/filters/http/wasm/test_data/grpc_callout_cpp.wasm b/test/extensions/filters/http/wasm/test_data/grpc_callout_cpp.wasm index 4df59786a6a5..0e99867bbb62 100644 Binary files a/test/extensions/filters/http/wasm/test_data/grpc_callout_cpp.wasm and b/test/extensions/filters/http/wasm/test_data/grpc_callout_cpp.wasm differ diff --git a/test/extensions/filters/http/wasm/test_data/headers_cpp.wasm b/test/extensions/filters/http/wasm/test_data/headers_cpp.wasm index 1a8abd854ce8..a5e339af55a5 100644 Binary files a/test/extensions/filters/http/wasm/test_data/headers_cpp.wasm and b/test/extensions/filters/http/wasm/test_data/headers_cpp.wasm differ diff --git a/test/extensions/filters/http/wasm/test_data/http_callout_cpp.wasm b/test/extensions/filters/http/wasm/test_data/http_callout_cpp.wasm index 1cdae9316406..086113cbf492 100644 Binary files a/test/extensions/filters/http/wasm/test_data/http_callout_cpp.wasm and b/test/extensions/filters/http/wasm/test_data/http_callout_cpp.wasm differ diff --git a/test/extensions/filters/http/wasm/test_data/metadata_cpp.wasm b/test/extensions/filters/http/wasm/test_data/metadata_cpp.wasm index d288e857c809..38d31f32aefe 100644 Binary files a/test/extensions/filters/http/wasm/test_data/metadata_cpp.wasm and b/test/extensions/filters/http/wasm/test_data/metadata_cpp.wasm differ diff --git a/test/extensions/filters/http/wasm/test_data/queue_cpp.wasm b/test/extensions/filters/http/wasm/test_data/queue_cpp.wasm index 16a2f42f9333..3a0f2be26ed1 100644 Binary files a/test/extensions/filters/http/wasm/test_data/queue_cpp.wasm and b/test/extensions/filters/http/wasm/test_data/queue_cpp.wasm differ diff --git a/test/extensions/filters/http/wasm/test_data/shared_cpp.wasm b/test/extensions/filters/http/wasm/test_data/shared_cpp.wasm index e6a8ed384f79..75e6a7822742 100644 Binary files a/test/extensions/filters/http/wasm/test_data/shared_cpp.wasm and b/test/extensions/filters/http/wasm/test_data/shared_cpp.wasm differ diff --git a/test/extensions/wasm/test_data/asm2wasm_cpp.wasm b/test/extensions/wasm/test_data/asm2wasm_cpp.wasm index b8f6835cb95f..52027da15a0f 100644 Binary files a/test/extensions/wasm/test_data/asm2wasm_cpp.wasm and b/test/extensions/wasm/test_data/asm2wasm_cpp.wasm differ diff --git a/test/extensions/wasm/test_data/bad_signature_cpp.wasm b/test/extensions/wasm/test_data/bad_signature_cpp.wasm index 8572df5d4564..302cb61d5956 100644 Binary files a/test/extensions/wasm/test_data/bad_signature_cpp.wasm and b/test/extensions/wasm/test_data/bad_signature_cpp.wasm differ diff --git a/test/extensions/wasm/test_data/emscripten_cpp.wasm b/test/extensions/wasm/test_data/emscripten_cpp.wasm index d1a0f54ad644..680740546172 100644 Binary files a/test/extensions/wasm/test_data/emscripten_cpp.wasm and b/test/extensions/wasm/test_data/emscripten_cpp.wasm differ diff --git a/test/extensions/wasm/test_data/logging_cpp.wasm b/test/extensions/wasm/test_data/logging_cpp.wasm index 590aaaca4bdd..1c6760bb9eae 100644 Binary files a/test/extensions/wasm/test_data/logging_cpp.wasm and b/test/extensions/wasm/test_data/logging_cpp.wasm differ diff --git a/test/extensions/wasm/test_data/missing_cpp.wasm b/test/extensions/wasm/test_data/missing_cpp.wasm index 2e3db3135d4f..8637b7836ea1 100644 Binary files a/test/extensions/wasm/test_data/missing_cpp.wasm and b/test/extensions/wasm/test_data/missing_cpp.wasm differ diff --git a/test/extensions/wasm/test_data/segv_cpp.wasm b/test/extensions/wasm/test_data/segv_cpp.wasm index da9497d58527..4d1aedb52798 100644 Binary files a/test/extensions/wasm/test_data/segv_cpp.wasm and b/test/extensions/wasm/test_data/segv_cpp.wasm differ diff --git a/test/extensions/wasm/test_data/stats_cpp.wasm b/test/extensions/wasm/test_data/stats_cpp.wasm index 38f9869c64b9..6c5ca1d5b439 100644 Binary files a/test/extensions/wasm/test_data/stats_cpp.wasm and b/test/extensions/wasm/test_data/stats_cpp.wasm differ