Improve runtime error handling
This commit is contained in:
@@ -1,27 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace Execute
|
namespace Execute
|
||||||
{
|
{
|
||||||
struct RuntimeError
|
class RuntimeError
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
std::string message;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string const & GetMessage() const;
|
||||||
|
|
||||||
|
RuntimeError();
|
||||||
|
RuntimeError(std::string const & what);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StackUnderflow : RuntimeError
|
class StackUnderflow : public RuntimeError
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
StackUnderflow();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StackOverflow : RuntimeError
|
class StackOverflow : public RuntimeError
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
StackOverflow();
|
||||||
|
};
|
||||||
|
|
||||||
|
class MissingLabel : public RuntimeError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MissingLabel(std::string const & label);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
struct BadValueType : RuntimeError
|
class BadValueType : public RuntimeError
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
BadValueType();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,5 +2,43 @@
|
|||||||
|
|
||||||
namespace Execute
|
namespace Execute
|
||||||
{
|
{
|
||||||
|
std::string const & RuntimeError::GetMessage() const
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeError::RuntimeError()
|
||||||
|
: message("Undocumented runtime error")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeError::RuntimeError(std::string const & what)
|
||||||
|
: message(what)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
StackUnderflow::StackUnderflow()
|
||||||
|
: RuntimeError("Stack underflow error")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
StackOverflow::StackOverflow()
|
||||||
|
: RuntimeError("Stack overflow error")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MissingLabel::MissingLabel(std::string const & label)
|
||||||
|
{
|
||||||
|
message = "Missing jump/function label \"";
|
||||||
|
message += label;
|
||||||
|
message += '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Internal
|
||||||
|
{
|
||||||
|
BadValueType::BadValueType()
|
||||||
|
: RuntimeError("Internal error: bad value type")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <execute/virtualmachine.hpp>
|
#include <execute/virtualmachine.hpp>
|
||||||
|
#include <execute/error.hpp>
|
||||||
|
|
||||||
namespace Execute
|
namespace Execute
|
||||||
{
|
{
|
||||||
@@ -6,7 +7,18 @@ namespace Execute
|
|||||||
{
|
{
|
||||||
state.nextStatement = state.currentStatement + 1u;
|
state.nextStatement = state.currentStatement + 1u;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
code.statements[state.currentStatement]->Execute(flags, state, registers);
|
code.statements[state.currentStatement]->Execute(flags, state, registers);
|
||||||
|
}
|
||||||
|
catch(RuntimeError & ex)
|
||||||
|
{
|
||||||
|
terminated = true;
|
||||||
|
std::puts("\nA fatal error occurred and execution has been halted:");
|
||||||
|
std::printf("%s\n", ex.GetMessage().c_str());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
state.currentStatement = state.nextStatement;
|
state.currentStatement = state.nextStatement;
|
||||||
if (state.currentStatement >= code.statements.size())
|
if (state.currentStatement >= code.statements.size())
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace Interpret
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Attempted jump to nonexisting label");
|
throw Execute::MissingLabel(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ namespace Interpret
|
|||||||
auto const & elem = state.labelStatementIndice.find(label);
|
auto const & elem = state.labelStatementIndice.find(label);
|
||||||
if (elem == state.labelStatementIndice.end())
|
if (elem == state.labelStatementIndice.end())
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Attempted call nonexisting function (missing label)");
|
throw Execute::MissingLabel(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((state.memory.size() - state.stackPointer) < sizeof(unsigned))
|
if ((state.memory.size() - state.stackPointer) < sizeof(unsigned))
|
||||||
|
|||||||
Reference in New Issue
Block a user