mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-12 19:31:41 +00:00
Beginnings of the "pass everything using a native type wrapper" console code.
- ConsoleValue class is now the base value class. - ConsoleValueRef is now used to supply function parameters. Values are disposable. - Script functions return values instead of just strings where possible. - Variables can be disposable strings - Bytecode changed Fix the issues with console method parameters and fields which prevented missions from loading.
This commit is contained in:
parent
394d87cd54
commit
38c8e52c1d
68 changed files with 1511 additions and 529 deletions
|
|
@ -102,7 +102,11 @@ IterStackRecord iterStack[ MaxStackSize ];
|
|||
F64 floatStack[MaxStackSize];
|
||||
S64 intStack[MaxStackSize];
|
||||
|
||||
|
||||
|
||||
|
||||
StringStack STR;
|
||||
ConsoleValueStack CSTK;
|
||||
|
||||
U32 _FLT = 0; ///< Stack pointer for floatStack.
|
||||
U32 _UINT = 0; ///< Stack pointer for intStack.
|
||||
|
|
@ -401,14 +405,15 @@ static void setFieldComponent( SimObject* object, StringTableEntry field, const
|
|||
}
|
||||
}
|
||||
|
||||
const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, const char **argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
|
||||
ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
U32 stackStart = STR.mStartStackSize;
|
||||
U32 consoleStackStart = CSTK.mStackPos;
|
||||
#endif
|
||||
|
||||
static char traceBuffer[1024];
|
||||
U32 i;
|
||||
S32 i;
|
||||
|
||||
U32 iterDepth = 0;
|
||||
|
||||
|
|
@ -424,7 +429,7 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
// assume this points into a function decl:
|
||||
U32 fnArgc = code[ip + 5];
|
||||
thisFunctionName = U32toSTE(code[ip]);
|
||||
argc = getMin(argc-1, fnArgc); // argv[0] is func name
|
||||
S32 wantedArgc = getMin(argc-1, fnArgc); // argv[0] is func name
|
||||
if(gEvalState.traceOn)
|
||||
{
|
||||
traceBuffer[0] = 0;
|
||||
|
|
@ -456,11 +461,22 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
}
|
||||
gEvalState.pushFrame(thisFunctionName, thisNamespace);
|
||||
popFrame = true;
|
||||
for(i = 0; i < argc; i++)
|
||||
|
||||
for(i = 0; i < wantedArgc; i++)
|
||||
{
|
||||
StringTableEntry var = U32toSTE(code[ip + i + 6]);
|
||||
gEvalState.setCurVarNameCreate(var);
|
||||
gEvalState.setStringVariable(argv[i+1]);
|
||||
|
||||
ConsoleValueRef ref = argv[i+1];
|
||||
|
||||
if (argv[i+1].isString())
|
||||
gEvalState.setStringVariable(argv[i+1]);
|
||||
else if (argv[i+1].isInt())
|
||||
gEvalState.setIntVariable(argv[i+1]);
|
||||
else if (argv[i+1].isFloat())
|
||||
gEvalState.setFloatVariable(argv[i+1]);
|
||||
else
|
||||
gEvalState.setStringVariable(argv[i+1]);
|
||||
}
|
||||
ip = ip + fnArgc + 6;
|
||||
curFloatTable = functionFloats;
|
||||
|
|
@ -497,6 +513,11 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
}
|
||||
}
|
||||
|
||||
// jamesu - reset the console stack frame which at this point will contain
|
||||
// either nothing or argv[] which we just copied
|
||||
// NOTE: it might be better to do this when we are finished?
|
||||
CSTK.resetFrame();
|
||||
|
||||
// Grab the state of the telenet debugger here once
|
||||
// so that the push and pop frames are always balanced.
|
||||
const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected();
|
||||
|
|
@ -530,7 +551,7 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
char nsDocBlockClass[nsDocLength];
|
||||
|
||||
U32 callArgc;
|
||||
const char **callArgv;
|
||||
ConsoleValueRef *callArgv;
|
||||
|
||||
static char curFieldArray[256];
|
||||
static char prevFieldArray[256];
|
||||
|
|
@ -543,6 +564,10 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
Con::gCurrentRoot = this->modPath;
|
||||
}
|
||||
const char * val;
|
||||
const char *retValue;
|
||||
|
||||
// note: anything returned is pushed to CSTK and will be invalidated on the next exec()
|
||||
ConsoleValueRef returnValue;
|
||||
|
||||
// The frame temp is used by the variable accessor ops (OP_SAVEFIELD_* and
|
||||
// OP_LOADFIELD_*) to store temporary values for the fields.
|
||||
|
|
@ -615,8 +640,8 @@ breakContinue:
|
|||
objectCreationStack[ objectCreationStackIndex++ ].failJump = failJump;
|
||||
|
||||
// Get the constructor information off the stack.
|
||||
STR.getArgcArgv(NULL, &callArgc, &callArgv);
|
||||
const char* objectName = callArgv[ 2 ];
|
||||
CSTK.getArgcArgv(NULL, &callArgc, &callArgv);
|
||||
const char *objectName = callArgv[ 2 ];
|
||||
|
||||
// Con::printf("Creating object...");
|
||||
|
||||
|
|
@ -638,6 +663,7 @@ breakContinue:
|
|||
Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare data block %s with a different class.", getFileLine(ip), objectName);
|
||||
ip = failJump;
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -650,18 +676,19 @@ breakContinue:
|
|||
// IF we aren't looking at a local/internal object, then check if
|
||||
// this object already exists in the global space
|
||||
|
||||
SimObject *obj = Sim::findObject( objectName );
|
||||
SimObject *obj = Sim::findObject( (const char*)objectName );
|
||||
if (obj /*&& !obj->isLocalName()*/)
|
||||
{
|
||||
if ( isSingleton )
|
||||
{
|
||||
// Make sure we're not trying to change types
|
||||
if ( dStricmp( obj->getClassName(), callArgv[1] ) != 0 )
|
||||
if ( dStricmp( obj->getClassName(), (const char*)callArgv[1] ) != 0 )
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare object [%s] with a different class [%s] - was [%s].",
|
||||
getFileLine(ip), objectName, callArgv[1], obj->getClassName());
|
||||
getFileLine(ip), objectName, (const char*)callArgv[1], obj->getClassName());
|
||||
ip = failJump;
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -679,13 +706,29 @@ breakContinue:
|
|||
// string stack and may get stomped if deleteObject triggers
|
||||
// script execution.
|
||||
|
||||
const char* savedArgv[ StringStack::MaxArgs ];
|
||||
dMemcpy( savedArgv, callArgv, sizeof( savedArgv[ 0 ] ) * callArgc );
|
||||
ConsoleValueRef savedArgv[ StringStack::MaxArgs ];
|
||||
for (int i=0; i<callArgc; i++) {
|
||||
savedArgv[i] = callArgv[i];
|
||||
}
|
||||
//dMemcpy( savedArgv, callArgv, sizeof( savedArgv[ 0 ] ) * callArgc );
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.pushFrame();
|
||||
STR.pushFrame();
|
||||
// --
|
||||
|
||||
obj->deleteObject();
|
||||
obj = NULL;
|
||||
|
||||
dMemcpy( callArgv, savedArgv, sizeof( callArgv[ 0 ] ) * callArgc );
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
|
||||
//dMemcpy( callArgv, savedArgv, sizeof( callArgv[ 0 ] ) * callArgc );
|
||||
for (int i=0; i<callArgc; i++) {
|
||||
callArgv[i] = savedArgv[i];
|
||||
}
|
||||
}
|
||||
else if( dStricmp( redefineBehavior, "renameNew" ) == 0 )
|
||||
{
|
||||
|
|
@ -714,6 +757,7 @@ breakContinue:
|
|||
getFileLine(ip), newName.c_str() );
|
||||
ip = failJump;
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
|
@ -725,6 +769,7 @@ breakContinue:
|
|||
getFileLine(ip), objectName);
|
||||
ip = failJump;
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -732,16 +777,17 @@ breakContinue:
|
|||
}
|
||||
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
|
||||
if(!currentNewObject)
|
||||
{
|
||||
// Well, looks like we have to create a new object.
|
||||
ConsoleObject *object = ConsoleObject::create(callArgv[1]);
|
||||
ConsoleObject *object = ConsoleObject::create((const char*)callArgv[1]);
|
||||
|
||||
// Deal with failure!
|
||||
if(!object)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", getFileLine(ip), callArgv[1]);
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", getFileLine(ip), (const char*)callArgv[1]);
|
||||
ip = failJump;
|
||||
break;
|
||||
}
|
||||
|
|
@ -757,7 +803,7 @@ breakContinue:
|
|||
else
|
||||
{
|
||||
// They tried to make a non-datablock with a datablock keyword!
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-datablock class %s.", getFileLine(ip), callArgv[1]);
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-datablock class %s.", getFileLine(ip), (const char*)callArgv[1]);
|
||||
// Clean up...
|
||||
delete object;
|
||||
ip = failJump;
|
||||
|
|
@ -771,7 +817,7 @@ breakContinue:
|
|||
// Deal with the case of a non-SimObject.
|
||||
if(!currentNewObject)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", getFileLine(ip), callArgv[1]);
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", getFileLine(ip), (const char*)callArgv[1]);
|
||||
delete object;
|
||||
ip = failJump;
|
||||
break;
|
||||
|
|
@ -798,7 +844,7 @@ breakContinue:
|
|||
else
|
||||
{
|
||||
if ( Con::gObjectCopyFailures == -1 )
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", getFileLine(ip), objParent, callArgv[1]);
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", getFileLine(ip), objParent, (const char*)callArgv[1]);
|
||||
else
|
||||
++Con::gObjectCopyFailures;
|
||||
|
||||
|
|
@ -821,15 +867,30 @@ breakContinue:
|
|||
currentNewObject->setOriginalName( objectName );
|
||||
}
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.pushFrame();
|
||||
STR.pushFrame();
|
||||
// --
|
||||
|
||||
// Do the constructor parameters.
|
||||
if(!currentNewObject->processArguments(callArgc-3, callArgv+3))
|
||||
{
|
||||
delete currentNewObject;
|
||||
currentNewObject = NULL;
|
||||
ip = failJump;
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
break;
|
||||
}
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
|
||||
// If it's not a datablock, allow people to modify bits of it.
|
||||
if(!isDataBlock)
|
||||
{
|
||||
|
|
@ -854,6 +915,11 @@ breakContinue:
|
|||
|
||||
// Con::printf("Adding object %s", currentNewObject->getName());
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.pushFrame();
|
||||
STR.pushFrame();
|
||||
// --
|
||||
|
||||
// Make sure it wasn't already added, then add it.
|
||||
if(currentNewObject->isProperlyAdded() == false)
|
||||
{
|
||||
|
|
@ -877,6 +943,10 @@ breakContinue:
|
|||
Con::warnf(ConsoleLogEntry::General, "%s: Register object failed for object %s of class %s.", getFileLine(ip), currentNewObject->getName(), currentNewObject->getClassName());
|
||||
delete currentNewObject;
|
||||
ip = failJump;
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -885,6 +955,8 @@ breakContinue:
|
|||
SimDataBlock *dataBlock = dynamic_cast<SimDataBlock *>(currentNewObject);
|
||||
static String errorStr;
|
||||
|
||||
|
||||
|
||||
// If so, preload it.
|
||||
if(dataBlock && !dataBlock->preload(true, errorStr))
|
||||
{
|
||||
|
|
@ -892,6 +964,11 @@ breakContinue:
|
|||
currentNewObject->getName(), errorStr.c_str());
|
||||
dataBlock->deleteObject();
|
||||
ip = failJump;
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -946,6 +1023,10 @@ breakContinue:
|
|||
else
|
||||
intStack[++_UINT] = currentNewObject->getId();
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1028,6 +1109,29 @@ breakContinue:
|
|||
// We're falling thru here on purpose.
|
||||
|
||||
case OP_RETURN:
|
||||
retValue = STR.getStringValue();
|
||||
|
||||
if( iterDepth > 0 )
|
||||
{
|
||||
// Clear iterator state.
|
||||
while( iterDepth > 0 )
|
||||
{
|
||||
iterStack[ -- _ITER ].mIsStringIter = false;
|
||||
-- iterDepth;
|
||||
}
|
||||
|
||||
STR.rewind();
|
||||
STR.setStringValue( retValue ); // Not nice but works.
|
||||
retValue = STR.getStringValue();
|
||||
}
|
||||
|
||||
// Previously the return value was on the stack and would be returned using STR.getStringValue().
|
||||
// Now though we need to wrap it in a ConsoleValueRef
|
||||
returnValue.value = CSTK.pushStackString(retValue);
|
||||
|
||||
goto execFinished;
|
||||
|
||||
case OP_RETURN_FLT:
|
||||
|
||||
if( iterDepth > 0 )
|
||||
{
|
||||
|
|
@ -1038,10 +1142,27 @@ breakContinue:
|
|||
-- iterDepth;
|
||||
}
|
||||
|
||||
const char* returnValue = STR.getStringValue();
|
||||
STR.rewind();
|
||||
STR.setStringValue( returnValue ); // Not nice but works.
|
||||
}
|
||||
|
||||
returnValue.value = CSTK.pushFLT(floatStack[_FLT]);
|
||||
_FLT--;
|
||||
|
||||
goto execFinished;
|
||||
|
||||
case OP_RETURN_UINT:
|
||||
|
||||
if( iterDepth > 0 )
|
||||
{
|
||||
// Clear iterator state.
|
||||
while( iterDepth > 0 )
|
||||
{
|
||||
iterStack[ -- _ITER ].mIsStringIter = false;
|
||||
-- iterDepth;
|
||||
}
|
||||
}
|
||||
|
||||
returnValue.value = CSTK.pushUINT(intStack[_UINT]);
|
||||
_UINT--;
|
||||
|
||||
goto execFinished;
|
||||
|
||||
|
|
@ -1514,6 +1635,7 @@ breakContinue:
|
|||
getFileLine(ip-4), fnNamespace ? fnNamespace : "",
|
||||
fnNamespace ? "::" : "", fnName);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
// Now fall through to OP_CALLFUNC...
|
||||
|
|
@ -1538,7 +1660,7 @@ breakContinue:
|
|||
U32 callType = code[ip+2];
|
||||
|
||||
ip += 3;
|
||||
STR.getArgcArgv(fnName, &callArgc, &callArgv);
|
||||
CSTK.getArgcArgv(fnName, &callArgc, &callArgv);
|
||||
|
||||
const char *componentReturnValue = "";
|
||||
|
||||
|
|
@ -1555,14 +1677,15 @@ breakContinue:
|
|||
else if(callType == FuncCallExprNode::MethodCall)
|
||||
{
|
||||
saveObject = gEvalState.thisObject;
|
||||
gEvalState.thisObject = Sim::findObject(callArgv[1]);
|
||||
gEvalState.thisObject = Sim::findObject((const char*)callArgv[1]);
|
||||
if(!gEvalState.thisObject)
|
||||
{
|
||||
// Go back to the previous saved object.
|
||||
gEvalState.thisObject = saveObject;
|
||||
|
||||
Con::warnf(ConsoleLogEntry::General,"%s: Unable to find object: '%s' attempting to call function '%s'", getFileLine(ip-4), callArgv[1], fnName);
|
||||
Con::warnf(ConsoleLogEntry::General,"%s: Unable to find object: '%s' attempting to call function '%s'", getFileLine(ip-4), (const char*)callArgv[1], fnName);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1618,6 +1741,7 @@ breakContinue:
|
|||
}
|
||||
}
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
|
||||
if( routingId == MethodOnComponent )
|
||||
STR.setStringValue( componentReturnValue );
|
||||
|
|
@ -1628,12 +1752,30 @@ breakContinue:
|
|||
}
|
||||
if(nsEntry->mType == Namespace::Entry::ConsoleFunctionType)
|
||||
{
|
||||
const char *ret = "";
|
||||
ConsoleValueRef ret;
|
||||
if(nsEntry->mFunctionOffset)
|
||||
ret = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage);
|
||||
|
||||
STR.popFrame();
|
||||
STR.setStringValue(ret);
|
||||
|
||||
STR.popFrame();
|
||||
// Functions are assumed to return strings, so look ahead to see if we can skip the conversion
|
||||
if(code[ip] == OP_STR_TO_UINT)
|
||||
{
|
||||
ip++;
|
||||
intStack[++_UINT] = (U32)((S32)ret);
|
||||
}
|
||||
else if(code[ip] == OP_STR_TO_FLT)
|
||||
{
|
||||
ip++;
|
||||
floatStack[++_FLT] = (F32)ret;
|
||||
}
|
||||
else if(code[ip] == OP_STR_TO_NONE)
|
||||
ip++;
|
||||
else
|
||||
STR.setStringValue((const char*)ret);
|
||||
|
||||
// This will clear everything including returnValue
|
||||
CSTK.popFrame();
|
||||
STR.clearFunctionOffset();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1654,6 +1796,7 @@ breakContinue:
|
|||
callArgc, nsEntry->mMinArgs, nsEntry->mMaxArgs);
|
||||
Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-4), nsEntry->mUsage);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1663,16 +1806,18 @@ breakContinue:
|
|||
{
|
||||
const char *ret = nsEntry->cb.mStringCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
if(ret != STR.getStringValue())
|
||||
STR.setStringValue(ret);
|
||||
else
|
||||
STR.setLen(dStrlen(ret));
|
||||
//else
|
||||
// STR.setLen(dStrlen(ret));
|
||||
break;
|
||||
}
|
||||
case Namespace::Entry::IntCallbackType:
|
||||
{
|
||||
S32 result = nsEntry->cb.mIntCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
if(code[ip] == OP_STR_TO_UINT)
|
||||
{
|
||||
ip++;
|
||||
|
|
@ -1695,6 +1840,7 @@ breakContinue:
|
|||
{
|
||||
F64 result = nsEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
if(code[ip] == OP_STR_TO_UINT)
|
||||
{
|
||||
ip++;
|
||||
|
|
@ -1719,12 +1865,14 @@ breakContinue:
|
|||
Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-4), fnName, functionName);
|
||||
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
STR.setStringValue("");
|
||||
break;
|
||||
case Namespace::Entry::BoolCallbackType:
|
||||
{
|
||||
bool result = nsEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
if(code[ip] == OP_STR_TO_UINT)
|
||||
{
|
||||
ip++;
|
||||
|
|
@ -1778,11 +1926,24 @@ breakContinue:
|
|||
intStack[++_UINT] = STR.compare();
|
||||
break;
|
||||
case OP_PUSH:
|
||||
STR.push();
|
||||
STR.push();
|
||||
//Con::printf("Pushing str: %s",STR.getPreviousStringValue());
|
||||
CSTK.pushString(STR.getPreviousStringValue());
|
||||
break;
|
||||
case OP_PUSH_UINT:
|
||||
//Con::printf("Pushing int: %i",(S32)intStack[_UINT]);
|
||||
CSTK.pushUINT(intStack[_UINT]);
|
||||
_UINT--;
|
||||
break;
|
||||
case OP_PUSH_FLT:
|
||||
//Con::printf("Pushing float: %f",(F32)intStack[_UINT]);
|
||||
CSTK.pushFLT(floatStack[_FLT]);
|
||||
_FLT--;
|
||||
break;
|
||||
|
||||
case OP_PUSH_FRAME:
|
||||
STR.pushFrame();
|
||||
CSTK.pushFrame();
|
||||
break;
|
||||
|
||||
case OP_ASSERT:
|
||||
|
|
@ -1961,8 +2122,9 @@ execFinished:
|
|||
if ( telDebuggerOn && setFrame < 0 )
|
||||
TelDebugger->popStackFrame();
|
||||
|
||||
if ( popFrame )
|
||||
if ( popFrame ) {
|
||||
gEvalState.popFrame();
|
||||
}
|
||||
|
||||
if(argv)
|
||||
{
|
||||
|
|
@ -2012,7 +2174,8 @@ execFinished:
|
|||
AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
|
||||
AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
|
||||
#endif
|
||||
return STR.getStringValue();
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue