diff --git a/bin/example.wasm b/bin/example.wasm index 599c73b..515e672 100644 --- a/bin/example.wasm +++ b/bin/example.wasm @@ -89,6 +89,11 @@ seti %B $4; int $3; # Jump over the interrupt -call program_exit; +call noop_function; int $3; -program_exit: \ No newline at end of file +jmp the_real_exit; + +noop_function: +ret; + +the_real_exit: \ No newline at end of file diff --git a/include/interpret/statement.hpp b/include/interpret/statement.hpp index d046a0b..7e900c1 100644 --- a/include/interpret/statement.hpp +++ b/include/interpret/statement.hpp @@ -66,6 +66,11 @@ namespace Interpret FunctionCallStatement(std::string const & label); }; + struct ReturnFromFunctionStatement : Statement + { + void Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) override; + }; + struct SetStatement : Statement { Value firstArgument; diff --git a/include/token/operandtype.hpp b/include/token/operandtype.hpp index b6f534f..56bc07b 100644 --- a/include/token/operandtype.hpp +++ b/include/token/operandtype.hpp @@ -14,6 +14,7 @@ namespace Token ShiftIntegerRight, Jump, CallFunction, + ReturnFromFunction, LessThanInteger, GreaterThanInteger, EqualInteger, diff --git a/src/interpret/operanddefinitions.cpp b/src/interpret/operanddefinitions.cpp index 7cfaef9..4bbb64f 100644 --- a/src/interpret/operanddefinitions.cpp +++ b/src/interpret/operanddefinitions.cpp @@ -165,6 +165,11 @@ namespace Interpret return std::make_unique(std::get(labelToken.data)); } + case Token::OperandType::ReturnFromFunction: + { + return std::make_unique(); + } + case Token::OperandType::LessThanInteger: { auto statement = std::make_unique(); @@ -310,6 +315,7 @@ namespace Interpret default: std::printf("WARNING: returning default argument length of 0 for operand type %i\n", static_cast(type)); + case Token::OperandType::ReturnFromFunction: return 0; } } diff --git a/src/interpret/statement.cpp b/src/interpret/statement.cpp index 87a902c..82569d4 100644 --- a/src/interpret/statement.cpp +++ b/src/interpret/statement.cpp @@ -66,6 +66,17 @@ namespace Interpret { } + void ReturnFromFunctionStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) + { + if (state.stackPointer < sizeof(unsigned)) + { + throw Execute::StackUnderflow(); + } + + state.nextStatement = *(reinterpret_cast(state.memory.data() + (state.stackPointer - 1u))); + state.stackPointer -= sizeof(unsigned); + } + void SetStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers) { firstArgument.GetValue(state, registers) = secondArgument.GetValue(state, registers); diff --git a/src/token/operandtype.cpp b/src/token/operandtype.cpp index fa911ad..c8b4789 100644 --- a/src/token/operandtype.cpp +++ b/src/token/operandtype.cpp @@ -15,6 +15,7 @@ namespace Token { "shli", OperandType::ShiftIntegerLeft }, { "jmp", OperandType::Jump }, { "call", OperandType::CallFunction }, + { "ret", OperandType::ReturnFromFunction }, { "lti", OperandType::LessThanInteger }, { "gti", OperandType::GreaterThanInteger }, { "eqi", OperandType::EqualInteger },