Fix string stack issue returning from a foreach statement.

This commit is contained in:
Jeff Hutchinson 2021-08-31 22:18:08 -04:00
parent 485330ec7a
commit f04aca9def
2 changed files with 162 additions and 42 deletions

View file

@ -1257,9 +1257,9 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
{
iterStack[--_ITER].mIsStringIter = false;
--iterDepth;
}
_STK--; // this is a pop from foreach()
_STK--; // this is a pop from foreach()
}
}
returnValue.setEmptyString();
@ -1269,61 +1269,48 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
case OP_RETURN:
{
if (iterDepth > 0)
{
// Clear iterator state.
while (iterDepth > 0)
{
iterStack[--_ITER].mIsStringIter = false;
--iterDepth;
}
const char* retVal = stack[_STK].getString();
_STK--;
_STK--;
stack[_STK + 1].setString(retVal);
_STK++; // Not nice but works.
}
returnValue = std::move(stack[_STK]);
_STK--;
// Clear iterator state.
while (iterDepth > 0)
{
iterStack[--_ITER].mIsStringIter = false;
--iterDepth;
_STK--;
}
goto execFinished;
}
case OP_RETURN_FLT:
if (iterDepth > 0)
{
// Clear iterator state.
while (iterDepth > 0)
{
iterStack[--_ITER].mIsStringIter = false;
--iterDepth;
}
}
returnValue.setFloat(stack[_STK].getFloat());
_STK--;
// Clear iterator state.
while (iterDepth > 0)
{
iterStack[--_ITER].mIsStringIter = false;
--iterDepth;
_STK--;
}
goto execFinished;
case OP_RETURN_UINT:
if (iterDepth > 0)
{
// Clear iterator state.
while (iterDepth > 0)
{
iterStack[--_ITER].mIsStringIter = false;
--iterDepth;
}
}
returnValue.setInt(stack[_STK].getInt());
_STK--;
// Clear iterator state.
while (iterDepth > 0)
{
iterStack[--_ITER].mIsStringIter = false;
--iterDepth;
_STK--;
}
goto execFinished;
case OP_CMPEQ:

View file

@ -405,6 +405,124 @@ TEST(Script, ForEachLoop)
)");
ASSERT_EQ(forEach4.getInt(), 5);
ConsoleValue forEach5 = RunScript(R"(
function SimObject::ret1(%this)
{
return 1;
}
function SimSet::doForeach5(%this)
{
%count = 0;
foreach (%obj in %this)
{
%count += %obj.ret1();
}
return %count;
}
function a()
{
%set = new SimSet();
%set.add(new SimObject());
%set.add(new SimObject());
%set.add(new SimObject());
return %set.doForeach5();
}
return a();
)");
ASSERT_EQ(forEach5.getInt(), 3);
ConsoleValue forEachContinue = RunScript(R"(
function SimSet::foreach6(%this)
{
%count = 0;
foreach (%obj in %this)
{
if (%obj.getName() $= "A")
continue;
%count++;
}
return %count;
}
function a()
{
%set = new SimSet();
%set.add(new SimObject(A));
%set.add(new SimObject());
%set.add(new SimObject());
return %set.foreach6();
}
return a();
)");
ASSERT_EQ(forEachContinue.getInt(), 2);
ConsoleValue forEachReturn = RunScript(R"(
function SimSet::findA(%this)
{
foreach (%obj in %this)
{
if (%obj.getName() $= "A")
return 76;
}
return 0;
}
function a()
{
%set = new SimSet();
%set.add(new SimObject(A));
%set.add(new SimObject());
%set.add(new SimObject());
return %set.findA();
}
return a();
)");
ASSERT_EQ(forEachReturn.getInt(), 76);
ConsoleValue forEachNestedReturn = RunScript(R"(
function SimSet::findA(%this)
{
foreach (%obj in %this)
{
foreach (%innerObj in %this)
{
if (%innerObj.getName() $= "A")
return 42;
}
}
return 0;
}
function a()
{
%set = new SimSet();
%set.add(new SimObject(A));
%set.add(new SimObject());
%set.add(new SimObject());
%group = new SimGroup();
%group.add(%set);
return %set.findA();
}
return a();
)");
ASSERT_EQ(forEachNestedReturn.getInt(), 42);
}
TEST(Script, TorqueScript_Array_Testing)
@ -682,6 +800,21 @@ TEST(Script, Sugar_Syntax)
)");
ASSERT_EQ(valueSetArray.getInt(), 5);
ConsoleValue valueStoreCalculated = RunScript(R"(
function a()
{
%extent = 10 SPC 20;
%scaling = 1;
%size = %extent.x * %scaling;
echo("%size = " @ %size @ " calculated = " @ (%extent.x * %scaling));
return %size;
}
return a();
)");
ASSERT_EQ(valueStoreCalculated.getInt(), 10);
}
TEST(Script, InnerObjectTests)