aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
authorBrian Gaeke <gaeke@uiuc.edu>2003-11-07 20:44:58 +0000
committerBrian Gaeke <gaeke@uiuc.edu>2003-11-07 20:44:58 +0000
commitdbde1ae7a03cfed13b7abd3a37fa74fbdc2c9551 (patch)
tree0c07666608aaf508199842a2d1dcae91d93179b0 /lib/ExecutionEngine
parent351881793a0917de50445a2c2ce87c9fb771ac5c (diff)
downloadexternal_llvm-dbde1ae7a03cfed13b7abd3a37fa74fbdc2c9551.zip
external_llvm-dbde1ae7a03cfed13b7abd3a37fa74fbdc2c9551.tar.gz
external_llvm-dbde1ae7a03cfed13b7abd3a37fa74fbdc2c9551.tar.bz2
popStackAndReturnValueToCaller() must advance instruction pointer to normal
destination, if returning from an invoke. Implement 'unwind' instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9792 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp29
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index c5facde..6a224b9 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -435,8 +435,10 @@ void Interpreter::exitCalled(GenericValue GV) {
/// Pop the last stack frame off of ECStack and then copy the result
/// back into the result variable if we are not returning void. The
/// result variable may be the ExitCode, or the Value of the calling
-/// CallInst if there was a previous stack frame. This procedure may
-/// invalidate any ECStack iterators you have.
+/// CallInst if there was a previous stack frame. This method may
+/// invalidate any ECStack iterators you have. This method also takes
+/// care of switching to the normal destination BB, if we are returning
+/// from an invoke.
///
void Interpreter::popStackAndReturnValueToCaller (const Type *RetTy,
GenericValue Result) {
@@ -453,9 +455,11 @@ void Interpreter::popStackAndReturnValueToCaller (const Type *RetTy,
// If we have a previous stack frame, and we have a previous call,
// fill in the return value...
ExecutionContext &CallingSF = ECStack.back();
- if (CallingSF.Caller.getInstruction()) {
+ if (Instruction *I = CallingSF.Caller.getInstruction()) {
if (CallingSF.Caller.getType() != Type::VoidTy) // Save result...
- SetValue(CallingSF.Caller.getInstruction(), Result, CallingSF);
+ SetValue(I, Result, CallingSF);
+ if (InvokeInst *II = dyn_cast<InvokeInst> (I))
+ SwitchToNewBasicBlock (II->getNormalDest (), CallingSF);
CallingSF.Caller = CallSite(); // We returned from the call...
}
}
@@ -476,7 +480,22 @@ void Interpreter::visitReturnInst(ReturnInst &I) {
}
void Interpreter::visitUnwindInst(UnwindInst &I) {
- abort ();
+ // Unwind stack
+ Instruction *Inst;
+ do {
+ ECStack.pop_back ();
+ if (ECStack.empty ())
+ abort ();
+ Inst = ECStack.back ().Caller.getInstruction ();
+ } while (!(Inst && isa<InvokeInst> (Inst)));
+
+ // Return from invoke
+ ExecutionContext &InvokingSF = ECStack.back ();
+ InvokingSF.Caller = CallSite ();
+
+ // Go to exceptional destination BB of invoke instruction
+ SwitchToNewBasicBlock (cast<InvokeInst> (Inst)->getExceptionalDest (),
+ InvokingSF);
}
void Interpreter::visitBranchInst(BranchInst &I) {