You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/interpreter/runtime.cpp

120 lines
2.7 KiB
C++

#include "runtime.hpp"
#include <stdexcept>
#include <cassert>
#include <cstring>
namespace Interpreter
{
Runtime::Runtime() : mContext (nullptr), mCode (nullptr), mCodeSize(0), mPC (0) {}
int Runtime::getPC() const
{
return mPC;
}
int Runtime::getIntegerLiteral (int index) const
{
if (index < 0 || index >= static_cast<int> (mCode[1]))
throw std::out_of_range("out of range");
const Type_Code *literalBlock = mCode + 4 + mCode[0];
return *reinterpret_cast<const int *> (&literalBlock[index]);
}
float Runtime::getFloatLiteral (int index) const
{
if (index < 0 || index >= static_cast<int> (mCode[2]))
throw std::out_of_range("out of range");
const Type_Code *literalBlock = mCode + 4 + mCode[0] + mCode[1];
return *reinterpret_cast<const float *> (&literalBlock[index]);
}
std::string Runtime::getStringLiteral (int index) const
{
if (index < 0 || static_cast<int> (mCode[3]) <= 0)
throw std::out_of_range("out of range");
const char *literalBlock =
reinterpret_cast<const char *> (mCode + 4 + mCode[0] + mCode[1] + mCode[2]);
int offset = 0;
for (; index; --index)
{
offset += static_cast<int>(std::strlen (literalBlock+offset)) + 1;
if (offset / 4 >= static_cast<int> (mCode[3]))
throw std::out_of_range("out of range");
}
return literalBlock+offset;
}
void Runtime::configure (const Type_Code *code, int codeSize, Context& context)
{
clear();
mContext = &context;
mCode = code;
mCodeSize = codeSize;
mPC = 0;
}
void Runtime::clear()
{
mContext = nullptr;
mCode = nullptr;
mCodeSize = 0;
mStack.clear();
}
void Runtime::setPC (int PC)
{
mPC = PC;
}
void Runtime::push (const Data& data)
{
mStack.push_back (data);
}
void Runtime::push (Type_Integer value)
{
Data data;
data.mInteger = value;
push (data);
}
void Runtime::push (Type_Float value)
{
Data data;
data.mFloat = value;
push (data);
}
void Runtime::pop()
{
if (mStack.empty())
throw std::runtime_error ("stack underflow");
mStack.pop_back();
}
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()
{
assert (mContext);
return *mContext;
}
}