diff --git a/src/wasmedge/wasmedge.cc b/src/wasmedge/wasmedge.cc index 3359e1b27..69b0e1d9d 100644 --- a/src/wasmedge/wasmedge.cc +++ b/src/wasmedge/wasmedge.cc @@ -361,7 +361,7 @@ bool WasmEdge::link(std::string_view /*debug_name*/) { res = WasmEdge_ExecutorRegisterImport(executor_.get(), store_.get(), it.second->cxt_); if (!WasmEdge_ResultOK(res)) { fail(FailState::UnableToInitializeCode, - std::string("Failed to link Wasm module due to import: ") + it.first); + std::string("Failed to load Wasm module due to import: ") + it.first); return false; } } @@ -370,7 +370,7 @@ bool WasmEdge::link(std::string_view /*debug_name*/) { res = WasmEdge_ExecutorInstantiate(executor_.get(), &mod, store_.get(), ast_module_.get()); if (!WasmEdge_ResultOK(res)) { fail(FailState::UnableToInitializeCode, - std::string("Failed to link Wasm module: ") + std::string(WasmEdge_ResultGetMessage(res))); + std::string("Failed to load Wasm module: ") + std::string(WasmEdge_ResultGetMessage(res))); return false; } // Get the function and memory exports. diff --git a/src/wasmtime/wasmtime.cc b/src/wasmtime/wasmtime.cc index 1961542c0..6d2dbd8b0 100644 --- a/src/wasmtime/wasmtime.cc +++ b/src/wasmtime/wasmtime.cc @@ -254,7 +254,7 @@ bool Wasmtime::link(std::string_view /*debug_name*/) { TrapResult instance = linker_.instantiate(store_->context(), *module_); if (!instance) { fail(FailState::UnableToInitializeCode, - "Failed to create new Wasm instance: " + instance.err().message()); + "Failed to load Wasm module: " + instance.err().message()); return false; } instance_.emplace(instance.ok()); diff --git a/test/BUILD b/test/BUILD index 1b45b1318..57afb906e 100644 --- a/test/BUILD +++ b/test/BUILD @@ -72,6 +72,7 @@ cc_test( data = [ "//test/test_data:callback.wasm", "//test/test_data:clock.wasm", + "//test/test_data:incorrect_import_type.wasm", "//test/test_data:resource_limits.wasm", "//test/test_data:trap.wasm", ], diff --git a/test/runtime_test.cc b/test/runtime_test.cc index a8123806d..af0322419 100644 --- a/test/runtime_test.cc +++ b/test/runtime_test.cc @@ -229,6 +229,23 @@ TEST_P(TestVm, SerializeAndDeserializeRoundTripWorks) { EXPECT_LT(precompiled * 2, unprecompiled); } +TEST_P(TestVm, ImportWithMismatchingTypeFailsLink) { + auto source = readTestWasmFile("incorrect_import_type.wasm"); + ASSERT_FALSE(source.empty()); + auto wasm = TestWasm(std::move(vm_)); + auto *host = dynamic_cast(wasm.wasm_vm()->integration().get()); + + ASSERT_TRUE(wasm.load(source, false)); + ASSERT_FALSE(wasm.initialize()); + + EXPECT_TRUE(host->isErrorLogged("Failed to load Wasm module")); + // TODO: WasmEdge logs the failing import to stderr, but not to the Proxy-Wasm integration logger. + if (engine_ != "wasmedge") { + // The function that has the incorrect type + EXPECT_TRUE(host->isErrorLogged("proxy_done")); + } +} + class TestCounterContext : public TestContext { public: TestCounterContext(WasmBase *wasm) : TestContext(wasm) {} diff --git a/test/test_data/BUILD b/test/test_data/BUILD index 28f723c34..28ee875ef 100644 --- a/test/test_data/BUILD +++ b/test/test_data/BUILD @@ -47,6 +47,11 @@ wasm_rust_binary( srcs = ["bad_malloc.rs"], ) +wasm_rust_binary( + name = "incorrect_import_type.wasm", + srcs = ["incorrect_import_type.rs"], +) + wasm_rust_binary( name = "callback.wasm", srcs = ["callback.rs"], diff --git a/test/test_data/incorrect_import_type.rs b/test/test_data/incorrect_import_type.rs new file mode 100644 index 000000000..199ee4cac --- /dev/null +++ b/test/test_data/incorrect_import_type.rs @@ -0,0 +1,29 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +extern "C" { + // Wrong type! + fn proxy_done(incorrect_arg: u32) -> u32; +} + +#[no_mangle] +pub extern "C" fn proxy_abi_version_0_2_0() {} + +#[no_mangle] +pub extern "C" fn proxy_on_memory_allocate(_: usize) -> *mut u8 { + unsafe { + proxy_done(1234); + } + std::ptr::null_mut() +}