diff --git a/CMakeLists.txt b/CMakeLists.txt index ede663a..2ab094a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ file(GLOB SOURCE_FILES add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES}) set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node") -llvm_map_components_to_libnames(llvm_libs ${LLVM_TARGETS_TO_BUILD} bitwriter codegen core support tablegen target) +llvm_map_components_to_libnames(llvm_libs ${LLVM_TARGETS_TO_BUILD} bitwriter codegen core support tablegen target executionengine) # Link against LLVM libraries target_link_libraries(${PROJECT_NAME} ${llvm_libs} ${CMAKE_JS_LIB} ) \ No newline at end of file diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 8cca699..8e19afd 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -683,6 +683,14 @@ declare namespace llvm { getTypeByName(name: string): StructType | null; } + class ExecutionEngine { + /** + * Add a Module to the list of modules that we can JIT from. + * @param module + */ + addModule(module: Module): void; + } + // support class TargetRegistry { private constructor(); diff --git a/src/execution-engine/execution-engine-module.h b/src/execution-engine/execution-engine-module.h new file mode 100644 index 0000000..cd605c8 --- /dev/null +++ b/src/execution-engine/execution-engine-module.h @@ -0,0 +1,12 @@ + +#ifndef LLVM_NODE_EXECUTION_ENGINE_MODULE_H +#define LLVM_NODE_EXECUTION_ENGINE_MODULE_H + +#include +#include "execution-engine.h" + +NAN_MODULE_INIT(InitExecutionEngine) { + ExecutionEngineWrapper::Init(target); +} + +#endif //LLVM_NODE_EXECUTION_ENGINE_MODULE_H diff --git a/src/execution-engine/execution-engine.cc b/src/execution-engine/execution-engine.cc new file mode 100644 index 0000000..d4c3b40 --- /dev/null +++ b/src/execution-engine/execution-engine.cc @@ -0,0 +1,36 @@ + +#include "execution-engine.h" +#include "../ir/module.h" + +Nan::Persistent ExecutionEngineWrapper::executionEngineTemplate {}; + +NAN_MODULE_INIT(ExecutionEngineWrapper::Init) { + auto objectTemplate = Nan::New(); + objectTemplate->SetInternalFieldCount(1); + + Nan::SetMethod(objectTemplate, "addModule", ExecutionEngineWrapper::addModule); + + executionEngineTemplate.Reset(objectTemplate); +} + +NAN_METHOD(ExecutionEngineWrapper::addModule) { + if (info.Length() != 1 || !ModuleWrapper::isInstance(info[0])) { + return Nan::ThrowTypeError("addModule needs to be called with: mod: Module"); + } + + auto* module = ModuleWrapper::FromValue(info[0])->getModule(); + + auto* executionEngine = ExecutionEngineWrapper::FromValue(info.Holder())->executionEngine; + executionEngine->addModule(std::unique_ptr(module)); +} + +v8::Local ExecutionEngineWrapper::of(llvm::ExecutionEngine *executionEnginePtr) { + Nan::EscapableHandleScope escapeScope {}; + v8::Local tpl = Nan::New(executionEngineTemplate); + + auto object = Nan::NewInstance(tpl).ToLocalChecked(); + auto* wrapper = new ExecutionEngineWrapper { executionEnginePtr }; + wrapper->Wrap(object); + + return escapeScope.Escape(object); +} diff --git a/src/execution-engine/execution-engine.h b/src/execution-engine/execution-engine.h new file mode 100644 index 0000000..98187c1 --- /dev/null +++ b/src/execution-engine/execution-engine.h @@ -0,0 +1,25 @@ + +#ifndef LLVM_NODE_EXECUTION_ENGINE_H +#define LLVM_NODE_EXECUTION_ENGINE_H + +#include +#include +#include "../util/from-value-mixin.h" + +class ExecutionEngineWrapper: public Nan::ObjectWrap, public FromValueMixin { +public: + static NAN_MODULE_INIT(Init); + static v8::Local of(llvm::ExecutionEngine *ptr); + +private: + llvm::ExecutionEngine* executionEngine; + static Nan::Persistent executionEngineTemplate; + + explicit ExecutionEngineWrapper(llvm::ExecutionEngine* executionEngine): executionEngine { executionEngine } { + assert(executionEngine && "No execute engine passed"); + } + + static NAN_METHOD(addModule); +}; + +#endif //LLVM_NODE_EXECUTION_ENGINE_H diff --git a/src/llvm-node.cc b/src/llvm-node.cc index bc7c36c..1d97a7c 100644 --- a/src/llvm-node.cc +++ b/src/llvm-node.cc @@ -5,13 +5,14 @@ #include "config/config.h" #include "support/support.h" #include "target/target.h" +#include "execution-engine/execution-engine-module.h" NAN_MODULE_INIT(InitAll) { InitBitCode(target); InitConfig(target); InitIR(target); InitSupport(target); - InitTarget(target); + InitExecutionEngine(target); } NODE_MODULE(llvm, InitAll) \ No newline at end of file