?? vm.h
字號:
#ifndef __VM_H__
#define __VM_H__
#include <vector>
#include "Opcode.H"
// The VM class defines a stack-based implementation of an interpreter. The
// bytecode stream to execute is passed in to this class's constructor. Once
// the Exec() member function is called, the class will handle executing all
// the specified bytecode stream. Execution will continue until the entire
// bytecode stream has been process.
class VM {
public:
VM( const char *stream, size_t size );
~VM();
void Exec();
protected:
// Below are all of the various opcode handlers. They are responsible for
// actually evaluating the bytecode stream. They will modify the contents
// of the stack as needed.
bool HandleBinOp( Opcode op );
bool HandlePush( Opcode op );
bool HandlePop( Opcode op );
bool HandleDupe( Opcode op );
bool HandleLoad( Opcode op );
bool HandleStore( Opcode op );
bool HandleJump( Opcode op );
bool HandleIfZero( Opcode op );
protected:
// This function returns the new opcode in the bytecode stream. This
// implicitly increments the instruction pointer to point to next
// opcode.
Opcode GetNextOpcode();
// Some opcodes contain arguments in the bytecode stream. This function
// fetches the opcode's argument and increments the instruction pointer to
// skip the argument.
int GetOpcodeArg();
// The opcode handlers call this function to spew some text to stdout along
// with the current stack contents. By convention, the given string should
// not contain a newline, and this function should be called once the opcode
// handler is finished modifing the stack.
void Trace( char *fmt, ... );
protected:
// These two functions simply hide the stack pushing/poping. The main
// reason they exist is to make the std::vector interface a little easier to
// deal with. Mainly because it is convient for Pop() to actually the int
// that was popped off.
void Push( int arg );
int Pop();
private:
// Define the data member that contains all of the function pointers to the
// various opcode handlers. The index into this array is the actual opcode's
// value.
typedef bool ( VM::*OpcodeHandler )( Opcode );
OpcodeHandler m_opHandlers[ Num_Opcode ];
// Define a VM's actual execution stack. Note that the load and store
// instructions need to be able to modify arbitrary locations in the stack;
// therefore, it is more efficient to use a vector than a stack.
typedef std::vector<int> RuntimeStack;
RuntimeStack m_stack;
// The instruction pointer points to the next instruction to exectue.
const char *m_ip;
// These two data members keeps track of the bytecode stream that the VM
// should execute.
const char *m_stream;
size_t m_streamSize;
};
#endif // __VM_H__
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -