1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-04 10:45:34 +00:00
openmw/components/interpreter/runtime.cpp

125 lines
2.7 KiB
C++
Raw Normal View History

2010-06-28 17:20:45 +00:00
#include "runtime.hpp"
2010-06-28 19:49:48 +00:00
#include <cassert>
#include <cstring>
2022-09-22 18:26:05 +00:00
#include <stdexcept>
2010-06-28 19:49:48 +00:00
2010-06-28 17:20:45 +00:00
namespace Interpreter
{
2022-09-22 18:26:05 +00:00
Runtime::Runtime()
: mContext(nullptr)
, mCode(nullptr)
, mCodeSize(0)
, mPC(0)
{
}
2010-06-28 18:46:15 +00:00
int Runtime::getPC() const
{
return mPC;
}
2022-09-22 18:26:05 +00:00
int Runtime::getIntegerLiteral(int index) const
2010-06-28 19:49:48 +00:00
{
2022-09-22 18:26:05 +00:00
if (index < 0 || index >= static_cast<int>(mCode[1]))
throw std::out_of_range("out of range");
2022-09-22 18:26:05 +00:00
const Type_Code* literalBlock = mCode + 4 + mCode[0];
2022-09-22 18:26:05 +00:00
return *reinterpret_cast<const int*>(&literalBlock[index]);
2010-06-28 19:49:48 +00:00
}
2022-09-22 18:26:05 +00:00
float Runtime::getFloatLiteral(int index) const
2010-06-28 19:49:48 +00:00
{
2022-09-22 18:26:05 +00:00
if (index < 0 || index >= static_cast<int>(mCode[2]))
throw std::out_of_range("out of range");
2022-09-22 18:26:05 +00:00
const Type_Code* literalBlock = mCode + 4 + mCode[0] + mCode[1];
2022-09-22 18:26:05 +00:00
return *reinterpret_cast<const float*>(&literalBlock[index]);
2010-06-28 19:49:48 +00:00
}
std::string_view Runtime::getStringLiteral(int index) const
{
2022-09-22 18:26:05 +00:00
if (index < 0 || static_cast<int>(mCode[3]) <= 0)
throw std::out_of_range("out of range");
2022-09-22 18:26:05 +00:00
const char* literalBlock = reinterpret_cast<const char*>(mCode + 4 + mCode[0] + mCode[1] + mCode[2]);
size_t offset = 0;
for (; index; --index)
{
offset += std::strlen(literalBlock + offset) + 1;
if (offset / 4 >= mCode[3])
throw std::out_of_range("out of range");
}
2022-09-22 18:26:05 +00:00
return literalBlock + offset;
}
2022-09-22 18:26:05 +00:00
void Runtime::configure(const Type_Code* code, int codeSize, Context& context)
{
2010-06-28 17:20:45 +00:00
clear();
mContext = &context;
2010-06-28 17:20:45 +00:00
mCode = code;
mCodeSize = codeSize;
2010-06-28 18:46:15 +00:00
mPC = 0;
2010-06-28 17:20:45 +00:00
}
void Runtime::clear()
{
2020-11-13 07:39:47 +00:00
mContext = nullptr;
mCode = nullptr;
2010-06-28 17:20:45 +00:00
mCodeSize = 0;
2010-06-28 19:49:48 +00:00
mStack.clear();
2010-06-28 17:20:45 +00:00
}
2022-09-22 18:26:05 +00:00
void Runtime::setPC(int PC)
2010-06-28 18:46:15 +00:00
{
mPC = PC;
}
2022-09-22 18:26:05 +00:00
void Runtime::push(const Data& data)
2010-06-28 19:49:48 +00:00
{
2022-09-22 18:26:05 +00:00
mStack.push_back(data);
2010-06-28 19:49:48 +00:00
}
2022-09-22 18:26:05 +00:00
void Runtime::push(Type_Integer value)
{
Data data;
data.mInteger = value;
2022-09-22 18:26:05 +00:00
push(data);
}
2022-09-22 18:26:05 +00:00
void Runtime::push(Type_Float value)
{
Data data;
data.mFloat = value;
2022-09-22 18:26:05 +00:00
push(data);
}
2010-06-28 19:49:48 +00:00
void Runtime::pop()
{
if (mStack.empty())
2022-09-22 18:26:05 +00:00
throw std::runtime_error("stack underflow");
2022-01-28 14:26:43 +00:00
mStack.pop_back();
2010-06-28 19:49:48 +00:00
}
2022-09-22 18:26:05 +00:00
Data& Runtime::operator[](int Index)
2010-06-28 19:49:48 +00:00
{
2022-09-22 18:26:05 +00:00
if (Index < 0 || Index >= static_cast<int>(mStack.size()))
throw std::runtime_error("stack index out of range");
2022-09-22 18:26:05 +00:00
return mStack[mStack.size() - Index - 1];
2010-06-28 19:49:48 +00:00
}
2010-06-28 19:49:48 +00:00
Context& Runtime::getContext()
{
2022-09-22 18:26:05 +00:00
assert(mContext);
return *mContext;
2010-06-28 19:49:48 +00:00
}
2010-06-28 17:20:45 +00:00
}