From c6a37b2e18b2ce478c231665f96dd031282be7e2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 28 Jun 2010 21:49:48 +0200 Subject: [PATCH] added first batch of opcodes --- CMakeLists.txt | 3 +- apps/mwinterpreter/main.cpp | 2 + components/interpreter/genericopcodes.hpp | 33 +++++++++ components/interpreter/installopcodes.cpp | 24 +++++++ components/interpreter/installopcodes.hpp | 11 +++ components/interpreter/interpreter.cpp | 32 ++++++++- components/interpreter/interpreter.hpp | 18 +++++ components/interpreter/localopcodes.hpp | 82 +++++++++++++++++++++++ components/interpreter/runtime.cpp | 48 +++++++++++++ components/interpreter/runtime.hpp | 21 +++++- 10 files changed, 270 insertions(+), 4 deletions(-) create mode 100644 components/interpreter/genericopcodes.hpp create mode 100644 components/interpreter/installopcodes.cpp create mode 100644 components/interpreter/installopcodes.hpp create mode 100644 components/interpreter/localopcodes.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ff8340fd6..b9815041f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,8 @@ set(COMPILER components/compiler/errorhandler.cpp file(GLOB COMPILER_HEADER components/compiler/*.hpp) source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER}) -set(INTERPRETER components/interpreter/runtime.cpp components/interpreter/interpreter.cpp) +set(INTERPRETER components/interpreter/runtime.cpp components/interpreter/interpreter.cpp + components/interpreter/installopcodes.cpp) file(GLOB INTERPRETER_HEADER components/interpreter/*.hpp) source_group(interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER}) diff --git a/apps/mwinterpreter/main.cpp b/apps/mwinterpreter/main.cpp index df1cbc1c5..e8f0c8783 100644 --- a/apps/mwinterpreter/main.cpp +++ b/apps/mwinterpreter/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "context.hpp" @@ -21,6 +22,7 @@ int main (int argc, char **argv) SAInterpreter::Context context (localfilename); Interpreter::Interpreter interpreter (context); + Interpreter::installOpcodes (interpreter); std::string codefilename = filename + ".code"; diff --git a/components/interpreter/genericopcodes.hpp b/components/interpreter/genericopcodes.hpp new file mode 100644 index 000000000..f5849676c --- /dev/null +++ b/components/interpreter/genericopcodes.hpp @@ -0,0 +1,33 @@ +#ifndef INTERPRETER_GENERICOPCODES_H_INCLUDED +#define INTERPRETER_GENERICOPCODES_H_INCLUDED + +#include "opcodes.hpp" +#include "runtime.hpp" + +namespace Interpreter +{ + class OpPushInt : public Opcode1 + { + public: + + virtual void execute (Runtime& runtime, unsigned int arg0) + { + runtime.push (arg0); + } + }; + + class OpIntToFloat : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + Type_Data data = runtime[0]; + Type_Float floatValue = static_cast (data); + runtime[0] = *reinterpret_cast (&floatValue); + } + }; +} + +#endif + diff --git a/components/interpreter/installopcodes.cpp b/components/interpreter/installopcodes.cpp new file mode 100644 index 000000000..44206696f --- /dev/null +++ b/components/interpreter/installopcodes.cpp @@ -0,0 +1,24 @@ + +#include "installopcodes.hpp" + +#include "interpreter.hpp" +#include "genericopcodes.hpp" +#include "localopcodes.hpp" + +namespace Interpreter +{ + void installOpcodes (Interpreter& interpreter) + { + // generic + interpreter.installSegment0 (0, new OpPushInt); + interpreter.installSegment5 (3, new OpIntToFloat); + + // local variables + interpreter.installSegment5 (0, new OpStoreLocalShort); + interpreter.installSegment5 (1, new OpStoreLocalLong); + interpreter.installSegment5 (2, new OpStoreLocalFloat); + interpreter.installSegment5 (4, new OpFetchIntLiteral); + interpreter.installSegment5 (5, new OpFetchFloatLiteral); + } +} + diff --git a/components/interpreter/installopcodes.hpp b/components/interpreter/installopcodes.hpp new file mode 100644 index 000000000..8020490dd --- /dev/null +++ b/components/interpreter/installopcodes.hpp @@ -0,0 +1,11 @@ +#ifndef INTERPRETER_INSTALLOPCODES_H_INCLUDED +#define INTERPRETER_INSTALLOPCODES_H_INCLUDED + +namespace Interpreter +{ + class Interpreter; + + void installOpcodes (Interpreter& interpreter); +} + +#endif diff --git a/components/interpreter/interpreter.cpp b/components/interpreter/interpreter.cpp index 8b3159846..3654d209b 100644 --- a/components/interpreter/interpreter.cpp +++ b/components/interpreter/interpreter.cpp @@ -165,7 +165,37 @@ namespace Interpreter delete iter->second; } - void Interpreter::run (const Type_Code *code, int codeSize) + void Interpreter::installSegment0 (int code, Opcode1 *opcode) + { + mSegment0.insert (std::make_pair (code, opcode)); + } + + void Interpreter::installSegment1 (int code, Opcode2 *opcode) + { + mSegment1.insert (std::make_pair (code, opcode)); + } + + void Interpreter::installSegment2 (int code, Opcode1 *opcode) + { + mSegment2.insert (std::make_pair (code, opcode)); + } + + void Interpreter::installSegment3 (int code, Opcode1 *opcode) + { + mSegment3.insert (std::make_pair (code, opcode)); + } + + void Interpreter::installSegment4 (int code, Opcode2 *opcode) + { + mSegment4.insert (std::make_pair (code, opcode)); + } + + void Interpreter::installSegment5 (int code, Opcode0 *opcode) + { + mSegment5.insert (std::make_pair (code, opcode)); + } + + void Interpreter::Interpreter::run (const Type_Code *code, int codeSize) { assert (codeSize>=4); diff --git a/components/interpreter/interpreter.hpp b/components/interpreter/interpreter.hpp index 51a7ac90e..c67273707 100644 --- a/components/interpreter/interpreter.hpp +++ b/components/interpreter/interpreter.hpp @@ -38,6 +38,24 @@ namespace Interpreter ~Interpreter(); + void installSegment0 (int code, Opcode1 *opcode); + ///< ownership of \a opcode is transferred to *this. + + void installSegment1 (int code, Opcode2 *opcode); + ///< ownership of \a opcode is transferred to *this. + + void installSegment2 (int code, Opcode1 *opcode); + ///< ownership of \a opcode is transferred to *this. + + void installSegment3 (int code, Opcode1 *opcode); + ///< ownership of \a opcode is transferred to *this. + + void installSegment4 (int code, Opcode2 *opcode); + ///< ownership of \a opcode is transferred to *this. + + void installSegment5 (int code, Opcode0 *opcode); + ///< ownership of \a opcode is transferred to *this. + void run (const Type_Code *code, int codeSize); }; } diff --git a/components/interpreter/localopcodes.hpp b/components/interpreter/localopcodes.hpp new file mode 100644 index 000000000..d15635967 --- /dev/null +++ b/components/interpreter/localopcodes.hpp @@ -0,0 +1,82 @@ +#ifndef INTERPRETER_LOCALOPCODES_H_INCLUDED +#define INTERPRETER_LOCALOPCODES_H_INCLUDED + +#include "opcodes.hpp" +#include "runtime.hpp" +#include "context.hpp" + +namespace Interpreter +{ + class OpStoreLocalShort : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + Type_Data data = runtime[0]; + int index = runtime[1]; + + runtime.getContext().setLocalShort (index, *reinterpret_cast (&data)); + + runtime.pop(); + runtime.pop(); + } + }; + + class OpStoreLocalLong : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + Type_Data data = runtime[0]; + int index = runtime[1]; + + runtime.getContext().setLocalLong (index, *reinterpret_cast (&data)); + + runtime.pop(); + runtime.pop(); + } + }; + + class OpStoreLocalFloat : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + Type_Data data = runtime[0]; + int index = runtime[1]; + + runtime.getContext().setLocalFloat (index, *reinterpret_cast (&data)); + + runtime.pop(); + runtime.pop(); + } + }; + + class OpFetchIntLiteral : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + int intValue = runtime.getIntegerLiteral (runtime[0]); + runtime[0] = intValue; + } + }; + + class OpFetchFloatLiteral : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + float floatValue = runtime.getFloatLiteral (runtime[0]); + runtime[0] = *reinterpret_cast (&floatValue); + } + }; +} + +#endif + diff --git a/components/interpreter/runtime.cpp b/components/interpreter/runtime.cpp index 24048eb5a..bde4d6b9f 100644 --- a/components/interpreter/runtime.cpp +++ b/components/interpreter/runtime.cpp @@ -1,6 +1,9 @@ #include "runtime.hpp" +#include +#include + namespace Interpreter { Runtime::Runtime (Context& context) : mContext (context), mCode (0), mPC (0) {} @@ -10,6 +13,24 @@ namespace Interpreter return mPC; } + int Runtime::getIntegerLiteral (int index) const + { + assert (index>=0 && index (mCode[1])); + + const Type_Code *literalBlock = mCode + 4 + mCode[0]; + + return *reinterpret_cast (&literalBlock[index]); + } + + float Runtime::getFloatLiteral (int index) const + { + assert (index>=0 && index (mCode[2])); + + const Type_Code *literalBlock = mCode + 4 + mCode[0] + mCode[1]; + + return *reinterpret_cast (&literalBlock[index]); + } + void Runtime::configure (const Interpreter::Type_Code *code, int codeSize) { clear(); @@ -23,11 +44,38 @@ namespace Interpreter { mCode = 0; mCodeSize = 0; + mStack.clear(); } void Runtime::setPC (int PC) { mPC = PC; } + + void Runtime::push (Type_Data data) + { + mStack.push_back (data); + } + + void Runtime::pop() + { + if (mStack.empty()) + throw std::runtime_error ("stack underflow"); + + mStack.resize (mStack.size()-1); + } + + Type_Data& Runtime::operator[] (int Index) + { + if (Index<0 || Index>=static_cast (mStack.size())) + throw std::runtime_error ("stack index out of range"); + + return mStack[mStack.size()-Index-1]; + } + + Context& Runtime::getContext() + { + return mContext; + } } diff --git a/components/interpreter/runtime.hpp b/components/interpreter/runtime.hpp index e45789f16..a683a0f0f 100644 --- a/components/interpreter/runtime.hpp +++ b/components/interpreter/runtime.hpp @@ -1,6 +1,8 @@ #ifndef INTERPRETER_RUNTIME_H_INCLUDED #define INTERPRETER_RUNTIME_H_INCLUDED +#include + #include "types.hpp" namespace Interpreter @@ -15,6 +17,7 @@ namespace Interpreter const Type_Code *mCode; int mCodeSize; int mPC; + std::vector mStack; public: @@ -23,7 +26,11 @@ namespace Interpreter int getPC() const; ///< return program counter. - void configure (const Interpreter::Type_Code *code, int codeSize); + int getIntegerLiteral (int index) const; + + float getFloatLiteral (int index) const; + + void configure (const 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. @@ -31,7 +38,17 @@ namespace Interpreter void setPC (int PC); ///< set program counter. - + + void push (Type_Data data); + ///< push data on stack + + void pop(); + ///< pop stack + + Type_Data& operator[] (int Index); + ///< Access stack member, counted from the top. + + Context& getContext(); }; }