// Terminator Instruction Implementations
//===----------------------------------------------------------------------===//
+void Interpreter::exitCalled(GenericValue GV) {
+ cout << "Program returned ";
+ print(Type::IntTy, GV);
+ cout << " via 'void exit(int)'\n";
+
+ ExitCode = GV.SByteVal;
+ ECStack.clear();
+}
+
void Interpreter::executeRetInst(ReturnInst *I, ExecutionContext &SF) {
const Type *RetTy = 0;
GenericValue Result;
typedef GenericValue (*ExFunc)(MethodType *, const vector<GenericValue> &);
static map<const Method *, ExFunc> Functions;
+static Interpreter *TheInterpreter;
+
+// getCurrentExecutablePath() - Return the directory that the lli executable
+// lives in.
+//
+string Interpreter::getCurrentExecutablePath() const {
+ Dl_info Info;
+ if (dladdr(&TheInterpreter, &Info) == 0) return "";
+
+ string LinkAddr(Info.dli_fname);
+ unsigned SlashPos = LinkAddr.rfind('/');
+ if (SlashPos != string::npos)
+ LinkAddr.resize(SlashPos); // Trim the executable name off...
+
+ return LinkAddr;
+}
+
+
static char getTypeID(const Type *Ty) {
switch (Ty->getPrimitiveID()) {
case Type::VoidTyID: return 'V';
void Interpreter::callExternalMethod(Method *M,
const vector<GenericValue> &ArgVals) {
+ TheInterpreter = this;
+
// Do a lookup to see if the method is in our cache... this should just be a
// defered annotation!
map<const Method *, ExFunc>::iterator FI = Functions.find(M);
return GenericValue();
}
+// int "putchar"(int)
+GenericValue lle_ii_putchar(MethodType *M, const vector<GenericValue> &Args) {
+ cout << ((char)Args[0].IntVal) << flush;
+ return Args[0];
+}
+
// void "putchar"(ubyte)
GenericValue lle_VB_putchar(MethodType *M, const vector<GenericValue> &Args) {
- cout << Args[0].UByteVal;
- return GenericValue();
+ cout << Args[0].SByteVal << flush;
+ return Args[0];
}
// void "__main"()
return GenericValue();
}
+// void "exit"(int)
+GenericValue lle_Vi_exit(MethodType *M, const vector<GenericValue> &Args) {
+ TheInterpreter->exitCalled(Args[0]);
+ return GenericValue();
+}
+
} // End extern "C"
void executeRetInst(ReturnInst *I, ExecutionContext &SF);
void executeBrInst(BranchInst *I, ExecutionContext &SF);
void executeAllocInst(AllocationInst *I, ExecutionContext &SF);
+ void exitCalled(GenericValue GV);
// getCurrentMethod - Return the currently executing method
inline Method *getCurrentMethod() const {
inline bool isStopped() const { return !ECStack.empty(); }
private: // Helper functions
+ // getCurrentExecutablePath() - Return the directory that the lli executable
+ // lives in.
+ //
+ string getCurrentExecutablePath() const;
+
// printCurrentInstruction - Print out the instruction that the virtual PC is
// at, or fail silently if no program is running.
//
#include "llvm/Bytecode/Reader.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/Transforms/Linker.h"
#include <algorithm>
enum CommandID {
// loadModule - Load a new module to execute...
//
void Interpreter::loadModule(const string &Filename) {
+ string ErrorMsg;
if (CurMod && !flushModule()) return; // Kill current execution
- CurMod = ParseBytecodeFile(Filename);
+ CurMod = ParseBytecodeFile(Filename, &ErrorMsg);
if (CurMod == 0) {
- cout << "Error parsing '" << Filename << "': No module loaded.\n";
+ cout << "Error parsing '" << Filename << "': No module loaded: "
+ << ErrorMsg << "\n";
return;
}
- // TODO: link in support library...
+ string RuntimeLib = getCurrentExecutablePath() + "/RuntimeLib.bc";
+ if (Module *SupportLib = ParseBytecodeFile(RuntimeLib, &ErrorMsg)) {
+ if (LinkModules(CurMod, SupportLib, &ErrorMsg))
+ cerr << "Error Linking runtime library into current module: "
+ << ErrorMsg << endl;
+ } else {
+ cerr << "Error loading runtime library '"+RuntimeLib+"': "
+ << ErrorMsg << "\n";
+ }
}
LEVEL = ../..
TOOLNAME = lli
-USEDLIBS = opt bcreader bcwriter vmcore asmwriter analysis support target
+USEDLIBS = opt bcreader bcwriter vmcore asmwriter analysis support \
+ target transforms
TOOLLINKOPTS = -ldl
include $(LEVEL)/Makefile.common
/home/vadve/lattner/cvs/gcc_install/bin/gcc $< -c -o $@
$(LEVEL)/tools/Debug/RuntimeLib.bc: Debug/RuntimeLib.o
- opt -dce $< -o $@ -f -q
+ ../Debug/opt -dce $< -o $@ -f -q
LEVEL = ../..
TOOLNAME = lli
-USEDLIBS = opt bcreader bcwriter vmcore asmwriter analysis support target
+USEDLIBS = opt bcreader bcwriter vmcore asmwriter analysis support \
+ target transforms
TOOLLINKOPTS = -ldl
include $(LEVEL)/Makefile.common
/home/vadve/lattner/cvs/gcc_install/bin/gcc $< -c -o $@
$(LEVEL)/tools/Debug/RuntimeLib.bc: Debug/RuntimeLib.o
- opt -dce $< -o $@ -f -q
+ ../Debug/opt -dce $< -o $@ -f -q