Script: this returns nil after RemoveObject instead of throwing

Because the interpreter throws for every function that is called with a
this parameter that has been removed, this() isn't a function anymore.
The function could stay around so that Call("this") or foo->this()
would still work, but I doubt any script ever did that.
Günther Brammer 2012-06-18 04:07:36 +02:00
parent 23d1246be1
commit 7f9ab9ac19
4 changed files with 22 additions and 14 deletions

View File

@ -93,6 +93,7 @@ enum C4AulBCCType
AB_GLOBALN, // a named global
AB_GLOBALN_SET,
AB_PAR, // Par statement
AB_THIS, // this()
AB_FUNC, // function
AB_PARN_CONTEXT,

View File

@ -711,6 +711,13 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
pCurVal->Set0();
break;
case AB_THIS:
if (!pCurCtx->Obj || !pCurCtx->Obj->Status)
PushNullVals(1);
else
PushPropList(pCurCtx->Obj);
break;
case AB_FOREACH_NEXT:
{
// This should always hold

View File

@ -629,6 +629,7 @@ static const char * GetTTName(C4AulBCCType e)
case AB_GLOBALN: return "GLOBALN"; // a named global
case AB_GLOBALN_SET: return "GLOBALN_SET";
case AB_PAR: return "PAR"; // Par statement
case AB_THIS: return "THIS";
case AB_FUNC: return "FUNC"; // function
case AB_PARN_CONTEXT: return "AB_PARN_CONTEXT";
@ -689,7 +690,7 @@ static const char * GetTTName(C4AulBCCType e)
case AB_EOFN: return "EOFN"; // end of function
case AB_EOF: return "EOF";
default: return "?";
default: assert(false);
}
}
@ -829,6 +830,7 @@ int C4AulParse::GetStackValue(C4AulBCCType eType, intptr_t X)
case AB_LOCALN:
case AB_GLOBALN:
case AB_DUP:
case AB_THIS:
return 1;
case AB_Pow:
@ -1550,7 +1552,7 @@ void C4AulParse::Parse_Function()
case AB_STRING:
fprintf(stderr, "\t\"%s\"\n", pBCC->Par.s->GetCStr()); break;
case AB_DEBUG: case AB_NIL: case AB_RETURN:
case AB_PAR:
case AB_PAR: case AB_THIS:
case AB_ARRAYA: case AB_ARRAYA_SET: case AB_ARRAY_SLICE: case AB_ARRAY_SLICE_SET:
case AB_ERR: case AB_EOFN: case AB_EOF:
assert(!pBCC->Par.X); fprintf(stderr, "\n"); break;
@ -2310,6 +2312,15 @@ void C4AulParse::Parse_Expression(int iParentPrio)
Parse_Params(1, C4AUL_Par);//FIXME: don't use Parse_Params
AddBCC(AB_PAR);
}
else if (SEqual(Idtf, C4AUL_this))
{
Shift();
if (TokenType == ATT_BOPEN)
{
Parse_Params(0, Idtf, 0);
}
AddBCC(AB_THIS);
}
else if (SEqual(Idtf, C4AUL_Inherited) || SEqual(Idtf, C4AUL_SafeInherited))
{
Shift();
@ -2356,11 +2367,7 @@ void C4AulParse::Parse_Expression(int iParentPrio)
if (Config.Developer.ExtraWarnings && !FoundFn->GetPublic())
Warn("using deprecated function %s", Idtf);
Shift();
// Function parameters for all functions except "this", which can be used without
if (!SEqual(FoundFn->GetName(), C4AUL_this) || TokenType == ATT_BOPEN)
Parse_Params(FoundFn->GetParCount(), FoundFn->GetName(), FoundFn);
else
AddBCC(AB_STACK, FoundFn->GetParCount());
Parse_Params(FoundFn->GetParCount(), FoundFn->GetName(), FoundFn);
AddBCC(AB_FUNC, (intptr_t) FoundFn);
}
else

View File

@ -168,11 +168,6 @@ C4Value C4AulDefFunc::Exec(C4PropList * p, C4Value pPars[], bool fPassErrors)
//=============================== C4Script Functions ====================================
static C4PropList *Fnthis(C4PropList * _this)
{
return _this;
}
static C4PropList * FnCreatePropList(C4PropList * _this, C4PropList * prototype)
{
return C4PropList::New(prototype);
@ -641,8 +636,6 @@ void InitCoreFunctionMap(C4AulScriptEngine *pEngine)
F(LocateFunc);
F(eval);
F(this);
F(GetConstantNameByValue);
AddFunc(pEngine, "Translate", C4AulExec::FnTranslate);