Refactor TS compiler to not use the precompile step & also 64bit support

- Reduces headaches
- Expands STE entry size to allow for 64bit values
- Bonus: Adds in function lookup optimization from T2D
This commit is contained in:
James Urquhart 2014-09-07 17:38:35 +01:00
parent 1b06b0d92e
commit 1e44586606
8 changed files with 957 additions and 1009 deletions

View file

@ -422,8 +422,8 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
if(argv)
{
// assume this points into a function decl:
U32 fnArgc = code[ip + 5];
thisFunctionName = U32toSTE(code[ip]);
U32 fnArgc = code[ip + 2 + 6];
thisFunctionName = CodeToSTE(code, ip);
argc = getMin(argc-1, fnArgc); // argv[0] is func name
if(gEvalState.traceOn)
{
@ -458,11 +458,11 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
popFrame = true;
for(i = 0; i < argc; i++)
{
StringTableEntry var = U32toSTE(code[ip + i + 6]);
StringTableEntry var = CodeToSTE(code, ip + (2 + 6 + 1) + (i * 2));
gEvalState.setCurVarNameCreate(var);
gEvalState.setStringVariable(argv[i+1]);
}
ip = ip + fnArgc + 6;
ip = ip + (fnArgc * 2) + (2 + 6 + 1);
curFloatTable = functionFloats;
curStringTable = functionStrings;
curStringTableLen = functionStringsMaxLen;
@ -559,11 +559,11 @@ breakContinue:
case OP_FUNC_DECL:
if(!noCalls)
{
fnName = U32toSTE(code[ip]);
fnNamespace = U32toSTE(code[ip+1]);
fnPackage = U32toSTE(code[ip+2]);
bool hasBody = ( code[ ip + 3 ] & 0x01 ) != 0;
U32 lineNumber = code[ ip + 3 ] >> 1;
fnName = CodeToSTE(code, ip);
fnNamespace = CodeToSTE(code, ip+2);
fnPackage = CodeToSTE(code, ip+4);
bool hasBody = ( code[ ip + 6 ] & 0x01 ) != 0;
U32 lineNumber = code[ ip + 6 ] >> 1;
Namespace::unlinkPackages();
ns = Namespace::find(fnNamespace, fnPackage);
@ -586,18 +586,18 @@ breakContinue:
//Con::printf("Adding function %s::%s (%d)", fnNamespace, fnName, ip);
}
ip = code[ip + 4];
ip = code[ip + 7];
break;
case OP_CREATE_OBJECT:
{
// Read some useful info.
objParent = U32toSTE(code[ip ]);
bool isDataBlock = code[ip + 1];
bool isInternal = code[ip + 2];
bool isSingleton = code[ip + 3];
U32 lineNumber = code[ip + 4];
failJump = code[ip + 5];
objParent = CodeToSTE(code, ip);
bool isDataBlock = code[ip + 2];
bool isInternal = code[ip + 3];
bool isSingleton = code[ip + 4];
U32 lineNumber = code[ip + 5];
failJump = code[ip + 6];
// If we don't allow calls, we certainly don't allow creating objects!
// Moved this to after failJump is set. Engine was crashing when
@ -848,7 +848,7 @@ breakContinue:
}
// Advance the IP past the create info...
ip += 6;
ip += 7;
break;
}
@ -1170,8 +1170,8 @@ breakContinue:
break;
case OP_SETCURVAR:
var = U32toSTE(code[ip]);
ip++;
var = CodeToSTE(code, ip);
ip += 2;
// If a variable is set, then these must be NULL. It is necessary
// to set this here so that the vector parser can appropriately
@ -1190,8 +1190,8 @@ breakContinue:
break;
case OP_SETCURVAR_CREATE:
var = U32toSTE(code[ip]);
ip++;
var = CodeToSTE(code, ip);
ip += 2;
// See OP_SETCURVAR
prevField = NULL;
@ -1310,9 +1310,9 @@ breakContinue:
// Save the previous field for parsing vector fields.
prevField = curField;
dStrcpy( prevFieldArray, curFieldArray );
curField = U32toSTE(code[ip]);
curField = CodeToSTE(code, ip);
curFieldArray[0] = 0;
ip++;
ip += 2;
break;
case OP_SETCURFIELD_ARRAY:
@ -1504,28 +1504,38 @@ breakContinue:
break;
case OP_LOADIMMED_IDENT:
STR.setStringValue(U32toSTE(code[ip++]));
STR.setStringValue(CodeToSTE(code, ip));
ip += 2;
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]);
fnNamespace = CodeToSTE(code, ip+2);
fnName = CodeToSTE(code, ip);
// Try to look it up.
ns = Namespace::find(fnNamespace);
nsEntry = ns->lookup(fnName);
if(!nsEntry)
{
ip+= 3;
ip+= 5;
Con::warnf(ConsoleLogEntry::General,
"%s: Unable to find function %s%s%s",
getFileLine(ip-4), fnNamespace ? fnNamespace : "",
getFileLine(ip-7), fnNamespace ? fnNamespace : "",
fnNamespace ? "::" : "", fnName);
STR.popFrame();
break;
}
// Now fall through to OP_CALLFUNC...
// Now, rewrite our code a bit (ie, avoid future lookups) and fall
// through to OP_CALLFUNC
#ifdef TORQUE_64
*((U64*)(code+ip+2)) = ((U64)nsEntry);
#else
code[ip+2] = ((U32)nsEntry);
#endif
code[ip-1] = OP_CALLFUNC;
case OP_CALLFUNC:
{
@ -1535,7 +1545,7 @@ breakContinue:
// or just on the object.
S32 routingId = 0;
fnName = U32toSTE(code[ip]);
fnName = CodeToSTE(code, ip);
//if this is called from inside a function, append the ip and codeptr
if( gEvalState.getStackDepth() > 0 )
@ -1544,9 +1554,9 @@ breakContinue:
gEvalState.getCurrentFrame().ip = ip - 1;
}
U32 callType = code[ip+2];
U32 callType = code[ip+4];
ip += 3;
ip += 5;
STR.getArgcArgv(fnName, &callArgc, &callArgv);
const char *componentReturnValue = "";
@ -1555,9 +1565,12 @@ breakContinue:
{
if( !nsEntry )
{
// We must not have come from OP_CALLFUNC_RESOLVE, so figure out
// our own entry.
nsEntry = Namespace::global()->lookup( fnName );
#ifdef TORQUE_64
nsEntry = ((Namespace::Entry *) *((U64*)(code+ip-3)));
#else
nsEntry = ((Namespace::Entry *) *(code+ip-3));
#endif
ns = NULL;
}
ns = NULL;
}
@ -1618,7 +1631,7 @@ breakContinue:
{
if(!noCalls && !( routingId == MethodOnComponent ) )
{
Con::warnf(ConsoleLogEntry::General,"%s: Unknown command %s.", getFileLine(ip-4), fnName);
Con::warnf(ConsoleLogEntry::General,"%s: Unknown command %s.", getFileLine(ip-6), fnName);
if(callType == FuncCallExprNode::MethodCall)
{
Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s",
@ -1652,16 +1665,16 @@ breakContinue:
// which is useful behavior when debugging so I'm ifdefing this out for debug builds.
if(nsEntry->mToolOnly && ! Con::isCurrentScriptToolScript())
{
Con::errorf(ConsoleLogEntry::Script, "%s: %s::%s - attempting to call tools only function from outside of tools.", getFileLine(ip-4), nsName, fnName);
Con::errorf(ConsoleLogEntry::Script, "%s: %s::%s - attempting to call tools only function from outside of tools.", getFileLine(ip-6), nsName, fnName);
}
else
#endif
if((nsEntry->mMinArgs && S32(callArgc) < nsEntry->mMinArgs) || (nsEntry->mMaxArgs && S32(callArgc) > nsEntry->mMaxArgs))
{
Con::warnf(ConsoleLogEntry::Script, "%s: %s::%s - wrong number of arguments (got %i, expected min %i and max %i).",
getFileLine(ip-4), nsName, fnName,
getFileLine(ip-6), nsName, fnName,
callArgc, nsEntry->mMinArgs, nsEntry->mMaxArgs);
Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-4), nsEntry->mUsage);
Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-6), nsEntry->mUsage);
STR.popFrame();
}
else
@ -1725,7 +1738,7 @@ breakContinue:
case Namespace::Entry::VoidCallbackType:
nsEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
if( code[ ip ] != OP_STR_TO_NONE && Con::getBoolVariable( "$Con::warnVoidAssignment", true ) )
Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-4), fnName, functionName);
Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-6), fnName, functionName);
STR.popFrame();
STR.setStringValue("");
@ -1844,8 +1857,8 @@ breakContinue:
case OP_ITER_BEGIN:
{
StringTableEntry varName = U32toSTE( code[ ip ] );
U32 failIp = code[ ip + 1 ];
StringTableEntry varName = CodeToSTE(code, ip);
U32 failIp = code[ ip + 2 ];
IterStackRecord& iter = iterStack[ _ITER ];
@ -1880,7 +1893,7 @@ breakContinue:
STR.push();
ip += 2;
ip += 3;
break;
}