Script: Put function name instead of function in the bytecode

The function name is used to look up the function at run time for some time
now.

committer: Günther Brammer <gbrammer@gmx.de>
Günther Brammer 2009-05-09 15:17:24 +02:00
parent 675da642c3
commit f370a2198a
3 changed files with 121 additions and 101 deletions

View File

@ -224,7 +224,13 @@ extern C4ScriptOpDef C4ScriptOpMap[];
struct C4AulBCC
{
C4AulBCCType bccType; // chunk type
intptr_t bccX; // extra info (long for use with amd64)
union
{
int32_t i;
C4String * s;
C4AulFunc * f;
intptr_t X;
} Par; // extra info (long for use with amd64)
const char *SPos;
};

View File

@ -325,19 +325,19 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
switch(pCPos->bccType)
{
case AB_INT:
PushValue(C4VInt(pCPos->bccX));
PushValue(C4VInt(pCPos->Par.i));
break;
case AB_BOOL:
PushValue(C4VBool(!! pCPos->bccX));
PushValue(C4VBool(!! pCPos->Par.i));
break;
case AB_STRING:
PushString(reinterpret_cast<C4String *>(pCPos->bccX));
PushString(pCPos->Par.s);
break;
case AB_C4ID:
PushValue(C4VID(pCPos->bccX));
PushValue(C4VID(pCPos->Par.i));
break;
case AB_EOFN:
@ -347,17 +347,17 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
throw new C4AulExecError(pCurCtx->Obj, "syntax error: see previous parser error for details.");
case AB_PARN_R:
PushValueRef(pCurCtx->Pars[pCPos->bccX]);
PushValueRef(pCurCtx->Pars[pCPos->Par.i]);
break;
case AB_PARN_V:
PushValue(pCurCtx->Pars[pCPos->bccX]);
PushValue(pCurCtx->Pars[pCPos->Par.i]);
break;
case AB_VARN_R:
PushValueRef(pCurCtx->Vars[pCPos->bccX]);
PushValueRef(pCurCtx->Vars[pCPos->Par.i]);
break;
case AB_VARN_V:
PushValue(pCurCtx->Vars[pCPos->bccX]);
PushValue(pCurCtx->Vars[pCPos->Par.i]);
break;
case AB_LOCALN_R: case AB_LOCALN_V:
@ -366,54 +366,54 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
if(pCurCtx->Func->Owner->Def != pCurCtx->Def)
throw new C4AulExecError(pCurCtx->Obj, "can't access local variables after ChangeDef!");
if (pCPos->bccType == AB_LOCALN_R)
PushValueRef(*pCurCtx->Obj->LocalNamed.GetItem(pCPos->bccX));
PushValueRef(*pCurCtx->Obj->LocalNamed.GetItem(pCPos->Par.i));
else
PushValue(*pCurCtx->Obj->LocalNamed.GetItem(pCPos->bccX));
PushValue(*pCurCtx->Obj->LocalNamed.GetItem(pCPos->Par.i));
break;
case AB_GLOBALN_R:
PushValueRef(*Game.ScriptEngine.GlobalNamed.GetItem(pCPos->bccX));
PushValueRef(*Game.ScriptEngine.GlobalNamed.GetItem(pCPos->Par.i));
break;
case AB_GLOBALN_V:
PushValue(*Game.ScriptEngine.GlobalNamed.GetItem(pCPos->bccX));
PushValue(*Game.ScriptEngine.GlobalNamed.GetItem(pCPos->Par.i));
break;
// prefix
case AB_Inc1: // ++
CheckOpPar(pCPos->bccX);
CheckOpPar(pCPos->Par.i);
if(pCurVal->GetRefVal().ConvertTo(C4V_Int))
++(*pCurVal);
else
pCurVal->Set0();
break;
case AB_Dec1: // --
CheckOpPar(pCPos->bccX);
CheckOpPar(pCPos->Par.i);
if(pCurVal->GetRefVal().ConvertTo(C4V_Int))
--(*pCurVal);
else
pCurVal->Set0();
break;
case AB_BitNot: // ~
CheckOpPar(pCPos->bccX);
CheckOpPar(pCPos->Par.i);
pCurVal->SetInt(~pCurVal->_getInt());
break;
case AB_Not: // !
CheckOpPar(pCPos->bccX);
CheckOpPar(pCPos->Par.i);
pCurVal->SetBool(!pCurVal->_getRaw());
break;
case AB_Neg: // -
CheckOpPar(pCPos->bccX);
CheckOpPar(pCPos->Par.i);
pCurVal->SetInt(-pCurVal->_getInt());
break;
// postfix (whithout second statement)
case AB_Inc1_Postfix: // ++
CheckOpPar(pCPos->bccX);
CheckOpPar(pCPos->Par.i);
if(pCurVal->GetRefVal().ConvertTo(C4V_Int))
pCurVal->Set((*pCurVal)++);
else
pCurVal->Set0();
break;
case AB_Dec1_Postfix: // --
CheckOpPar(pCPos->bccX);
CheckOpPar(pCPos->Par.i);
if(pCurVal->GetRefVal().ConvertTo(C4V_Int))
pCurVal->Set((*pCurVal)--);
else
@ -422,7 +422,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
// postfix
case AB_Pow: // **
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(Pow(pPar1->_getInt(), pPar2->_getInt()));
PopValue();
@ -430,7 +430,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Div: // /
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
if(pPar2->_getInt())
pPar1->SetInt(pPar1->_getInt() / pPar2->_getInt());
@ -441,7 +441,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Mul: // *
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(pPar1->_getInt() * pPar2->_getInt());
PopValue();
@ -449,7 +449,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Mod: // %
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
if(pPar2->_getInt())
pPar1->SetInt(pPar1->_getInt() % pPar2->_getInt());
@ -460,7 +460,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Sub: // -
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(pPar1->_getInt() - pPar2->_getInt());
PopValue();
@ -468,7 +468,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Sum: // +
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(pPar1->_getInt() + pPar2->_getInt());
PopValue();
@ -476,7 +476,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_LeftShift: // <<
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(pPar1->_getInt() << pPar2->_getInt());
PopValue();
@ -484,7 +484,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_RightShift: // >>
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(pPar1->_getInt() >> pPar2->_getInt());
PopValue();
@ -492,7 +492,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_LessThan: // <
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(pPar1->_getInt() < pPar2->_getInt());
PopValue();
@ -500,7 +500,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_LessThanEqual: // <=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(pPar1->_getInt() <= pPar2->_getInt());
PopValue();
@ -508,7 +508,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_GreaterThan: // >
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(pPar1->_getInt() > pPar2->_getInt());
PopValue();
@ -516,7 +516,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_GreaterThanEqual: // >=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(pPar1->_getInt() >= pPar2->_getInt());
PopValue();
@ -524,7 +524,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_EqualIdent: // old ==
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(pPar1->_getRaw() == pPar2->_getRaw());
PopValue();
@ -532,7 +532,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Equal: // new ==
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(*pPar1 == *pPar2);
PopValue();
@ -540,7 +540,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_NotEqualIdent: // old !=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(pPar1->_getRaw() != pPar2->_getRaw());
PopValue();
@ -548,7 +548,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_NotEqual: // new !=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(*pPar1 != *pPar2);
PopValue();
@ -556,7 +556,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_SEqual: // S=, eq
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(SEqual(pPar1->_getStr() ? pPar1->_getStr()->GetCStr() : "",
pPar2->_getStr() ? pPar2->_getStr()->GetCStr() : ""));
@ -565,7 +565,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_SNEqual: // ne
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(!SEqual(pPar1->_getStr() ? pPar1->_getStr()->GetCStr() : "",
pPar2->_getStr() ? pPar2->_getStr()->GetCStr() : ""));
@ -574,7 +574,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_BitAnd: // &
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(pPar1->_getInt() & pPar2->_getInt());
PopValue();
@ -582,7 +582,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_BitXOr: // ^
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(pPar1->_getInt() ^ pPar2->_getInt());
PopValue();
@ -590,7 +590,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_BitOr: // |
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetInt(pPar1->_getInt() | pPar2->_getInt());
PopValue();
@ -598,7 +598,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_And: // &&
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(pPar1->_getRaw() && pPar2->_getRaw());
PopValue();
@ -606,7 +606,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Or: // ||
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->SetBool(pPar1->_getRaw() || pPar2->_getRaw());
PopValue();
@ -614,7 +614,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_MulIt: // *=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->GetData().Int *= pPar2 ->_getInt();
PopValue();
@ -622,7 +622,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_DivIt: // /=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->GetData().Int = pPar2->_getInt() ? pPar1->GetData().Int / pPar2->_getInt() : 0;
PopValue();
@ -630,7 +630,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_ModIt: // %=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->GetData().Int = pPar2->_getInt() ? pPar1->GetData().Int % pPar2->_getInt() : 0;
PopValue();
@ -638,7 +638,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Inc: // +=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->GetData().Int += pPar2 ->_getInt();
PopValue();
@ -646,7 +646,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Dec: // -=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->GetData().Int -= pPar2 ->_getInt();
PopValue();
@ -654,7 +654,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_AndIt: // &=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->GetData().Int &= pPar2 ->_getInt();
PopValue();
@ -662,7 +662,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_OrIt: // |=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->GetData().Int |= pPar2 ->_getInt();
PopValue();
@ -670,7 +670,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_XOrIt: // ^=
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
pPar1->GetData().Int ^= pPar2 ->_getInt();
PopValue();
@ -678,7 +678,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_Set: // =
{
CheckOpPars(pCPos->bccX);
CheckOpPars(pCPos->Par.i);
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
*pPar1 = *pPar2;
PopValue();
@ -686,7 +686,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
/* case AB_UNOP:
{
int iOpID = pCPos->bccX;
int iOpID = pCPos->Par.i;
// Typecheck parameter
if(!pCurVal->ConvertTo(C4ScriptOpMap[iOpID].Type1))
@ -705,7 +705,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
case AB_BINOP:
{
int iOpID = pCPos->bccX;
int iOpID = pCPos->Par.i;
// Get parameters
C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
@ -735,16 +735,16 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
case AB_ARRAY:
{
// Create array
C4ValueArray *pArray = new C4ValueArray(pCPos->bccX);
C4ValueArray *pArray = new C4ValueArray(pCPos->Par.i);
// Pop values from stack
for(int i = 0; i < pCPos->bccX; i++)
pArray->GetItem(i) = pCurVal[i - pCPos->bccX + 1];
for(int i = 0; i < pCPos->Par.i; i++)
pArray->GetItem(i) = pCurVal[i - pCPos->Par.i + 1];
// Push array
if(pCPos->bccX > 0)
if(pCPos->Par.i > 0)
{
PopValues(pCPos->bccX - 1);
PopValues(pCPos->Par.i - 1);
pCurVal->SetArray(pArray);
}
else
@ -774,22 +774,22 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_STACK:
if(pCPos->bccX < 0)
PopValues(-pCPos->bccX);
if(pCPos->Par.i < 0)
PopValues(-pCPos->Par.i);
else
PushNullVals(pCPos->bccX);
PushNullVals(pCPos->Par.i);
break;
case AB_JUMP:
fJump = true;
pCPos += pCPos->bccX;
pCPos += pCPos->Par.i;
break;
case AB_JUMPAND:
if(!pCurVal[0])
{
fJump = true;
pCPos += pCPos->bccX;
pCPos += pCPos->Par.i;
}
else
{
@ -801,7 +801,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
if(!!pCurVal[0])
{
fJump = true;
pCPos += pCPos->bccX;
pCPos += pCPos->Par.i;
}
else
{
@ -813,7 +813,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
if(!pCurVal[0])
{
fJump = true;
pCPos += pCPos->bccX;
pCPos += pCPos->Par.i;
}
PopValue();
break;
@ -863,7 +863,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
case AB_FUNC:
{
// Get function call data
C4AulFunc *pFunc = reinterpret_cast<C4AulFunc *>(pCPos->bccX);
C4AulFunc *pFunc = pCPos->Par.f;
C4Value *pPars = pCurVal - pFunc->GetParCount() + 1;
// Save current position
pCurCtx->CPos = pCPos;
@ -920,7 +920,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
if(pCurVal->_getInt() >= pArray->GetSize())
break;
// Get next
pCurCtx->Vars[pCPos->bccX] = pArray->GetItem(iItem);
pCurCtx->Vars[pCPos->Par.i] = pArray->GetItem(iItem);
// Save position
pCurVal->SetInt(iItem + 1);
// Jump over next instruction
@ -930,7 +930,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
}
case AB_IVARN:
pCurCtx->Vars[pCPos->bccX] = pCurVal[0];
pCurCtx->Vars[pCPos->Par.i] = pCurVal[0];
PopValue();
break;
@ -971,13 +971,9 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
throw new C4AulExecError(pCurCtx->Obj,
FormatString("Object call: Invalid target type %s, expected object or id!", pTargetVal->GetTypeName()).getData());
// Resolve overloads
C4AulFunc *pFunc = reinterpret_cast<C4AulFunc *>(pCPos->bccX);
while(pFunc->OverloadedBy)
pFunc = pFunc->OverloadedBy;
// Search function for given context
pFunc = pDestDef->Script.GetFuncRecursive(pFunc->Name);
const char * szFuncName = pCPos->Par.s->GetCStr();
C4AulFunc * pFunc = pDestDef->Script.GetFuncRecursive(szFuncName);
if(!pFunc && pCPos->bccType == AB_CALLFS)
{
PopValuesUntil(pTargetVal);
@ -988,7 +984,6 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
// Function not found?
if(!pFunc)
{
const char *szFuncName = reinterpret_cast<C4AulFunc *>(pCPos->bccX)->Name;
if(pDestObj)
throw new C4AulExecError(pCurCtx->Obj,
FormatString("Object call: No function \"%s\" in object \"%s\"!", szFuncName, pTargetVal->GetDataString().getData()).getData());
@ -997,8 +992,9 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
FormatString("Definition call: No function \"%s\" in definition \"%s\"!", szFuncName, pDestDef->Name.getData()).getData());
}
// Save function back (optimization)
pCPos->bccX = reinterpret_cast<long>(pFunc);
// Resolve overloads
while(pFunc->OverloadedBy)
pFunc = pFunc->OverloadedBy;
// Save current position
pCurCtx->CPos = pCPos;

View File

@ -941,13 +941,26 @@ void C4AulScript::AddBCC(C4AulBCCType eType, intptr_t X, const char * SPos)
}
// store chunk
CPos->bccType = eType;
CPos->bccX = X;
CPos->Par.X = X;
CPos->SPos = SPos;
switch (eType)
{
case AB_STRING: case AB_CALL: case AB_CALLFS:
CPos->Par.s->IncRef();
}
CPos++; CodeSize++;
}
void C4AulScript::ClearCode()
{
for (int i = 0; i < CodeSize; ++i)
{
switch (Code[i].bccType)
{
case AB_STRING: case AB_CALL: case AB_CALLFS:
Code[i].Par.s->DecRef();
}
}
delete[] Code;
Code = 0;
CodeSize = CodeBufSize = 0;
@ -1117,11 +1130,11 @@ void C4AulParseState::AddBCC(C4AulBCCType eType, intptr_t X)
if(eType == AB_STACK &&
a->CPos > a->Code &&
(a->CPos-1)->bccType == AB_STACK
&& (X <= 0 || (a->CPos-1)->bccX >= 0))
&& (X <= 0 || (a->CPos-1)->Par.i >= 0))
{
(a->CPos-1)->bccX += X;
(a->CPos-1)->Par.i += X;
// Empty? Remove it.
if(!(a->CPos-1)->bccX)
if(!(a->CPos-1)->Par.i)
{
a->CPos--;
a->CodeSize--;
@ -1166,7 +1179,7 @@ void C4AulParseState::SetJumpHere(int iJumpOp)
// Set target
C4AulBCC *pBCC = a->GetCodeByPos(iJumpOp);
assert(pBCC->bccType == AB_JUMP || pBCC->bccType == AB_JUMPAND || pBCC->bccType == AB_JUMPOR || pBCC->bccType == AB_CONDN);
pBCC->bccX = a->GetCodePos() - iJumpOp;
pBCC->Par.i = a->GetCodePos() - iJumpOp;
// Set flag so the next generated code chunk won't get joined
fJump = true;
}
@ -1177,7 +1190,7 @@ void C4AulParseState::SetJump(int iJumpOp, int iWhere)
// Set target
C4AulBCC *pBCC = a->GetCodeByPos(iJumpOp);
assert(pBCC->bccType == AB_JUMP || pBCC->bccType == AB_JUMPAND || pBCC->bccType == AB_JUMPOR || pBCC->bccType == AB_CONDN);
pBCC->bccX = iWhere - iJumpOp;
pBCC->Par.i = iWhere - iJumpOp;
}
void C4AulParseState::AddJump(C4AulBCCType eType, int iWhere)
@ -2197,9 +2210,9 @@ int C4AulParseState::Parse_Params(int iMaxCnt, const char * sWarn, C4AulFunc * p
case AB_STRING: from = C4V_String; break;
case AB_ARRAY: from = C4V_Array; break;
case AB_BOOL: from = C4V_Bool; break;
case AB_UNOP: case AB_BINOP: from = C4ScriptOpMap[(a->CPos-1)->bccX].RetType; break;
case AB_UNOP: case AB_BINOP: from = C4ScriptOpMap[(a->CPos-1)->Par.i].RetType; break;
case AB_FUNC: case AB_CALL: case AB_CALLFS:
if((a->CPos-1)->bccX) from = reinterpret_cast<C4AulFunc *>((a->CPos-1)->bccX)->GetRetType(); break;
if((a->CPos-1)->Par.i) from = reinterpret_cast<C4AulFunc *>((a->CPos-1)->Par.i)->GetRetType(); break;
case AB_ARRAYA_R: case AB_PAR_R: case AB_VAR_R: case AB_PARN_R: case AB_VARN_R: case AB_LOCALN_R: case AB_GLOBALN_R:
from = C4V_pC4Value; break;
}
@ -2624,7 +2637,9 @@ void C4AulParseState::Parse_Expression(int iParentPrio)
{
case C4V_Int: AddBCC(AB_INT, val.GetData().Int); break;
case C4V_Bool: AddBCC(AB_BOOL, val.GetData().Int); break;
case C4V_String: AddBCC(AB_STRING, reinterpret_cast<intptr_t>(val.GetData().Str)); break;
case C4V_String:
AddBCC(AB_STRING, reinterpret_cast<intptr_t>(val._getStr()));
break;
case C4V_C4ID: AddBCC(AB_C4ID, val.GetData().Int); break;
case C4V_Any:
// any: allow zero; add it as int
@ -2701,7 +2716,7 @@ void C4AulParseState::Parse_Expression(int iParentPrio)
if(Type == PARSER && SEqual(C4ScriptOpMap[OpID].Identifier, "-"))
if((a->CPos - 1)->bccType == AB_INT)
{
(a->CPos - 1)->bccX = -(a->CPos - 1)->bccX;
(a->CPos - 1)->Par.i = -(a->CPos - 1)->Par.i;
break;
}
// write byte code
@ -2830,6 +2845,7 @@ void C4AulParseState::Parse_Expression2(int iParentPrio)
Shift(Discard, false);
// C4ID -> namespace given
C4AulFunc *pFunc = NULL;
C4String *pName = NULL;
C4AulBCCType eCallType = AB_CALL;
C4ID idNS = 0;
if(TokenType == ATT_C4ID)
@ -2854,8 +2870,6 @@ void C4AulParseState::Parse_Expression2(int iParentPrio)
{
throw new C4AulParseError(this, FormatString("direct object call: function %s::%s not found", C4IdText(idNS), Idtf).getData());
}
// write namespace chunk to byte code
AddBCC(AB_CALLNS, idNS);
}
}
else
@ -2886,12 +2900,16 @@ void C4AulParseState::Parse_Expression2(int iParentPrio)
break;
}
}
if (Type == PARSER)
{
pName = Game.ScriptEngine.Strings.RegString(Idtf);
}
// add call chunk
Shift();
Parse_Params(C4AUL_MAX_Par, pFunc ? pFunc->Name : 0, pFunc);
Parse_Params(C4AUL_MAX_Par, pName ? pName->GetCStr() : Idtf, pFunc);
if(idNS != 0)
AddBCC(AB_CALLNS, (long) idNS);
AddBCC(eCallType, (long) pFunc);
AddBCC(AB_CALLNS, idNS);
AddBCC(eCallType, (intptr_t) pName);
break;
}
default:
@ -3148,8 +3166,8 @@ BOOL C4AulScript::Parse()
{
C4AulBCC *pBCC = Code + i;
if(pBCC->bccType == AB_JUMP || pBCC->bccType == AB_JUMPAND || pBCC->bccType == AB_JUMPOR || pBCC->bccType == AB_CONDN)
if(!pBCC->bccX)
pBCC->bccX = CPos - Code - i;
if(!pBCC->Par.i)
pBCC->Par.i = CPos - Code - i;
}
// add an error chunk
AddBCC(AB_ERR);
@ -3195,15 +3213,15 @@ BOOL C4AulScript::Parse()
LogSilentF("%s:", Fn->Name);
for(C4AulBCC *pBCC = Fn->Code;; pBCC++)
{
C4AulBCCType eType = pBCC->bccType; long X = pBCC->bccX;
C4AulBCCType eType = pBCC->bccType;
switch (eType)
{
case AB_FUNC: case AB_CALL: case AB_CALLFS:
LogSilentF("%s\t'%s'\n", GetTTName(eType), X ? ((C4AulFunc *)X)->Name : ""); break;
case AB_STRING:
LogSilentF("%s\t'%s'\n", GetTTName(eType), X ? ((C4String *)X)->GetCStr() : ""); break;
case AB_FUNC:
LogSilentF("%s\t'%s'\n", GetTTName(eType), pBCC->Par.f->Name); break;
case AB_STRING: case AB_CALL: case AB_CALLFS:
LogSilentF("%s\t'%s'\n", GetTTName(eType), pBCC->Par.s->GetCStr()); break;
default:
LogSilentF("%s\t%ld\n", GetTTName(eType), X); break;
LogSilentF("%s\t%ld\n", GetTTName(eType), pBCC->Par.X); break;
}
if(eType == AB_EOFN) break;
}