mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 08:56:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			124 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "runtime.hpp"
 | |
| 
 | |
| #include <cassert>
 | |
| #include <cstring>
 | |
| #include <stdexcept>
 | |
| 
 | |
| 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_view 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]);
 | |
| 
 | |
|         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");
 | |
|         }
 | |
| 
 | |
|         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;
 | |
|     }
 | |
| }
 |