Skip to content
Open
14 changes: 14 additions & 0 deletions JSImpl/test/sprtTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,3 +423,17 @@ TEST_F(SPASMTest, StringEscapeD)
CompileAndRun(program);
ASSERT_EQ(Output.str(), "the answer\\\" is 42");
}


TEST_F(SPASMTest, DataStackResize)
{
const char* program =
"00: push 1025" "\n"
"01: push 15000" "\n"
"02: const 16025 123""\n"
"03: print 16025" "\n"
""
;
CompileAndRun(program);
ASSERT_EQ(Output.str(), "123");
}
39 changes: 36 additions & 3 deletions spasm/src/spasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,15 @@ Spasm::RunResult Spasm::run()
case OpCodes::Push:
{
const auto count = PC_t(read_reg(size));
assert(m_SP + count <= &data_stack[data_stack.size() - 1]);
if(!(m_SP + count <= &data_stack[data_stack.size() - 1]))
{
float resizeCoeff = 2.f;
if (count > data_stack.size())
{
resizeCoeff = float(ceil(count / data_stack.size()) + 1);
}
resizeDataStack(resizeCoeff);
}
std::fill(m_SP, m_SP + count, data_t{});
m_SP += count;
break;
Expand Down Expand Up @@ -236,6 +244,25 @@ Spasm::RunResult Spasm::run()
return RunResult::Success;
}

/*!
** Resizes the data stack. m_FP and m_SP are updated.
*/
void Spasm::resizeDataStack(float resizeCoefficient)
{
data_t* stackStart = &(data_stack[0]);
size_t fpOffset = m_FP - stackStart;
size_t spOffset = m_SP - stackStart;

size_t currentSize = data_stack.size();
size_t newSize = size_t(currentSize * resizeCoefficient);
data_stack.resize(newSize);

stackStart = &(data_stack[0]);
m_FP = stackStart + fpOffset;
m_SP = stackStart + spOffset;
}


/*!
** Pushes the next data_t object on the data stack
*/
Expand Down Expand Up @@ -449,7 +476,10 @@ data_t Spasm::get_local(reg_t reg)
void Spasm::set_local(reg_t reg, data_t data)
{
assert(&data_stack[0] <= (m_FP + reg));
assert((m_FP + reg) < &data_stack[data_stack.size() - 1]);
if(!((m_FP + reg) < &data_stack[data_stack.size() - 1]))
{
resizeDataStack();
}
m_FP[reg] = data;
}

Expand All @@ -462,7 +492,10 @@ data_t Spasm::pop_data()

void Spasm::push_data(data_t data)
{
assert(m_SP < &data_stack[data_stack.size() - 1]);
if(!(m_SP < &data_stack[data_stack.size() - 1]))
{
resizeDataStack();
}
*(m_SP++) = data;
}

Expand Down
4 changes: 3 additions & 1 deletion spasm/src/spasm_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ class Spasm
//! Input stream for read () operation
std::istream* istr;

//! Output stream for print () opertion
//! Output stream for print () operation
std::ostream* ostr;

void resizeDataStack(float resizeCoefficient = 2.f);

void push(reg_t reg);
void popto(reg_t reg);
void dup();
Expand Down