auto merge of #19750 : murarth/rust/rusti-support, r=brson
Makes a couple changes that support the implementation of a REPL: * Implementation of wrapper code for LLVM ExecutionEngine API * Fixing a change I made earlier to reset compiler state in `phase_1_[...]` instead of `compile_input` as the latter is not used in a REPL
This commit is contained in:
commit
b677746b1e
@ -22,7 +22,8 @@ LLVM_EXTRA_INCDIRS_$(1)= -iquote $(S)src/llvm/include \
|
||||
-iquote $$(CFG_LLVM_BUILD_DIR_$(1))/include
|
||||
endif
|
||||
|
||||
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, RustWrapper.cpp PassWrapper.cpp)
|
||||
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
|
||||
ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp)
|
||||
|
||||
RUSTLLVM_DEF_$(1) := $(1)/rustllvm/rustllvm$(CFG_DEF_SUFFIX_$(1))
|
||||
|
||||
|
@ -47,12 +47,6 @@ pub fn compile_input(sess: Session,
|
||||
outdir: &Option<Path>,
|
||||
output: &Option<Path>,
|
||||
addl_plugins: Option<Plugins>) {
|
||||
// These may be left in an incoherent state after a previous compile.
|
||||
// `clear_tables` and `get_ident_interner().clear()` can be used to free
|
||||
// memory, but they do not restore the initial state.
|
||||
syntax::ext::mtwt::reset_tables();
|
||||
token::reset_ident_interner();
|
||||
|
||||
// We need nested scopes here, because the intermediate results can keep
|
||||
// large chunks of memory alive and we want to free them as soon as
|
||||
// possible to keep the peak memory usage low
|
||||
@ -116,6 +110,12 @@ pub fn source_name(input: &Input) -> String {
|
||||
|
||||
pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
|
||||
-> ast::Crate {
|
||||
// These may be left in an incoherent state after a previous compile.
|
||||
// `clear_tables` and `get_ident_interner().clear()` can be used to free
|
||||
// memory, but they do not restore the initial state.
|
||||
syntax::ext::mtwt::reset_tables();
|
||||
token::reset_ident_interner();
|
||||
|
||||
let krate = time(sess.time_passes(), "parsing", (), |_| {
|
||||
match *input {
|
||||
Input::File(ref file) => {
|
||||
|
@ -466,6 +466,9 @@ pub type BuilderRef = *mut Builder_opaque;
|
||||
pub enum ExecutionEngine_opaque {}
|
||||
pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum RustJITMemoryManager_opaque {}
|
||||
pub type RustJITMemoryManagerRef = *mut RustJITMemoryManager_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum MemoryBuffer_opaque {}
|
||||
pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
@ -1064,7 +1067,18 @@ extern {
|
||||
Instr: ValueRef,
|
||||
Name: *const c_char);
|
||||
pub fn LLVMDisposeBuilder(Builder: BuilderRef);
|
||||
|
||||
/* Execution engine */
|
||||
pub fn LLVMRustCreateJITMemoryManager(morestack: *const ())
|
||||
-> RustJITMemoryManagerRef;
|
||||
pub fn LLVMBuildExecutionEngine(Mod: ModuleRef,
|
||||
MM: RustJITMemoryManagerRef) -> ExecutionEngineRef;
|
||||
pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
|
||||
pub fn LLVMExecutionEngineFinalizeObject(EE: ExecutionEngineRef);
|
||||
pub fn LLVMRustLoadDynamicLibrary(path: *const c_char) -> Bool;
|
||||
pub fn LLVMExecutionEngineAddModule(EE: ExecutionEngineRef, M: ModuleRef);
|
||||
pub fn LLVMExecutionEngineRemoveModule(EE: ExecutionEngineRef, M: ModuleRef)
|
||||
-> Bool;
|
||||
|
||||
/* Metadata */
|
||||
pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
|
||||
|
112
src/rustllvm/ExecutionEngineWrapper.cpp
Normal file
112
src/rustllvm/ExecutionEngineWrapper.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#include "rustllvm.h"
|
||||
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::sys;
|
||||
using namespace llvm::object;
|
||||
|
||||
class RustJITMemoryManager : public SectionMemoryManager
|
||||
{
|
||||
typedef SectionMemoryManager Base;
|
||||
|
||||
const void *morestack;
|
||||
|
||||
public:
|
||||
|
||||
RustJITMemoryManager(const void *morestack_ptr)
|
||||
: morestack(morestack_ptr)
|
||||
{}
|
||||
|
||||
uint64_t getSymbolAddress(const std::string &Name) override
|
||||
{
|
||||
if (Name == "__morestack" || Name == "___morestack")
|
||||
return reinterpret_cast<uint64_t>(morestack);
|
||||
|
||||
return Base::getSymbolAddress(Name);
|
||||
}
|
||||
};
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef)
|
||||
|
||||
extern "C" LLVMRustJITMemoryManagerRef LLVMRustCreateJITMemoryManager(void *morestack)
|
||||
{
|
||||
return wrap(new RustJITMemoryManager(morestack));
|
||||
}
|
||||
|
||||
extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
|
||||
{
|
||||
std::string err;
|
||||
DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(path, &err);
|
||||
|
||||
if (!lib.isValid())
|
||||
LLVMRustSetLastError(err.c_str());
|
||||
|
||||
return lib.isValid();
|
||||
}
|
||||
|
||||
// Calls LLVMAddModule;
|
||||
// exists for consistency with LLVMExecutionEngineRemoveModule
|
||||
extern "C" void LLVMExecutionEngineAddModule(
|
||||
LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
|
||||
{
|
||||
LLVMAddModule(eeref, mref);
|
||||
}
|
||||
|
||||
// LLVMRemoveModule exists in LLVM's C bindings,
|
||||
// but it requires pointless parameters
|
||||
extern "C" LLVMBool LLVMExecutionEngineRemoveModule(
|
||||
LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
|
||||
{
|
||||
ExecutionEngine *ee = unwrap(eeref);
|
||||
Module *m = unwrap(mref);
|
||||
|
||||
return ee->removeModule(m);
|
||||
}
|
||||
|
||||
extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(
|
||||
LLVMModuleRef mod, LLVMRustJITMemoryManagerRef mref)
|
||||
{
|
||||
// These are necessary for code generation to work properly.
|
||||
InitializeNativeTarget();
|
||||
InitializeNativeTargetAsmPrinter();
|
||||
InitializeNativeTargetAsmParser();
|
||||
|
||||
std::unique_ptr<Module> m(unwrap(mod));
|
||||
RustJITMemoryManager *mm = unwrap(mref);
|
||||
|
||||
std::string error_str;
|
||||
TargetOptions options;
|
||||
|
||||
options.JITEmitDebugInfo = true;
|
||||
options.NoFramePointerElim = true;
|
||||
|
||||
ExecutionEngine *ee = EngineBuilder(std::move(m))
|
||||
.setEngineKind(EngineKind::JIT)
|
||||
.setErrorStr(&error_str)
|
||||
.setMCJITMemoryManager(mm)
|
||||
.setTargetOptions(options)
|
||||
.create();
|
||||
|
||||
if (!ee)
|
||||
LLVMRustSetLastError(error_str.c_str());
|
||||
|
||||
return wrap(ee);
|
||||
}
|
||||
|
||||
extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref)
|
||||
{
|
||||
ExecutionEngine *ee = unwrap(eeref);
|
||||
|
||||
ee->finalizeObject();
|
||||
}
|
@ -72,6 +72,7 @@ typedef struct OpaqueRustString *RustStringRef;
|
||||
typedef struct LLVMOpaqueTwine *LLVMTwineRef;
|
||||
typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;
|
||||
typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef;
|
||||
typedef struct LLVMOpaqueRustJITMemoryManager *LLVMRustJITMemoryManagerRef;
|
||||
|
||||
extern "C" void
|
||||
rust_llvm_string_write_impl(RustStringRef str, const char *ptr, size_t size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user