diff --git a/lib/Interpreter/CppInterOpInterpreter.h b/lib/Interpreter/CppInterOpInterpreter.h index b5b8e7e96..3a766c0cc 100644 --- a/lib/Interpreter/CppInterOpInterpreter.h +++ b/lib/Interpreter/CppInterOpInterpreter.h @@ -400,6 +400,17 @@ class Interpreter { } CompilationResult loadLibrary(const std::string& filename, bool lookup) { +#ifdef __EMSCRIPTEN__ + if (lookup) { + llvm::errs() << "[cppinterop] Warning: 'lookup' has no effect on WASM.\n"; + } + // In WASM: directly use Interpreter's LoadDynamicLibrary + if (auto Err = inner->LoadDynamicLibrary(filename.c_str())) { + llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "loadLibrary: "); + return kFailure; + } + return kSuccess; +#endif DynamicLibraryManager* DLM = getDynamicLibraryManager(); std::string canonicalLib; if (lookup) diff --git a/unittests/CppInterOp/CMakeLists.txt b/unittests/CppInterOp/CMakeLists.txt index 734714238..6fe8e0527 100644 --- a/unittests/CppInterOp/CMakeLists.txt +++ b/unittests/CppInterOp/CMakeLists.txt @@ -91,6 +91,7 @@ if(EMSCRIPTEN) PUBLIC "SHELL: -s STACK_SIZE=32mb" PUBLIC "SHELL: -s INITIAL_MEMORY=128mb" PUBLIC "SHELL: --preload-file ${SYSROOT_PATH}/include@/include" + PUBLIC "SHELL: --preload-file ${CMAKE_CURRENT_BINARY_DIR}/unittests/bin/libTestSharedLib.so@/libTestSharedLib.so" ) endif() diff --git a/unittests/CppInterOp/DynamicLibraryManagerTest.cpp b/unittests/CppInterOp/DynamicLibraryManagerTest.cpp index c881d9fdd..f87e44a3c 100644 --- a/unittests/CppInterOp/DynamicLibraryManagerTest.cpp +++ b/unittests/CppInterOp/DynamicLibraryManagerTest.cpp @@ -57,3 +57,31 @@ TEST(DynamicLibraryManagerTest, Sanity) { // invalidated... // EXPECT_FALSE(Cpp::GetFunctionAddress("ret_zero")); } + +TEST(DynamicLibraryManagerTest, BasicSymbolLookup) { +#ifndef EMSCRIPTEN + GTEST_SKIP() << "This test is only intended for Emscripten builds."; +#endif + + // 1. Create interpreter + ASSERT_TRUE(Cpp::CreateInterpreter()); + + // 2. Before loading, the symbol should not exist + EXPECT_FALSE(Cpp::GetFunctionAddress("ret_zero")); + + // 3. Load the library manually. Use exact known preload path (MEMFS path) + const char* wasmLibPath = "libTestSharedLib.so"; // Preloaded path in MEMFS + EXPECT_TRUE(Cpp::LoadLibrary(wasmLibPath, false)); + + // 4. Force engine setup (optional here) + Cpp::Process(""); + + // 5. Symbol should now be found + void* Addr = Cpp::GetFunctionAddress("ret_zero"); + EXPECT_NE(Addr, nullptr) << "Symbol 'ret_zero' not found after dlopen."; + + // 6. Optionally, cast and call to test actual function (should return 0) + using RetZeroFn = int (*)(); + RetZeroFn Fn = reinterpret_cast(Addr); + EXPECT_EQ(Fn(), 0); +}