forked from mirror/openmw-tes3mp
added first batch of opcodes
This commit is contained in:
parent
d80cb3461c
commit
c6a37b2e18
10 changed files with 270 additions and 4 deletions
|
@ -76,7 +76,8 @@ set(COMPILER components/compiler/errorhandler.cpp
|
||||||
file(GLOB COMPILER_HEADER components/compiler/*.hpp)
|
file(GLOB COMPILER_HEADER components/compiler/*.hpp)
|
||||||
source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER})
|
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)
|
file(GLOB INTERPRETER_HEADER components/interpreter/*.hpp)
|
||||||
source_group(interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER})
|
source_group(interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER})
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <components/interpreter/interpreter.hpp>
|
#include <components/interpreter/interpreter.hpp>
|
||||||
#include <components/interpreter/context.hpp>
|
#include <components/interpreter/context.hpp>
|
||||||
#include <components/interpreter/types.hpp>
|
#include <components/interpreter/types.hpp>
|
||||||
|
#include <components/interpreter/installopcodes.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ int main (int argc, char **argv)
|
||||||
|
|
||||||
SAInterpreter::Context context (localfilename);
|
SAInterpreter::Context context (localfilename);
|
||||||
Interpreter::Interpreter interpreter (context);
|
Interpreter::Interpreter interpreter (context);
|
||||||
|
Interpreter::installOpcodes (interpreter);
|
||||||
|
|
||||||
std::string codefilename = filename + ".code";
|
std::string codefilename = filename + ".code";
|
||||||
|
|
||||||
|
|
33
components/interpreter/genericopcodes.hpp
Normal file
33
components/interpreter/genericopcodes.hpp
Normal file
|
@ -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<Type_Float> (data);
|
||||||
|
runtime[0] = *reinterpret_cast<Type_Data *> (&floatValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
24
components/interpreter/installopcodes.cpp
Normal file
24
components/interpreter/installopcodes.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
11
components/interpreter/installopcodes.hpp
Normal file
11
components/interpreter/installopcodes.hpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef INTERPRETER_INSTALLOPCODES_H_INCLUDED
|
||||||
|
#define INTERPRETER_INSTALLOPCODES_H_INCLUDED
|
||||||
|
|
||||||
|
namespace Interpreter
|
||||||
|
{
|
||||||
|
class Interpreter;
|
||||||
|
|
||||||
|
void installOpcodes (Interpreter& interpreter);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -165,7 +165,37 @@ namespace Interpreter
|
||||||
delete iter->second;
|
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);
|
assert (codeSize>=4);
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,24 @@ namespace Interpreter
|
||||||
|
|
||||||
~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);
|
void run (const Type_Code *code, int codeSize);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
82
components/interpreter/localopcodes.hpp
Normal file
82
components/interpreter/localopcodes.hpp
Normal file
|
@ -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<int *> (&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<int *> (&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<float *> (&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<Type_Data *> (&floatValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
|
||||||
#include "runtime.hpp"
|
#include "runtime.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace Interpreter
|
namespace Interpreter
|
||||||
{
|
{
|
||||||
Runtime::Runtime (Context& context) : mContext (context), mCode (0), mPC (0) {}
|
Runtime::Runtime (Context& context) : mContext (context), mCode (0), mPC (0) {}
|
||||||
|
@ -10,6 +13,24 @@ namespace Interpreter
|
||||||
return mPC;
|
return mPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Runtime::getIntegerLiteral (int index) const
|
||||||
|
{
|
||||||
|
assert (index>=0 && index<static_cast<int> (mCode[1]));
|
||||||
|
|
||||||
|
const Type_Code *literalBlock = mCode + 4 + mCode[0];
|
||||||
|
|
||||||
|
return *reinterpret_cast<const int *> (&literalBlock[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Runtime::getFloatLiteral (int index) const
|
||||||
|
{
|
||||||
|
assert (index>=0 && index<static_cast<int> (mCode[2]));
|
||||||
|
|
||||||
|
const Type_Code *literalBlock = mCode + 4 + mCode[0] + mCode[1];
|
||||||
|
|
||||||
|
return *reinterpret_cast<const float *> (&literalBlock[index]);
|
||||||
|
}
|
||||||
|
|
||||||
void Runtime::configure (const Interpreter::Type_Code *code, int codeSize)
|
void Runtime::configure (const Interpreter::Type_Code *code, int codeSize)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -23,11 +44,38 @@ namespace Interpreter
|
||||||
{
|
{
|
||||||
mCode = 0;
|
mCode = 0;
|
||||||
mCodeSize = 0;
|
mCodeSize = 0;
|
||||||
|
mStack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runtime::setPC (int PC)
|
void Runtime::setPC (int PC)
|
||||||
{
|
{
|
||||||
mPC = 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<int> (mStack.size()))
|
||||||
|
throw std::runtime_error ("stack index out of range");
|
||||||
|
|
||||||
|
return mStack[mStack.size()-Index-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Context& Runtime::getContext()
|
||||||
|
{
|
||||||
|
return mContext;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef INTERPRETER_RUNTIME_H_INCLUDED
|
#ifndef INTERPRETER_RUNTIME_H_INCLUDED
|
||||||
#define INTERPRETER_RUNTIME_H_INCLUDED
|
#define INTERPRETER_RUNTIME_H_INCLUDED
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
namespace Interpreter
|
namespace Interpreter
|
||||||
|
@ -15,6 +17,7 @@ namespace Interpreter
|
||||||
const Type_Code *mCode;
|
const Type_Code *mCode;
|
||||||
int mCodeSize;
|
int mCodeSize;
|
||||||
int mPC;
|
int mPC;
|
||||||
|
std::vector<Type_Data> mStack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -23,7 +26,11 @@ namespace Interpreter
|
||||||
int getPC() const;
|
int getPC() const;
|
||||||
///< return program counter.
|
///< 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
|
///< \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.
|
||||||
|
|
||||||
|
@ -32,6 +39,16 @@ namespace Interpreter
|
||||||
void setPC (int PC);
|
void setPC (int PC);
|
||||||
///< set program counter.
|
///< 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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue