aboutsummaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/Interpreter/Interpreter.h
blob: 9ff83365dbee7bab7eacb17a78c353e5ddba9bd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//===-- Interpreter.h ------------------------------------------*- C++ -*--===//
//
// This header file defines the interpreter structure
//
//===----------------------------------------------------------------------===//

#ifndef LLI_INTERPRETER_H
#define LLI_INTERPRETER_H

#include "llvm/Module.h"
#include "llvm/Method.h"

struct MethodInfo;          // Defined in ExecutionAnnotations.h
class CallInst;
class ReturnInst;
class BranchInst;

union GenericValue {
  bool            BoolVal;
  unsigned char   UByteVal;
  signed   char   SByteVal;
  unsigned short  UShortVal;
  signed   short  ShortVal;
  unsigned int    UIntVal;
  signed   int    IntVal;
  double          DoubleVal;
  float           FloatVal;
  GenericValue *PointerVal;
};

typedef vector<GenericValue> ValuePlaneTy;

// ExecutionContext struct - This struct represents one stack frame currently
// executing.
//
struct ExecutionContext {
  Method               *CurMethod;  // The currently executing method
  BasicBlock           *CurBB;      // The currently executing BB
  BasicBlock::iterator  CurInst;    // The next instruction to execute
  MethodInfo           *MethInfo;   // The MethInfo annotation for the method
  vector<ValuePlaneTy>  Values;     // ValuePlanes for each type

  BasicBlock           *PrevBB;     // The previous BB or null if in first BB
  CallInst             *Caller;     // Holds the call that called subframes.
                                    // NULL if main func or debugger invoked fn
};


// Interpreter - This class represents the entirety of the interpreter.
//
class Interpreter {
  Module *CurMod;              // The current Module being executed (0 if none)
  int ExitCode;                // The exit code to be returned by the lli util
  bool Profile;                // Profiling enabled?
  int CurFrame;                // The current stack frame being inspected

  // The runtime stack of executing code.  The top of the stack is the current
  // method record.
  vector<ExecutionContext> ECStack;

public:
  Interpreter();
  inline ~Interpreter() { delete CurMod; }

  // getExitCode - return the code that should be the exit code for the lli
  // utility.
  inline int getExitCode() const { return ExitCode; }

  // enableProfiling() - Turn profiling on, clear stats?
  void enableProfiling() { Profile = true; }

  void initializeExecutionEngine();
  void handleUserInput();

  // User Interation Methods...
  bool callMethod(const string &Name);      // return true on failure
  void setBreakpoint(const string &Name);
  void printValue(const string &Name);
  void printValue(const Type *Ty, GenericValue V);


  void list();             // Do the 'list' command
  void printStackTrace();  // Do the 'backtrace' command

  // Code execution methods...
  void callMethod(Method *Meth, ExecutionContext *SF = 0);
  bool executeInstruction(); // Execute one instruction...

  void stepInstruction();  // Do the 'step' command
  void nextInstruction();  // Do the 'next' command
  void run();              // Do the 'run' command
  void finish();           // Do the 'finish' command

  // Opcode Implementations
  void executeCallInst(CallInst *I, ExecutionContext &SF);
  void executeRetInst(ReturnInst *I, ExecutionContext &SF);
  void executeBrInst(BranchInst *I, ExecutionContext &SF);

  // getCurrentMethod - Return the currently executing method
  inline Method *getCurrentMethod() const {
    return CurFrame < 0 ? 0 : ECStack[CurFrame].CurMethod;
  }

  // isStopped - Return true if a program is stopped.  Return false if no
  // program is running.
  //
  inline bool isStopped() const { return !ECStack.empty(); }

private:  // Helper functions
  // printCurrentInstruction - Print out the instruction that the virtual PC is
  // at, or fail silently if no program is running.
  //
  void printCurrentInstruction();

  // LookupMatchingNames - Search the current method namespace, then the global
  // namespace looking for values that match the specified name.  Return ALL
  // matches to that name.  This is obviously slow, and should only be used for
  // user interaction.
  //
  vector<Value*> LookupMatchingNames(const string &Name);

  // ChooseOneOption - Prompt the user to choose among the specified options to
  // pick one value.  If no options are provided, emit an error.  If a single 
  // option is provided, just return that option.
  //
  Value *ChooseOneOption(const string &Name, const vector<Value*> &Opts);
};

#endif