From d80cb3461c431f48d37a21cfe9aea1ddb3ec81de Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 28 Jun 2010 20:46:15 +0200 Subject: [PATCH] added code execution main loop --- components/interpreter/interpreter.cpp | 167 ++++++++++++++++++++++++- components/interpreter/interpreter.hpp | 18 +++ components/interpreter/opcodes.hpp | 4 +- components/interpreter/runtime.cpp | 15 ++- components/interpreter/runtime.hpp | 9 +- 5 files changed, 207 insertions(+), 6 deletions(-) diff --git a/components/interpreter/interpreter.cpp b/components/interpreter/interpreter.cpp index 1db683e3c..8b3159846 100644 --- a/components/interpreter/interpreter.cpp +++ b/components/interpreter/interpreter.cpp @@ -1,21 +1,186 @@ #include "interpreter.hpp" +#include +#include +#include +#include + +#include "opcodes.hpp" + 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::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::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::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::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::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::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) : mRuntime (context) {} Interpreter::~Interpreter() { - + for (std::map::iterator iter (mSegment0.begin()); + iter!=mSegment0.end(); ++iter) + delete iter->second; + + for (std::map::iterator iter (mSegment1.begin()); + iter!=mSegment1.end(); ++iter) + delete iter->second; + + for (std::map::iterator iter (mSegment2.begin()); + iter!=mSegment2.end(); ++iter) + delete iter->second; + + for (std::map::iterator iter (mSegment3.begin()); + iter!=mSegment3.end(); ++iter) + delete iter->second; + + for (std::map::iterator iter (mSegment4.begin()); + iter!=mSegment4.end(); ++iter) + delete iter->second; + + for (std::map::iterator iter (mSegment5.begin()); + iter!=mSegment5.end(); ++iter) + delete iter->second; } void Interpreter::run (const Type_Code *code, int codeSize) { + assert (codeSize>=4); + mRuntime.configure (code, codeSize); + int opcodes = static_cast (code[0]); + + const Type_Code *codeBlock = code + 4; + + while (mRuntime.getPC()>=0 && mRuntime.getPC() + #include "runtime.hpp" #include "types.hpp" namespace Interpreter { + class Opcode0; + class Opcode1; + class Opcode2; + class Interpreter { Runtime mRuntime; + std::map mSegment0; + std::map mSegment1; + std::map mSegment2; + std::map mSegment3; + std::map mSegment4; + std::map mSegment5; // not implemented Interpreter (const Interpreter&); Interpreter& operator= (const Interpreter&); + void execute (Type_Code code); + + void abortUnknownCode (int segment, int opcode); + + void abortUnknownSegment (Type_Code code); + public: Interpreter (Context& context); diff --git a/components/interpreter/opcodes.hpp b/components/interpreter/opcodes.hpp index d24e8c62c..c447e1f10 100644 --- a/components/interpreter/opcodes.hpp +++ b/components/interpreter/opcodes.hpp @@ -22,7 +22,7 @@ namespace Interpreter virtual void execute (Runtime& runtime, unsigned int arg0) = 0; - virtual ~Opcode0() {} + virtual ~Opcode1() {} }; /// opcode for 2 arguments @@ -32,7 +32,7 @@ namespace Interpreter virtual void execute (Runtime& runtime, unsigned int arg1, unsigned int arg2) = 0; - virtual ~Opcode0() {} + virtual ~Opcode2() {} }; } diff --git a/components/interpreter/runtime.cpp b/components/interpreter/runtime.cpp index 33f1e3780..24048eb5a 100644 --- a/components/interpreter/runtime.cpp +++ b/components/interpreter/runtime.cpp @@ -3,14 +3,20 @@ 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) { clear(); mCode = code; mCodeSize = codeSize; + mPC = 0; } void Runtime::clear() @@ -18,5 +24,10 @@ namespace Interpreter mCode = 0; mCodeSize = 0; } + + void Runtime::setPC (int PC) + { + mPC = PC; + } } diff --git a/components/interpreter/runtime.hpp b/components/interpreter/runtime.hpp index 2166e3cc7..e45789f16 100644 --- a/components/interpreter/runtime.hpp +++ b/components/interpreter/runtime.hpp @@ -12,18 +12,25 @@ namespace Interpreter class Runtime { Context& mContext; - const Interpreter::Type_Code *mCode; + const Type_Code *mCode; int mCodeSize; + int mPC; public: Runtime (Context& context); + int getPC() const; + ///< return program counter. + void configure (const Interpreter::Type_Code *code, int codeSize); ///< \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. void clear(); + + void setPC (int PC); + ///< set program counter. }; }