added code execution main loop

actorid
Marc Zinnschlag 15 years ago
parent 770eb14d95
commit d80cb3461c

@ -1,21 +1,186 @@
#include "interpreter.hpp" #include "interpreter.hpp"
#include <cassert>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include "opcodes.hpp"
namespace Interpreter namespace Interpreter
{ {
void Interpreter::execute (Type_Code code)
{
unsigned int segSpec = code>>30;
switch (segSpec)
{
case 0:
{
int opcode = code>>24;
unsigned int arg0 = code & 0xffffff;
std::map<int, Opcode1 *>::iterator iter = mSegment0.find (opcode);
if (iter==mSegment0.end())
abortUnknownCode (0, opcode);
iter->second->execute (mRuntime, arg0);
return;
}
case 1:
{
int opcode = (code>>24) & 0x3f;
unsigned int arg0 = (code>>16) & 0xfff;
unsigned int arg1 = code & 0xfff;
std::map<int, Opcode2 *>::iterator iter = mSegment1.find (opcode);
if (iter==mSegment1.end())
abortUnknownCode (1, opcode);
iter->second->execute (mRuntime, arg0, arg1);
return;
}
case 2:
{
int opcode = (code>>20) & 0x3ff;
unsigned int arg0 = code & 0xfffff;
std::map<int, Opcode1 *>::iterator iter = mSegment2.find (opcode);
if (iter==mSegment2.end())
abortUnknownCode (2, opcode);
iter->second->execute (mRuntime, arg0);
return;
}
}
segSpec = code>>26;
switch (segSpec)
{
case 0x30:
{
int opcode = (code>>16) & 0x3ff;
unsigned int arg0 = code & 0xffff;
std::map<int, Opcode1 *>::iterator iter = mSegment3.find (opcode);
if (iter==mSegment3.end())
abortUnknownCode (3, opcode);
iter->second->execute (mRuntime, arg0);
return;
}
case 0x31:
{
int opcode = (code>>16) & 0x3ff;
unsigned int arg0 = (code>>8) & 0xff;
unsigned int arg1 = code & 0xff;
std::map<int, Opcode2 *>::iterator iter = mSegment4.find (opcode);
if (iter==mSegment4.end())
abortUnknownCode (4, opcode);
iter->second->execute (mRuntime, arg0, arg1);
return;
}
case 0x32:
{
int opcode = code & 0x3ffffff;
std::map<int, Opcode0 *>::iterator iter = mSegment5.find (opcode);
if (iter==mSegment5.end())
abortUnknownCode (5, opcode);
iter->second->execute (mRuntime);
return;
}
}
abortUnknownSegment (code);
}
void Interpreter::abortUnknownCode (int segment, int opcode)
{
std::ostringstream error;
error << "unknown opcode " << opcode << " in segment " << segment;
throw std::runtime_error (error.str());
}
void Interpreter::abortUnknownSegment (Type_Code code)
{
std::ostringstream error;
error << "opcode outside of the allocated segment range: " << code;
throw std::runtime_error (error.str());
}
Interpreter::Interpreter (Context& context) Interpreter::Interpreter (Context& context)
: mRuntime (context) : mRuntime (context)
{} {}
Interpreter::~Interpreter() Interpreter::~Interpreter()
{ {
for (std::map<int, Opcode1 *>::iterator iter (mSegment0.begin());
iter!=mSegment0.end(); ++iter)
delete iter->second;
for (std::map<int, Opcode2 *>::iterator iter (mSegment1.begin());
iter!=mSegment1.end(); ++iter)
delete iter->second;
for (std::map<int, Opcode1 *>::iterator iter (mSegment2.begin());
iter!=mSegment2.end(); ++iter)
delete iter->second;
for (std::map<int, Opcode1 *>::iterator iter (mSegment3.begin());
iter!=mSegment3.end(); ++iter)
delete iter->second;
for (std::map<int, Opcode2 *>::iterator iter (mSegment4.begin());
iter!=mSegment4.end(); ++iter)
delete iter->second;
for (std::map<int, Opcode0 *>::iterator iter (mSegment5.begin());
iter!=mSegment5.end(); ++iter)
delete iter->second;
} }
void Interpreter::run (const Type_Code *code, int codeSize) void Interpreter::run (const Type_Code *code, int codeSize)
{ {
assert (codeSize>=4);
mRuntime.configure (code, codeSize); mRuntime.configure (code, codeSize);
int opcodes = static_cast<int> (code[0]);
const Type_Code *codeBlock = code + 4;
while (mRuntime.getPC()>=0 && mRuntime.getPC()<opcodes)
{
Type_Code code = codeBlock[mRuntime.getPC()];
mRuntime.setPC (mRuntime.getPC()+1);
execute (code);
}
mRuntime.clear(); mRuntime.clear();
} }

@ -1,19 +1,37 @@
#ifndef INTERPRETER_INTERPRETER_H_INCLUDED #ifndef INTERPRETER_INTERPRETER_H_INCLUDED
#define INTERPRETER_INTERPRETER_H_INCLUDED #define INTERPRETER_INTERPRETER_H_INCLUDED
#include <map>
#include "runtime.hpp" #include "runtime.hpp"
#include "types.hpp" #include "types.hpp"
namespace Interpreter namespace Interpreter
{ {
class Opcode0;
class Opcode1;
class Opcode2;
class Interpreter class Interpreter
{ {
Runtime mRuntime; Runtime mRuntime;
std::map<int, Opcode1 *> mSegment0;
std::map<int, Opcode2 *> mSegment1;
std::map<int, Opcode1 *> mSegment2;
std::map<int, Opcode1 *> mSegment3;
std::map<int, Opcode2 *> mSegment4;
std::map<int, Opcode0 *> mSegment5;
// not implemented // not implemented
Interpreter (const Interpreter&); Interpreter (const Interpreter&);
Interpreter& operator= (const Interpreter&); Interpreter& operator= (const Interpreter&);
void execute (Type_Code code);
void abortUnknownCode (int segment, int opcode);
void abortUnknownSegment (Type_Code code);
public: public:
Interpreter (Context& context); Interpreter (Context& context);

@ -22,7 +22,7 @@ namespace Interpreter
virtual void execute (Runtime& runtime, unsigned int arg0) = 0; virtual void execute (Runtime& runtime, unsigned int arg0) = 0;
virtual ~Opcode0() {} virtual ~Opcode1() {}
}; };
/// opcode for 2 arguments /// opcode for 2 arguments
@ -32,7 +32,7 @@ namespace Interpreter
virtual void execute (Runtime& runtime, unsigned int arg1, unsigned int arg2) = 0; virtual void execute (Runtime& runtime, unsigned int arg1, unsigned int arg2) = 0;
virtual ~Opcode0() {} virtual ~Opcode2() {}
}; };
} }

@ -3,7 +3,12 @@
namespace Interpreter namespace Interpreter
{ {
Runtime::Runtime (Context& context) : mContext (context), mCode (0) {} Runtime::Runtime (Context& context) : mContext (context), mCode (0), mPC (0) {}
int Runtime::getPC() const
{
return mPC;
}
void Runtime::configure (const Interpreter::Type_Code *code, int codeSize) void Runtime::configure (const Interpreter::Type_Code *code, int codeSize)
{ {
@ -11,6 +16,7 @@ namespace Interpreter
mCode = code; mCode = code;
mCodeSize = codeSize; mCodeSize = codeSize;
mPC = 0;
} }
void Runtime::clear() void Runtime::clear()
@ -18,5 +24,10 @@ namespace Interpreter
mCode = 0; mCode = 0;
mCodeSize = 0; mCodeSize = 0;
} }
void Runtime::setPC (int PC)
{
mPC = PC;
}
} }

@ -12,19 +12,26 @@ namespace Interpreter
class Runtime class Runtime
{ {
Context& mContext; Context& mContext;
const Interpreter::Type_Code *mCode; const Type_Code *mCode;
int mCodeSize; int mCodeSize;
int mPC;
public: public:
Runtime (Context& context); Runtime (Context& context);
int getPC() const;
///< return program counter.
void configure (const Interpreter::Type_Code *code, int codeSize); void configure (const Interpreter::Type_Code *code, int codeSize);
///< \a context and \a code must exist as least until either configure, clear or ///< \a context and \a code must exist as least until either configure, clear or
/// the destructor is called. \a codeSize is given in 32-bit words. /// the destructor is called. \a codeSize is given in 32-bit words.
void clear(); void clear();
void setPC (int PC);
///< set program counter.
}; };
} }

Loading…
Cancel
Save