Files
swift-mirror/tools/swift/Immediate.cpp
2012-04-16 23:52:01 +00:00

136 lines
4.1 KiB
C++

//===-- Immediate.cpp - the swift immediate mode --------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This is the implementation of the swift interpreter, which takes a
// TranslationUnit and JITs it.
//
//===----------------------------------------------------------------------===//
#include "Immediate.h"
#include "swift/Subsystems.h"
#include "swift/IRGen/Options.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Component.h"
#include "swift/AST/Diagnostics.h"
#include "swift/AST/Module.h"
#include "swift/Basic/DiagnosticConsumer.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include <dlfcn.h>
void swift::RunImmediately(TranslationUnit *TU) {
ASTContext &Context = TU->Ctx;
irgen::Options Options;
Options.OutputFilename = TU->Name.str();
Options.Triple = llvm::sys::getDefaultTargetTriple();
Options.OptLevel = 0;
Options.OutputKind = irgen::OutputKind::Module;
// IRGen the main module.
llvm::LLVMContext LLVMContext;
llvm::Module Module(Options.OutputFilename, LLVMContext);
performCaptureAnalysis(TU);
performIRGeneration(Options, &Module, TU);
if (Context.hadError())
return;
llvm::SmallPtrSet<TranslationUnit*, 8> ImportedModules;
// IRGen the modules this module depends on.
for (auto ModPair : TU->getImportedModules()) {
if (isa<BuiltinModule>(ModPair.second))
continue;
TranslationUnit *SubTU = cast<TranslationUnit>(ModPair.second);
if (!ImportedModules.insert(SubTU))
continue;
// FIXME: Need to check whether this is actually safe in general.
llvm::Module SubModule(SubTU->Name.str(), LLVMContext);
performCaptureAnalysis(SubTU);
performIRGeneration(Options, &SubModule, SubTU);
if (Context.hadError())
return;
std::string ErrorMessage;
if (llvm::Linker::LinkModules(&Module, &SubModule,
llvm::Linker::DestroySource,
&ErrorMessage)) {
llvm::errs() << "Error linking swift modules\n";
llvm::errs() << ErrorMessage << "\n";
return;
}
}
// Load the swift runtime.
// FIXME: Need error-checking.
llvm::sys::Path LibPath =
llvm::sys::Path::GetMainExecutable(0, (void*)&RunImmediately);
LibPath.eraseComponent();
LibPath.eraseComponent();
LibPath.appendComponent("lib");
LibPath.appendComponent("libswift_abi.dylib");
dlopen(LibPath.c_str(), 0);
// Run the generated program.
// FIXME: This isn't the right entry point! (But what is?)
llvm::Function *EntryFn = Module.getFunction("main");
llvm::EngineBuilder builder(&Module);
std::string ErrorMsg;
builder.setErrorStr(&ErrorMsg);
builder.setEngineKind(llvm::EngineKind::JIT);
builder.setUseMCJIT(true);
llvm::ExecutionEngine *EE = builder.create();
EE->runFunctionAsMain(EntryFn, std::vector<std::string>(), 0);
}
// FIXME: We shouldn't be writing implemenetations for functions in the swift
// module in C, and this isn't really an ideal place to put those
// implementations.
extern "C" void _TSs5printFT3valNSs5int64_T_(int64_t l) {
printf("%lld", l);
}
extern "C" void _TSs5printFT3valNSs6double_T_(double l) {
printf("%f", l);
}
extern "C" void __TSs9printCharFT9characterNSs5int64_T_(int64_t l) {
printf("%c", (char)l);
}
extern "C" void _TSs5printFT3valNSs6String_T_(char* l) {
printf("%s", l);
}
extern "C" bool _TNSs4bool13getLogicValuefRS_FT_i1(bool* b) {
return *b;
}
extern "C" void _TSs4exitFT8exitCodeNSs5int64_T_(int64_t l) {
exit(l);
}