Skip to content
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
26 changes: 26 additions & 0 deletions tslang/test/tester/defaultlib-collector.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,32 @@ if(MODE STREQUAL "jit")
if(NOT WIN32)
run_program("JIT, default library, runtime not passed" "${WORK_DIR}/alone"
"${TSLANG}" --emit=jit ${common} "${alone}")

# Laid out as the release package is, the runtime next to tslang, and run from another
# folder with no --tslang-lib-path: tslang finds it in its own folder. Without it there,
# a clear error rather than the loader's "undefined symbol: GC_malloc" mid-run. A hard
# link, so /proc/self/exe names the package folder (a symlink resolves to the build).
set(package "${WORK_DIR}/package")
file(REMOVE_RECURSE "${package}")
file(MAKE_DIRECTORY "${package}")
file(CREATE_LINK "${TSLANG}" "${package}/tslang" COPY_ON_ERROR)
set(no_lib_path ${common})
list(FILTER no_lib_path EXCLUDE REGEX "^--tslang-lib-path=")

execute_process(COMMAND "${package}/tslang" --emit=jit ${no_lib_path} "${alone}"
WORKING_DIRECTORY "${WORK_DIR}/alone"
OUTPUT_VARIABLE out
ERROR_VARIABLE err
RESULT_VARIABLE status)
if(status EQUAL 0 OR NOT err MATCHES "needs the GC runtime, libTypeScriptRuntime.so")
message(FATAL_ERROR "JIT with no runtime to find: exit ${status}\n${out}\n${err}")
endif()
message(STATUS "JIT with no runtime to find: refused")

# the build's runtime is a symlink to its versioned file
file(COPY "${runtime}" DESTINATION "${package}" FOLLOW_SYMLINK_CHAIN)
run_program("JIT, default library, runtime next to tslang" "${WORK_DIR}/alone"
"${package}/tslang" --emit=jit ${no_lib_path} "${alone}")
endif()
elseif(MODE STREQUAL "compile")
run("--emit=exe alone, default library" "${WORK_DIR}/alone"
Expand Down
60 changes: 34 additions & 26 deletions tslang/tslang/jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ std::string mergeWithDefaultLibPath(std::string, std::string);
std::string getDefaultLibSubDir(bool, bool, const char *, const llvm::Triple &);
std::string getDefaultLibBinary(bool, const CompileOptions &, const llvm::Triple &);
std::string makeAbsolutePath(std::string);
std::string getExecutablePath(const char *);

int registerMLIRDialects(mlir::ModuleOp);
std::function<llvm::Error(llvm::Module *)> getTransformer(bool, int, int, CompileOptions&);
Expand Down Expand Up @@ -649,39 +650,46 @@ static int prepareJitProcess(CompileOptions &compileOptions, bool nativeImage)
return llvm::sys::path::stem(libPath).contains_insensitive("TypeScriptRuntime");
});

std::string pathTypeScriptLib("../lib/" LIB_NAME "TypeScriptRuntime." LIB_EXT);
if (compileOptions.needsGCRuntime() && !hasTypeScriptRuntime && !nativeImage)
{
auto absPath3 = makeAbsolutePath(mergeWithDefaultLibPath(getTslangLibPath(), LIB_NAME "TypeScriptRuntime." LIB_EXT));
if (absPath3.empty())
// --tslang-lib-path (TSLANG_LIB_PATH), then ../lib and the current folder, then beside
// tslang itself: its own folder - where the release package puts it, and the Windows build
// its bin folder - and ../lib, where the Linux build does. A run started from a project
// folder finds it only there.
llvm::SmallString<256> exeDir(getExecutablePath("tslang"));
llvm::sys::path::remove_filename(exeDir);
llvm::SmallString<256> exeRuntimePath(exeDir);
llvm::sys::path::append(exeRuntimePath, LIB_NAME "TypeScriptRuntime." LIB_EXT);
llvm::SmallString<256> exeLibRuntimePath(exeDir);
llvm::sys::path::append(exeLibRuntimePath, "..", "lib", LIB_NAME "TypeScriptRuntime." LIB_EXT);

std::string runtimePath;
for (auto candidate : {mergeWithDefaultLibPath(getTslangLibPath(), LIB_NAME "TypeScriptRuntime." LIB_EXT),
std::string("../lib/" LIB_NAME "TypeScriptRuntime." LIB_EXT),
std::string(LIB_NAME "TypeScriptRuntime." LIB_EXT),
exeRuntimePath.str().str(),
exeLibRuntimePath.str().str()})
{
auto absPath = makeAbsolutePath(pathTypeScriptLib);
if (absPath.empty())
{
pathTypeScriptLib = LIB_NAME "TypeScriptRuntime." LIB_EXT;
auto absPath2 = makeAbsolutePath(pathTypeScriptLib);
if (absPath2.empty())
{
/*
llvm::WithColor::error(llvm::errs(), "tslang") << "JIT initialization failed. Missing GC library. Did you forget to provide it via "
"'--shared-libs=" LIB_NAME "TypeScriptRuntime." LIB_EXT "'? or you can switch it off by using '-mm=none'\n";
return -1;
*/
}
else
{
clSharedLibs.push_back(absPath2);
}
}
else
runtimePath = makeAbsolutePath(candidate);
if (!runtimePath.empty())
{
clSharedLibs.push_back(absPath);
break;
}
}
else
}

// Not left to fail later: the default library and the program call GC_malloc & co., and
// with no runtime loaded that surfaces as an unresolved symbol (on Linux a "symbol lookup
// error" from the loader in the middle of the run) that never names the missing file.
if (runtimePath.empty())
{
clSharedLibs.push_back(absPath3);
llvm::WithColor::error(llvm::errs(), "tslang")
<< "-mm=gc needs the GC runtime, " LIB_NAME "TypeScriptRuntime." LIB_EXT ", and it is not "
<< "next to tslang, in the current folder or in --tslang-lib-path. Pass its folder with "
<< "--tslang-lib-path, or the file with --shared-libs.\n";
return -1;
}

clSharedLibs.push_back(runtimePath);
}

// After the runtime: on Linux the default library leaves GC_* undefined and takes them from
Expand Down
Loading