📄 compiledeval.cc
字号:
gEvalState.setCurVarNameCreate(var);
gEvalState.setStringVariable(argv[i+1]);
}
ip = ip + fnArgc + 6;
curFloatTable = functionFloats;
curStringTable = functionStrings;
}
else
{
curFloatTable = globalFloats;
curStringTable = globalStrings;
// Do we want this code to execute using a new stack frame?
if (setFrame < 0)
{
gEvalState.pushFrame(NULL, NULL);
popFrame = true;
}
else if (!gEvalState.stack.empty())
{
// We want to copy a reference to an existing stack frame
// on to the top of the stack. Any change that occurs to
// the locals during this new frame will also occur in the
// original frame.
S32 stackIndex = gEvalState.stack.size() - setFrame - 1;
gEvalState.pushFrameRef( stackIndex );
popFrame = true;
}
}
if (TelDebugger && setFrame < 0)
TelDebugger->pushStackFrame();
StringTableEntry var, objParent;
U32 failJump;
StringTableEntry fnName;
StringTableEntry fnNamespace, fnPackage;
SimObject *currentNewObject = 0;
StringTableEntry curField;
SimObject *curObject;
SimObject *saveObject=NULL;
Namespace::Entry *nsEntry;
Namespace *ns;
U32 callArgc;
const char **callArgv;
static char curFieldArray[256];
CodeBlock *saveCodeBlock = smCurrentCodeBlock;
smCurrentCodeBlock = this;
if(this->name)
{
Con::gCurrentFile = this->name;
Con::gCurrentRoot = mRoot;
}
const char * val;
for(;;)
{
U32 instruction = code[ip++];
breakContinue:
switch(instruction)
{
case OP_FUNC_DECL:
if(!noCalls)
{
fnName = U32toSTE(code[ip]);
fnNamespace = U32toSTE(code[ip+1]);
fnPackage = U32toSTE(code[ip+2]);
bool hasBody = bool(code[ip+3]);
Namespace::unlinkPackages();
ns = Namespace::find(fnNamespace, fnPackage);
ns->addFunction(fnName, this, hasBody ? ip : 0);// if no body, set the IP to 0
Namespace::relinkPackages();
//Con::printf("Adding function %s::%s (%d)", fnNamespace, fnName, ip);
}
ip = code[ip + 4];
break;
case OP_CREATE_OBJECT:
{
// If we don't allow calls, we certainly don't allow creating objects!
if(noCalls)
{
ip = failJump;
break;
}
// Read some useful info.
objParent = U32toSTE(code[ip ]);
bool isDataBlock = code[ip + 1];
failJump = code[ip + 2];
// Get the constructor information off the stack.
STR.getArgcArgv(NULL, &callArgc, &callArgv);
// Con::printf("Creating object...");
// objectName = argv[1]...
currentNewObject = NULL;
// Are we creating a datablock? If so, deal with case where we override
// an old one.
if(isDataBlock)
{
// Con::printf(" - is a datablock");
// Find the old one if any.
SimObject *db = Sim::getDataBlockGroup()->findObject(callArgv[2]);
// Make sure we're not changing types on ourselves...
if(db && dStricmp(db->getClassName(), callArgv[1]))
{
Con::errorf(ConsoleLogEntry::General, "Cannot re-declare data block %s with a different class.", callArgv[2]);
ip = failJump;
break;
}
// If there was one, set the currentNewObject and move on.
if(db)
currentNewObject = db;
}
if(!currentNewObject)
{
// Well, looks like we have to create a new object.
ConsoleObject *object = ConsoleObject::create(callArgv[1]);
// Deal with failure!
if(!object)
{
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", getFileLine(ip-1), callArgv[1]);
ip = failJump;
break;
}
// Do special datablock init if appropros
if(isDataBlock)
{
SimDataBlock *dataBlock = dynamic_cast<SimDataBlock *>(object);
if(dataBlock)
{
dataBlock->assignId();
}
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-1), callArgv[1]);
// Clean up...
delete object;
ip = failJump;
break;
}
}
// Finally, set currentNewObject to point to the new one.
currentNewObject = dynamic_cast<SimObject *>(object);
// Deal with the case of a non-SimObject.
if(!currentNewObject)
{
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", getFileLine(ip-1), callArgv[1]);
delete object;
ip = failJump;
break;
}
// Does it have a parent object? (ie, the copy constructor : syntax, not inheriance)
if(*objParent)
{
// Find it!
SimObject *parent;
if(Sim::findObject(objParent, parent))
{
// Con::printf(" - Parent object found: %s", parent->getClassName());
// and suck the juices from it!
currentNewObject->assignFieldsFrom(parent);
}
else
Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", getFileLine(ip-1), objParent, callArgv[1]);
// Mm! Juices!
}
// If a name was passed, assign it.
if(callArgv[2][0])
currentNewObject->assignName(callArgv[2]);
// Do the constructor parameters.
if(!currentNewObject->processArguments(callArgc-3, callArgv+3))
{
delete currentNewObject;
currentNewObject = NULL;
ip = failJump;
break;
}
// If it's not a datablock, allow people to modify bits of it.
if(!isDataBlock)
{
currentNewObject->setModStaticFields(true);
currentNewObject->setModDynamicFields(true);
}
}
// Advance the IP past the create info...
ip += 3;
break;
}
case OP_ADD_OBJECT:
{
// Do we place this object at the root?
bool placeAtRoot = code[ip++];
// Con::printf("Adding object %s", currentNewObject->getName());
// Make sure it wasn't already added, then add it.
if(currentNewObject->isProperlyAdded() == false && !currentNewObject->registerObject())
{
// This error is usually caused by failing to call Parent::initPersistFields in the class' initPersistFields().
Con::warnf(ConsoleLogEntry::General, "%s: Register object failed for object %s of class %s.", getFileLine(ip-2), currentNewObject->getName(), currentNewObject->getClassName());
delete currentNewObject;
ip = failJump;
break;
}
// Are we dealing with a datablock?
SimDataBlock *dataBlock = dynamic_cast<SimDataBlock *>(currentNewObject);
static char errorBuffer[256];
// If so, preload it.
if(dataBlock && !dataBlock->preload(true, errorBuffer))
{
Con::errorf(ConsoleLogEntry::General, "%s: preload failed for %s: %s.", getFileLine(ip-2),
currentNewObject->getName(), errorBuffer);
dataBlock->deleteObject();
ip = failJump;
break;
}
// What group will we be added to, if any?
U32 groupAddId = intStack[g_uIntIP];
SimGroup *grp = NULL;
SimSet *set = NULL;
if(!placeAtRoot || !currentNewObject->getGroup())
{
if(placeAtRoot)
{
// Deal with the instantGroup if we're being put at the root.
const char *addGroupName = Con::getVariable("instantGroup");
if(!Sim::findObject(addGroupName, grp))
Sim::findObject(RootGroupId, grp);
}
else
{
// Otherwise just add to the requested group or set.
if(!Sim::findObject(groupAddId, grp))
Sim::findObject(groupAddId, set);
}
// If we didn't get a group, then make sure we have a pointer to
// the rootgroup.
if(!grp)
Sim::findObject(RootGroupId, grp);
// add to the parent group
grp->addObject(currentNewObject);
// add to any set we might be in
if(set)
set->addObject(currentNewObject);
}
// store the new object's ID on the stack (overwriting the group/set
// id, if one was given, otherwise getting pushed)
if(placeAtRoot)
intStack[g_uIntIP] = currentNewObject->getId();
else
intStack[++g_uIntIP] = currentNewObject->getId();
break;
}
case OP_END_OBJECT:
{
// If we're not to be placed at the root, make sure we clean up
// our group reference.
bool placeAtRoot = code[ip++];
if(!placeAtRoot)
g_uIntIP--;
break;
}
case OP_JMPIFFNOT:
if(floatStack[g_uFloatIP--])
{
ip++;
break;
}
ip = code[ip];
break;
case OP_JMPIFNOT:
if(intStack[g_uIntIP--])
{
ip++;
break;
}
ip = code[ip];
break;
case OP_JMPIFF:
if(!floatStack[g_uFloatIP--])
{
ip++;
break;
}
ip = code[ip];
break;
case OP_JMPIF:
if(!intStack[g_uIntIP--])
{
ip ++;
break;
}
ip = code[ip];
break;
case OP_JMPIFNOT_NP:
if(intStack[g_uIntIP])
{
g_uIntIP--;
ip++;
break;
}
ip = code[ip];
break;
case OP_JMPIF_NP:
if(!intStack[g_uIntIP])
{
g_uIntIP--;
ip++;
break;
}
ip = code[ip];
break;
case OP_JMP:
ip = code[ip];
break;
case OP_RETURN:
goto execFinished;
case OP_CMPEQ:
intStack[g_uIntIP+1] = bool(floatStack[g_uFloatIP] == floatStack[g_uFloatIP-1]);
g_uIntIP++;
g_uFloatIP -= 2;
break;
case OP_CMPGR:
intStack[g_uIntIP+1] = bool(floatStack[g_uFloatIP] > floatStack[g_uFloatIP-1]);
g_uIntIP++;
g_uFloatIP -= 2;
break;
case OP_CMPGE:
intStack[g_uIntIP+1] = bool(floatStack[g_uFloatIP] >= floatStack[g_uFloatIP-1]);
g_uIntIP++;
g_uFloatIP -= 2;
break;
case OP_CMPLT:
intStack[g_uIntIP+1] = bool(floatStack[g_uFloatIP] < floatStack[g_uFloatIP-1]);
g_uIntIP++;
g_uFloatIP -= 2;
break;
case OP_CMPLE:
intStack[g_uIntIP+1] = bool(floatStack[g_uFloatIP] <= floatStack[g_uFloatIP-1]);
g_uIntIP++;
g_uFloatIP -= 2;
break;
case OP_CMPNE:
intStack[g_uIntIP+1] = bool(floatStack[g_uFloatIP] != floatStack[g_uFloatIP-1]);
g_uIntIP++;
g_uFloatIP -= 2;
break;
case OP_XOR:
intStack[g_uIntIP-1] = intStack[g_uIntIP] ^ intStack[g_uIntIP-1];
g_uIntIP--;
break;
case OP_MOD:
intStack[g_uIntIP-1] = intStack[g_uIntIP] % intStack[g_uIntIP-1];
g_uIntIP--;
break;
case OP_BITAND:
intStack[g_uIntIP-1] = intStack[g_uIntIP] & intStack[g_uIntIP-1];
g_uIntIP--;
break;
case OP_BITOR:
intStack[g_uIntIP-1] = intStack[g_uIntIP] | intStack[g_uIntIP-1];
g_uIntIP--;
break;
case OP_NOT:
intStack[g_uIntIP] = !intStack[g_uIntIP];
break;
case OP_NOTF:
intStack[g_uIntIP+1] = !floatStack[g_uFloatIP];
g_uFloatIP--;
g_uIntIP++;
break;
case OP_ONESCOMPLEMENT:
intStack[g_uIntIP] = ~intStack[g_uIntIP];
break;
case OP_SHR:
intStack[g_uIntIP-1] = intStack[g_uIntIP] >> intStack[g_uIntIP-1];
g_uIntIP--;
break;
case OP_SHL:
intStack[g_uIntIP-1] = intStack[g_uIntIP] << intStack[g_uIntIP-1];
g_uIntIP--;
break;
case OP_AND:
intStack[g_uIntIP-1] = intStack[g_uIntIP] && intStack[g_uIntIP-1];
g_uIntIP--;
break;
case OP_OR:
intStack[g_uIntIP-1] = intStack[g_uIntIP] || intStack[g_uIntIP-1];
g_uIntIP--;
break;
case OP_ADD:
floatStack[g_uFloatIP-1] = floatStack[g_uFloatIP] + floatStack[g_uFloatIP-1];
g_uFloatIP--;
break;
case OP_SUB:
floatStack[g_uFloatIP-1] = floatStack[g_uFloatIP] - floatStack[g_uFloatIP-1];
g_uFloatIP--;
break;
case OP_MUL:
floatStack[g_uFloatIP-1] = floatStack[g_uFloatIP] * floatStack[g_uFloatIP-1];
g_uFloatIP--;
break;
case OP_DIV:
floatStack[g_uFloatIP-1] = floatStack[g_uFloatIP] / floatStack[g_uFloatIP-1];
g_uFloatIP--;
break;
case OP_NEG:
floatStack[g_uFloatIP] = -floatStack[g_uFloatIP];
break;
case OP_SETCURVAR:
var = U32toSTE(code[ip]);
ip++;
gEvalState.setCurVarName(var);
break;
case OP_SETCURVAR_CREATE:
var = U32toSTE(code[ip]);
ip++;
gEvalState.setCurVarNameCreate(var);
break;
case OP_SETCURVAR_ARRAY:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -