mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 03:26:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			119 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			119 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.resize (mStack.size()-1);
 | 
						|
    }
 | 
						|
 | 
						|
    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;
 | 
						|
    }
 | 
						|
}
 |