mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Add support for atexit function, remove support for __main function
llvm-svn: 6194
This commit is contained in:
parent
e7f979708b
commit
cbf31910a5
@ -520,7 +520,9 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
|
||||
// Terminator Instruction Implementations
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void PerformExitStuff() {
|
||||
// PerformExitStuff - Print out counters and profiling information if
|
||||
// applicable...
|
||||
void Interpreter::PerformExitStuff() {
|
||||
#ifdef PROFILE_STRUCTURE_FIELDS
|
||||
// Print out structure field accounting information...
|
||||
if (!FieldAccessCounts.empty()) {
|
||||
@ -575,7 +577,6 @@ void Interpreter::exitCalled(GenericValue GV) {
|
||||
|
||||
ExitCode = GV.SByteVal;
|
||||
ECStack.clear();
|
||||
PerformExitStuff();
|
||||
}
|
||||
|
||||
void Interpreter::visitReturnInst(ReturnInst &I) {
|
||||
@ -609,8 +610,6 @@ void Interpreter::visitReturnInst(ReturnInst &I) {
|
||||
} else {
|
||||
ExitCode = 0;
|
||||
}
|
||||
|
||||
PerformExitStuff();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ static ExFunc lookupFunction(const Function *M) {
|
||||
}
|
||||
|
||||
GenericValue Interpreter::callExternalFunction(Function *M,
|
||||
const vector<GenericValue> &ArgVals) {
|
||||
const std::vector<GenericValue> &ArgVals) {
|
||||
TheInterpreter = this;
|
||||
|
||||
// Do a lookup to see if the function is in our cache... this should just be a
|
||||
@ -134,9 +134,13 @@ GenericValue lle_VB_putchar(FunctionType *M, const vector<GenericValue> &Args) {
|
||||
return Args[0];
|
||||
}
|
||||
|
||||
// void __main()
|
||||
GenericValue lle_V___main(FunctionType *M, const vector<GenericValue> &Args) {
|
||||
return GenericValue();
|
||||
// void atexit(Function*)
|
||||
GenericValue lle_X_atexit(FunctionType *M, const vector<GenericValue> &Args) {
|
||||
assert(Args.size() == 1);
|
||||
TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0]));
|
||||
GenericValue GV;
|
||||
GV.IntVal = 0;
|
||||
return GV;
|
||||
}
|
||||
|
||||
// void exit(int)
|
||||
@ -731,7 +735,6 @@ void Interpreter::initializeExternalFunctions() {
|
||||
FuncNames["lle_Vb_putchar"] = lle_Vb_putchar;
|
||||
FuncNames["lle_ii_putchar"] = lle_ii_putchar;
|
||||
FuncNames["lle_VB_putchar"] = lle_VB_putchar;
|
||||
FuncNames["lle_V___main"] = lle_V___main;
|
||||
FuncNames["lle_X_exit"] = lle_X_exit;
|
||||
FuncNames["lle_X_abort"] = lle_X_abort;
|
||||
FuncNames["lle_X_malloc"] = lle_X_malloc;
|
||||
|
@ -48,10 +48,21 @@ int Interpreter::run(const std::string &MainFunction,
|
||||
run();
|
||||
}
|
||||
|
||||
// If debug mode, allow the user to interact... also, if the user pressed
|
||||
// ctrl-c or execution hit an error, enter the event loop...
|
||||
if (Debug || isStopped())
|
||||
handleUserInput();
|
||||
do {
|
||||
// If debug mode, allow the user to interact... also, if the user pressed
|
||||
// ctrl-c or execution hit an error, enter the event loop...
|
||||
if (Debug || isStopped())
|
||||
handleUserInput();
|
||||
|
||||
// If the program has exited, run atexit handlers...
|
||||
if (ECStack.empty() && !AtExitHandlers.empty()) {
|
||||
callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
|
||||
AtExitHandlers.pop_back();
|
||||
run();
|
||||
}
|
||||
} while (!ECStack.empty());
|
||||
|
||||
PerformExitStuff();
|
||||
return ExitCode;
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,8 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
|
||||
// function record.
|
||||
std::vector<ExecutionContext> ECStack;
|
||||
|
||||
// AtExitHandlers - List of functions to call when the program exits.
|
||||
std::vector<Function*> AtExitHandlers;
|
||||
public:
|
||||
Interpreter(Module *M, unsigned Config, bool DebugMode, bool TraceMode);
|
||||
inline ~Interpreter() { CW.setModule(0); }
|
||||
@ -164,6 +166,10 @@ public:
|
||||
//
|
||||
inline bool isStopped() const { return !ECStack.empty(); }
|
||||
|
||||
void addAtExitHandler(Function *F) {
|
||||
AtExitHandlers.push_back(F);
|
||||
}
|
||||
|
||||
//FIXME: private:
|
||||
public:
|
||||
GenericValue executeGEPOperation(Value *Ptr, User::op_iterator I,
|
||||
@ -207,6 +213,9 @@ private: // Helper functions
|
||||
Value *ChooseOneOption(const std::string &Name,
|
||||
const std::vector<Value*> &Opts);
|
||||
|
||||
// PerformExitStuff - Print out counters and profiling information if
|
||||
// applicable...
|
||||
void PerformExitStuff();
|
||||
|
||||
void initializeExecutionEngine();
|
||||
void initializeExternalFunctions();
|
||||
|
@ -115,7 +115,7 @@ void Interpreter::handleUserInput() {
|
||||
case Call:
|
||||
std::cin >> Command;
|
||||
callFunction(Command); // Enter the specified function
|
||||
finish(); // Run until it's complete
|
||||
finish(); // Run until it's complete
|
||||
break;
|
||||
|
||||
case TraceOpt:
|
||||
@ -129,6 +129,7 @@ void Interpreter::handleUserInput() {
|
||||
}
|
||||
|
||||
} while (!UserQuit);
|
||||
AtExitHandlers.clear();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user