📄 compiledeval.cc
字号:
var = STR.getSTValue();
gEvalState.setCurVarName(var);
break;
case OP_SETCURVAR_ARRAY_CREATE:
var = STR.getSTValue();
gEvalState.setCurVarNameCreate(var);
break;
case OP_LOADVAR_UINT:
intStack[g_uIntIP+1] = gEvalState.getIntVariable();
g_uIntIP++;
break;
case OP_LOADVAR_FLT:
floatStack[g_uFloatIP+1] = gEvalState.getFloatVariable();
g_uFloatIP++;
break;
case OP_LOADVAR_STR:
val = gEvalState.getStringVariable();
STR.setStringValue(val);
break;
case OP_SAVEVAR_UINT:
gEvalState.setIntVariable(intStack[g_uIntIP]);
break;
case OP_SAVEVAR_FLT:
gEvalState.setFloatVariable(floatStack[g_uFloatIP]);
break;
case OP_SAVEVAR_STR:
gEvalState.setStringVariable(STR.getStringValue());
break;
case OP_SETCUROBJECT:
curObject = Sim::findObject(STR.getStringValue());
break;
case OP_SETCUROBJECT_NEW:
curObject = currentNewObject;
break;
case OP_SETCURFIELD:
curField = U32toSTE(code[ip]);
curFieldArray[0] = 0;
ip++;
break;
case OP_SETCURFIELD_ARRAY:
dStrcpy(curFieldArray, STR.getStringValue());
break;
case OP_LOADFIELD_UINT:
if(curObject)
intStack[g_uIntIP+1] = U32(dAtoi(curObject->getDataField(curField, curFieldArray)));
else
intStack[g_uIntIP+1] = 0;
g_uIntIP++;
break;
case OP_LOADFIELD_FLT:
if(curObject)
floatStack[g_uFloatIP+1] = dAtof(curObject->getDataField(curField, curFieldArray));
else
floatStack[g_uFloatIP+1] = 0;
g_uFloatIP++;
break;
case OP_LOADFIELD_STR:
if(curObject)
val = curObject->getDataField(curField, curFieldArray);
else
val = "";
STR.setStringValue(val);
break;
case OP_SAVEFIELD_UINT:
STR.setIntValue(intStack[g_uIntIP]);
if(curObject)
curObject->setDataField(curField, curFieldArray, STR.getStringValue());
break;
case OP_SAVEFIELD_FLT:
STR.setFloatValue(floatStack[g_uFloatIP]);
if(curObject)
curObject->setDataField(curField, curFieldArray, STR.getStringValue());
break;
case OP_SAVEFIELD_STR:
if(curObject)
curObject->setDataField(curField, curFieldArray, STR.getStringValue());
break;
case OP_STR_TO_UINT:
intStack[g_uIntIP+1] = STR.getIntValue();
g_uIntIP++;
break;
case OP_STR_TO_FLT:
floatStack[g_uFloatIP+1] = STR.getFloatValue();
g_uFloatIP++;
break;
case OP_STR_TO_NONE:
// This exists simply to deal with certain typecast situations.
break;
case OP_FLT_TO_UINT:
intStack[g_uIntIP+1] = (unsigned int)floatStack[g_uFloatIP];
g_uFloatIP--;
g_uIntIP++;
break;
case OP_FLT_TO_STR:
STR.setFloatValue(floatStack[g_uFloatIP]);
g_uFloatIP--;
break;
case OP_FLT_TO_NONE:
g_uFloatIP--;
break;
case OP_UINT_TO_FLT:
floatStack[g_uFloatIP+1] = intStack[g_uIntIP];
g_uIntIP--;
g_uFloatIP++;
break;
case OP_UINT_TO_STR:
STR.setIntValue(intStack[g_uIntIP]);
g_uIntIP--;
break;
case OP_UINT_TO_NONE:
g_uIntIP--;
break;
case OP_LOADIMMED_UINT:
intStack[g_uIntIP+1] = code[ip++];
g_uIntIP++;
break;
case OP_LOADIMMED_FLT:
floatStack[g_uFloatIP+1] = curFloatTable[code[ip]];
ip++;
g_uFloatIP++;
break;
case OP_TAG_TO_STR:
code[ip-1] = OP_LOADIMMED_STR;
// it's possible the string has already been converted
if(U8(curStringTable[code[ip]]) != StringTagPrefixByte)
{
U32 id = GameAddTaggedString(curStringTable + code[ip]);
dSprintf(curStringTable + code[ip] + 1, 7, "%d", id);
*(curStringTable + code[ip]) = StringTagPrefixByte;
}
case OP_LOADIMMED_STR:
STR.setStringValue(curStringTable + code[ip++]);
break;
#ifdef TGE_RPG_SCRIPT
case OP_LOAD_VSTRING:
if(processVString(curStringTable + code[ip++],val))
STR.setStringValue(val);
break;
#endif
case OP_LOADIMMED_IDENT:
STR.setStringValue(U32toSTE(code[ip++]));
break;
case OP_CALLFUNC_RESOLVE:
// This deals with a function that is potentially living in a namespace.
fnNamespace = U32toSTE(code[ip+1]);
fnName = U32toSTE(code[ip]);
// Try to look it up.
ns = Namespace::find(fnNamespace);
nsEntry = ns->lookup(fnName);
if(!nsEntry)
{
ip+= 3;
Con::warnf(ConsoleLogEntry::General,
"%s: Unable to find function %s%s%s",
getFileLine(ip-4), fnNamespace ? fnNamespace : "",
fnNamespace ? "::" : "", fnName);
STR.getArgcArgv(fnName, &callArgc, &callArgv);
break;
}
// Now, rewrite our code a bit (ie, avoid future lookups) and fall
// through to OP_CALLFUNC
code[ip+1] = *((U32 *) &nsEntry);
code[ip-1] = OP_CALLFUNC;
case OP_CALLFUNC:
{
fnName = U32toSTE(code[ip]);
//if this is called from inside a function, append the ip and codeptr
if (!gEvalState.stack.empty())
{
gEvalState.stack.last()->code = this;
gEvalState.stack.last()->ip = ip - 1;
}
U32 callType = code[ip+2];
ip += 3;
STR.getArgcArgv(fnName, &callArgc, &callArgv);
if(callType == FuncCallExprNode::FunctionCall) {
nsEntry = *((Namespace::Entry **) &code[ip-2]);
ns = NULL;
}
else if(callType == FuncCallExprNode::MethodCall)
{
saveObject = gEvalState.thisObject;
gEvalState.thisObject = Sim::findObject(callArgv[1]);
if(!gEvalState.thisObject)
{
gEvalState.thisObject = 0;
Con::warnf(ConsoleLogEntry::General,"%s: Unable to find object: '%s' attempting to call function '%s'", getFileLine(ip-4), callArgv[1], fnName);
break;
}
ns = gEvalState.thisObject->getNamespace();
if(ns)
nsEntry = ns->lookup(fnName);
else
nsEntry = NULL;
}
else // it's a ParentCall
{
if(thisNamespace)
{
ns = thisNamespace->mParent;
if(ns)
nsEntry = ns->lookup(fnName);
else
nsEntry = NULL;
}
else
{
ns = NULL;
nsEntry = NULL;
}
}
if(!nsEntry || noCalls)
{
if(!noCalls)
{
Con::warnf(ConsoleLogEntry::General,"%s: Unknown command %s.", getFileLine(ip-4), fnName);
if(callType == FuncCallExprNode::MethodCall)
{
Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s",
gEvalState.thisObject->getName() ? gEvalState.thisObject->getName() : "",
gEvalState.thisObject->getId(), getNamespaceList(ns) );
}
}
STR.setStringValue("");
break;
}
if(nsEntry->mType == Namespace::Entry::ScriptFunctionType)
{
if(nsEntry->mFunctionOffset)
nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage);
else // no body
STR.setStringValue("");
}
else
{
if((nsEntry->mMinArgs && S32(callArgc) < nsEntry->mMinArgs) || (nsEntry->mMaxArgs && S32(callArgc) > nsEntry->mMaxArgs))
{
const char* nsName = ns? ns->mName: "";
Con::warnf(ConsoleLogEntry::Script, "%s: %s::%s - wrong number of arguments.", getFileLine(ip-4), nsName, fnName);
Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-4), nsEntry->mUsage);
}
else
{
switch(nsEntry->mType)
{
case Namespace::Entry::StringCallbackType:
{
const char *ret = nsEntry->cb.mStringCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
if(ret != STR.getStringValue())
STR.setStringValue(ret);
else
STR.setLen(dStrlen(ret));
break;
}
case Namespace::Entry::IntCallbackType:
{
S32 result = nsEntry->cb.mIntCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
if(code[ip] == OP_STR_TO_UINT)
{
ip++;
intStack[++g_uIntIP] = result;
break;
}
else if(code[ip] == OP_STR_TO_FLT)
{
ip++;
floatStack[++g_uFloatIP] = result;
break;
}
else if(code[ip] == OP_STR_TO_NONE)
ip++;
else
STR.setIntValue(result);
break;
}
case Namespace::Entry::FloatCallbackType:
{
F64 result = nsEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
if(code[ip] == OP_STR_TO_UINT)
{
ip++;
intStack[++g_uIntIP] = (unsigned int)result;
break;
}
else if(code[ip] == OP_STR_TO_FLT)
{
ip++;
floatStack[++g_uFloatIP] = result;
break;
}
else if(code[ip] == OP_STR_TO_NONE)
ip++;
else
STR.setFloatValue(result);
break;
}
case Namespace::Entry::VoidCallbackType:
nsEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
if(code[ip] != OP_STR_TO_NONE)
Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-4), fnName, functionName);
STR.setStringValue("");
break;
case Namespace::Entry::BoolCallbackType:
{
bool result = nsEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
if(code[ip] == OP_STR_TO_UINT)
{
ip++;
intStack[++g_uIntIP] = result;
break;
}
else if(code[ip] == OP_STR_TO_FLT)
{
ip++;
floatStack[++g_uFloatIP] = result;
break;
}
else if(code[ip] == OP_STR_TO_NONE)
ip++;
else
STR.setIntValue(result);
break;
}
}
}
}
if(callType == FuncCallExprNode::MethodCall)
gEvalState.thisObject = saveObject;
break;
}
case OP_ADVANCE_STR:
STR.advance();
break;
case OP_ADVANCE_STR_APPENDCHAR:
STR.advanceChar(code[ip++]);
break;
case OP_ADVANCE_STR_COMMA:
STR.advanceChar('_');
break;
case OP_ADVANCE_STR_NUL:
STR.advanceChar(0);
break;
case OP_REWIND_STR:
STR.rewind();
break;
case OP_TERMINATE_REWIND_STR:
STR.rewindTerminate();
break;
case OP_COMPARE_STR:
intStack[++g_uIntIP] = STR.compare();
break;
case OP_PUSH:
STR.push();
break;
case OP_PUSH_FRAME:
STR.pushFrame();
break;
case OP_BREAK:
{
//append the ip and codeptr before managing the breakpoint!
AssertFatal( !gEvalState.stack.empty(), "Empty eval stack on break!");
gEvalState.stack.last()->code = this;
gEvalState.stack.last()->ip = ip - 1;
U32 breakLine;
findBreakLine(ip-1, breakLine, instruction);
if(!breakLine)
goto breakContinue;
TelDebugger->executionStopped(this, breakLine);
goto breakContinue;
}
case OP_INVALID:
default:
// error!
goto execFinished;
}
}
execFinished:
if (TelDebugger && setFrame < 0)
TelDebugger->popStackFrame();
if ( popFrame )
gEvalState.popFrame();
if(argv)
{
if(gEvalState.traceOn)
{
traceBuffer[0] = 0;
dStrcat(traceBuffer, "Leaving ");
if(packageName)
{
dStrcat(traceBuffer, "[");
dStrcat(traceBuffer, packageName);
dStrcat(traceBuffer, "]");
}
if(thisNamespace && thisNamespace->mName)
{
dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer),
"%s::%s() - return %s", thisNamespace->mName, thisFunctionName, STR.getStringValue());
}
else
{
dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer),
"%s() - return %s", thisFunctionName, STR.getStringValue());
}
Con::printf("%s", traceBuffer);
}
}
else
{
delete[] const_cast<char*>(globalStrings);
delete[] globalFloats;
globalStrings = NULL;
globalFloats = NULL;
}
smCurrentCodeBlock = saveCodeBlock;
if(saveCodeBlock && saveCodeBlock->name)
{
Con::gCurrentFile = saveCodeBlock->name;
Con::gCurrentRoot = saveCodeBlock->mRoot;
}
decRefCount();
return STR.getStringValue();
}
//------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -