aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Interpreter/CMakeLists.txt6
-rw-r--r--clang/lib/Interpreter/IncrementalExecutor.cpp2
-rw-r--r--clang/lib/Interpreter/IncrementalExecutor.h11
-rw-r--r--clang/lib/Interpreter/Interpreter.cpp13
-rw-r--r--clang/lib/Interpreter/Wasm.cpp114
-rw-r--r--clang/lib/Interpreter/Wasm.h37
6 files changed, 179 insertions, 4 deletions
diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt
index 9065f99..6a06965 100644
--- a/clang/lib/Interpreter/CMakeLists.txt
+++ b/clang/lib/Interpreter/CMakeLists.txt
@@ -12,6 +12,10 @@ set(LLVM_LINK_COMPONENTS
TargetParser
)
+if (EMSCRIPTEN AND "lld" IN_LIST LLVM_ENABLE_PROJECTS)
+ set(WASM_SRC Wasm.cpp)
+endif()
+
add_clang_library(clangInterpreter
DeviceOffload.cpp
CodeCompletion.cpp
@@ -20,6 +24,8 @@ add_clang_library(clangInterpreter
Interpreter.cpp
InterpreterUtils.cpp
Value.cpp
+ ${WASM_SRC}
+ PARTIAL_SOURCES_INTENDED
DEPENDS
intrinsics_gen
diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp b/clang/lib/Interpreter/IncrementalExecutor.cpp
index 6f03610..1824a5b 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -36,6 +36,8 @@ LLVM_ATTRIBUTE_USED void linkComponents() {
}
namespace clang {
+IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC)
+ : TSCtx(TSC) {}
llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
IncrementalExecutor::createDefaultJITBuilder(
diff --git a/clang/lib/Interpreter/IncrementalExecutor.h b/clang/lib/Interpreter/IncrementalExecutor.h
index b434720..7954cde 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.h
+++ b/clang/lib/Interpreter/IncrementalExecutor.h
@@ -43,16 +43,19 @@ class IncrementalExecutor {
llvm::DenseMap<const PartialTranslationUnit *, llvm::orc::ResourceTrackerSP>
ResourceTrackers;
+protected:
+ IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC);
+
public:
enum SymbolNameKind { IRName, LinkerName };
IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
llvm::orc::LLJITBuilder &JITBuilder, llvm::Error &Err);
- ~IncrementalExecutor();
+ virtual ~IncrementalExecutor();
- llvm::Error addModule(PartialTranslationUnit &PTU);
- llvm::Error removeModule(PartialTranslationUnit &PTU);
- llvm::Error runCtors() const;
+ virtual llvm::Error addModule(PartialTranslationUnit &PTU);
+ virtual llvm::Error removeModule(PartialTranslationUnit &PTU);
+ virtual llvm::Error runCtors() const;
llvm::Error cleanUp();
llvm::Expected<llvm::orc::ExecutorAddr>
getSymbolAddress(llvm::StringRef Name, SymbolNameKind NameKind) const;
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index 7a95278..49dc92d 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -15,6 +15,9 @@
#include "IncrementalExecutor.h"
#include "IncrementalParser.h"
#include "InterpreterUtils.h"
+#ifdef __EMSCRIPTEN__
+#include "Wasm.h"
+#endif // __EMSCRIPTEN__
#include "clang/AST/ASTContext.h"
#include "clang/AST/Mangle.h"
@@ -186,6 +189,12 @@ IncrementalCompilerBuilder::CreateCpp() {
std::vector<const char *> Argv;
Argv.reserve(5 + 1 + UserArgs.size());
Argv.push_back("-xc++");
+#ifdef __EMSCRIPTEN__
+ Argv.push_back("-target");
+ Argv.push_back("wasm32-unknown-emscripten");
+ Argv.push_back("-pie");
+ Argv.push_back("-shared");
+#endif
Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());
std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
@@ -426,8 +435,12 @@ llvm::Error Interpreter::CreateExecutor() {
}
llvm::Error Err = llvm::Error::success();
+#ifdef __EMSCRIPTEN__
+ auto Executor = std::make_unique<WasmIncrementalExecutor>(*TSCtx);
+#else
auto Executor =
std::make_unique<IncrementalExecutor>(*TSCtx, *JITBuilder, Err);
+#endif
if (!Err)
IncrExecutor = std::move(Executor);
diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp
new file mode 100644
index 0000000..1001410
--- /dev/null
+++ b/clang/lib/Interpreter/Wasm.cpp
@@ -0,0 +1,114 @@
+//===----------------- Wasm.cpp - Wasm Interpreter --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements interpreter support for code execution in WebAssembly.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Wasm.h"
+#include "IncrementalExecutor.h"
+
+#include <llvm/IR/LegacyPassManager.h>
+#include <llvm/IR/Module.h>
+#include <llvm/MC/TargetRegistry.h>
+#include <llvm/Target/TargetMachine.h>
+
+#include <clang/Interpreter/Interpreter.h>
+
+#include <string>
+
+namespace lld {
+namespace wasm {
+bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
+ llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput);
+} // namespace wasm
+} // namespace lld
+
+#include <dlfcn.h>
+
+namespace clang {
+
+WasmIncrementalExecutor::WasmIncrementalExecutor(
+ llvm::orc::ThreadSafeContext &TSC)
+ : IncrementalExecutor(TSC) {}
+
+llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
+ std::string ErrorString;
+
+ const llvm::Target *Target = llvm::TargetRegistry::lookupTarget(
+ PTU.TheModule->getTargetTriple(), ErrorString);
+ if (!Target) {
+ return llvm::make_error<llvm::StringError>("Failed to create Wasm Target: ",
+ llvm::inconvertibleErrorCode());
+ }
+
+ llvm::TargetOptions TO = llvm::TargetOptions();
+ llvm::TargetMachine *TargetMachine = Target->createTargetMachine(
+ PTU.TheModule->getTargetTriple(), "", "", TO, llvm::Reloc::Model::PIC_);
+ PTU.TheModule->setDataLayout(TargetMachine->createDataLayout());
+ std::string OutputFileName = PTU.TheModule->getName().str() + ".wasm";
+
+ std::error_code Error;
+ llvm::raw_fd_ostream OutputFile(llvm::StringRef(OutputFileName), Error);
+
+ llvm::legacy::PassManager PM;
+ if (TargetMachine->addPassesToEmitFile(PM, OutputFile, nullptr,
+ llvm::CodeGenFileType::ObjectFile)) {
+ return llvm::make_error<llvm::StringError>(
+ "Wasm backend cannot produce object.", llvm::inconvertibleErrorCode());
+ }
+
+ if (!PM.run(*PTU.TheModule)) {
+
+ return llvm::make_error<llvm::StringError>("Failed to emit Wasm object.",
+ llvm::inconvertibleErrorCode());
+ }
+
+ OutputFile.close();
+
+ std::vector<const char *> LinkerArgs = {"wasm-ld",
+ "-pie",
+ "--import-memory",
+ "--no-entry",
+ "--export-all",
+ "--experimental-pic",
+ "--no-export-dynamic",
+ "--stack-first",
+ OutputFileName.c_str(),
+ "-o",
+ OutputFileName.c_str()};
+ int Result =
+ lld::wasm::link(LinkerArgs, llvm::outs(), llvm::errs(), false, false);
+ if (!Result)
+ return llvm::make_error<llvm::StringError>(
+ "Failed to link incremental module", llvm::inconvertibleErrorCode());
+
+ void *LoadedLibModule =
+ dlopen(OutputFileName.c_str(), RTLD_NOW | RTLD_GLOBAL);
+ if (LoadedLibModule == nullptr) {
+ llvm::errs() << dlerror() << '\n';
+ return llvm::make_error<llvm::StringError>(
+ "Failed to load incremental module", llvm::inconvertibleErrorCode());
+ }
+
+ return llvm::Error::success();
+}
+
+llvm::Error WasmIncrementalExecutor::removeModule(PartialTranslationUnit &PTU) {
+ return llvm::make_error<llvm::StringError>("Not implemented yet",
+ llvm::inconvertibleErrorCode());
+}
+
+llvm::Error WasmIncrementalExecutor::runCtors() const {
+ // This seems to be automatically done when using dlopen()
+ return llvm::Error::success();
+}
+
+WasmIncrementalExecutor::~WasmIncrementalExecutor() = default;
+
+} // namespace clang
diff --git a/clang/lib/Interpreter/Wasm.h b/clang/lib/Interpreter/Wasm.h
new file mode 100644
index 0000000..b1fd880
--- /dev/null
+++ b/clang/lib/Interpreter/Wasm.h
@@ -0,0 +1,37 @@
+//===------------------ Wasm.h - Wasm Interpreter ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements interpreter support for code execution in WebAssembly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_INTERPRETER_WASM_H
+#define LLVM_CLANG_LIB_INTERPRETER_WASM_H
+
+#ifndef __EMSCRIPTEN__
+#error "This requires emscripten."
+#endif // __EMSCRIPTEN__
+
+#include "IncrementalExecutor.h"
+
+namespace clang {
+
+class WasmIncrementalExecutor : public IncrementalExecutor {
+public:
+ WasmIncrementalExecutor(llvm::orc::ThreadSafeContext &TSC);
+
+ llvm::Error addModule(PartialTranslationUnit &PTU) override;
+ llvm::Error removeModule(PartialTranslationUnit &PTU) override;
+ llvm::Error runCtors() const override;
+
+ ~WasmIncrementalExecutor() override;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_LIB_INTERPRETER_WASM_H