diff --git a/src/VM/Instructions/ControlInstructions.cpp b/src/VM/Instructions/ControlInstructions.cpp index 1849f7a..ece95b2 100644 --- a/src/VM/Instructions/ControlInstructions.cpp +++ b/src/VM/Instructions/ControlInstructions.cpp @@ -18,6 +18,13 @@ #include "VM/VM.h" #include "Data/Variable.h" +static void returnCat1Var(VMThread* thread) +{ + const Variable returnVal = thread->m_currentFrame->popOperand(); + thread->popFrame(); + thread->returnVar(returnVal); +} + void gotoInstruction(INSTRUCTION_ARGS) { u1 byte1 = args[0]; @@ -30,98 +37,27 @@ void gotoInstruction(INSTRUCTION_ARGS) void freturnInstruction(INSTRUCTION_ARGS) { - StackFrame* stackFrame = thread->m_currentFrame; - thread->m_pc = stackFrame->previousPc; - thread->m_currentClass = stackFrame->previousClass; - thread->m_currentMethod = stackFrame->previousMethod; - - Variable returnVal = thread->m_currentFrame->popOperand(); - - thread->m_stack.frames.pop_back(); - if (thread->m_stack.frames.size() > 0) - { - thread->m_currentFrame = &thread->m_stack.frames[thread->m_stack.frames.size()-1]; - thread->m_currentFrame->operands.push_back(returnVal); - } else - { - thread->m_currentFrame = 0; - } + returnCat1Var(thread); } void ireturnInstruction(INSTRUCTION_ARGS) { - StackFrame* stackFrame = thread->m_currentFrame; - thread->m_pc = stackFrame->previousPc; - thread->m_currentClass = stackFrame->previousClass; - thread->m_currentMethod = stackFrame->previousMethod; - - Variable returnVal = thread->m_currentFrame->popOperand(); - - thread->m_stack.frames.pop_back(); - if (thread->m_stack.frames.size() > 0) - { - thread->m_currentFrame = &thread->m_stack.frames[thread->m_stack.frames.size()-1]; - thread->m_currentFrame->operands.push_back(returnVal); - } else - { - thread->m_currentFrame = 0; - } + returnCat1Var(thread); } void dreturnInstruction(INSTRUCTION_ARGS) { - StackFrame* stackFrame = thread->m_currentFrame; - thread->m_pc = stackFrame->previousPc; - thread->m_currentClass = stackFrame->previousClass; - thread->m_currentMethod = stackFrame->previousMethod; - - Variable lowByte = thread->m_currentFrame->popOperand(); - Variable highByte = thread->m_currentFrame->popOperand(); - - thread->m_stack.frames.pop_back(); - if (thread->m_stack.frames.size() > 0) - { - thread->m_currentFrame = &thread->m_stack.frames[thread->m_stack.frames.size()-1]; - thread->m_currentFrame->operands.push_back(highByte); - thread->m_currentFrame->operands.push_back(lowByte); - } else - { - thread->m_currentFrame = 0; - } + const Variable lowByte = thread->m_currentFrame->popOperand(); + const Variable highByte = thread->m_currentFrame->popOperand(); + thread->popFrame(); + thread->returnVar(highByte, lowByte); } void areturnInstruction(INSTRUCTION_ARGS) { - StackFrame* stackFrame = thread->m_currentFrame; - thread->m_pc = stackFrame->previousPc; - thread->m_currentClass = stackFrame->previousClass; - thread->m_currentMethod = stackFrame->previousMethod; - - Variable returnVal = thread->m_currentFrame->popOperand(); - - - thread->m_stack.frames.pop_back(); - - StackFrame* nonNativeFrame = thread->getTopFrameNonNative(); - thread->m_currentFrame = &thread->m_stack.frames[thread->m_stack.frames.size()-1]; - if (nonNativeFrame != nullptr) - { - nonNativeFrame->operands.push_back(returnVal); - } - + returnCat1Var(thread); } void returnInstruction(INSTRUCTION_ARGS) { - StackFrame* stackFrame = thread->m_currentFrame; - thread->m_pc = stackFrame->previousPc; - thread->m_currentClass = stackFrame->previousClass; - thread->m_currentMethod = stackFrame->previousMethod; - thread->m_stack.frames.pop_back(); - if (thread->m_stack.frames.size() > 0) - { - thread->m_currentFrame = &thread->m_stack.frames[thread->m_stack.frames.size()-1]; - } else - { - thread->m_currentFrame = 0; - } + thread->popFrame(); } diff --git a/src/VM/VMThread.cpp b/src/VM/VMThread.cpp index ed8a95f..8967e61 100644 --- a/src/VM/VMThread.cpp +++ b/src/VM/VMThread.cpp @@ -19,6 +19,8 @@ #include +static constexpr std::string_view NoNonNativeStackFrameFound{"Can't return to previous frame because there is no previous non-native frame"}; + void VMThread::pushStackFrameWithoutParams(ClassInfo* classInfo, const MethodInfo* methodInfo) { StackFrame stackFrame; @@ -123,9 +125,9 @@ void VMThread::pushStackFrameSpecial(ClassInfo* classInfo, const MethodInfo* met } } -void VMThread::internalError(const char* error) +void VMThread::internalError(const std::string_view error) const { - fprintf(stdout, "Unhandled VM error in thread \"%s\": %s\n", m_name.data(), error); + fprintf(stdout, "Unhandled VM error in thread \"%s\": %s\n", m_name.data(), error.data()); for (i8 currentFrame = m_stack.frames.size() - 1; currentFrame >= 0; --currentFrame) { const StackFrame frame = m_stack.frames[currentFrame]; @@ -155,26 +157,27 @@ StackFrame* VMThread::getTopFrameNonNative() void VMThread::returnVar(const Variable returnValue) { - if (m_stack.frames.size() > 1) + StackFrame* targetFrame = getTopFrameNonNative(); + if (targetFrame != nullptr) { - StackFrame* previousStackFrame = &m_stack.frames[m_stack.frames.size()-2]; - previousStackFrame->operands.push_back(returnValue); - } else + targetFrame->operands.push_back(returnValue); + } + else { - internalError("Can't return to previous frame because there is no previous frame"); + internalError(NoNonNativeStackFrameFound); } } void VMThread::returnVar(Variable highByte, Variable lowByte) { - if (m_stack.frames.size() > 1) + StackFrame* targetFrame = getTopFrameNonNative(); + if (targetFrame != nullptr) { - StackFrame* previousStackFrame = &m_stack.frames[m_stack.frames.size()-2]; - previousStackFrame->operands.push_back(highByte); - previousStackFrame->operands.push_back(lowByte); + targetFrame->operands.push_back(highByte); + targetFrame->operands.push_back(lowByte); } else { - internalError("Can't return to previous frame because there is no previous frame"); + internalError(NoNonNativeStackFrameFound); } } diff --git a/src/VM/VMThread.h b/src/VM/VMThread.h index fef0eaa..9b6e571 100644 --- a/src/VM/VMThread.h +++ b/src/VM/VMThread.h @@ -29,7 +29,7 @@ class VMThread void pushStackFrameSpecial(ClassInfo* classInfo, const MethodInfo* methodInfo, StackFrame* previousFrame, JavaHeap* heap); void returnVar(Variable returnValue); void returnVar(Variable highByte, Variable lowByte); - void internalError(const char* error); + void internalError(std::string_view error) const; StackFrame* getTopFrameNonNative(); };