Move DirectExec from C4AulScript to C4AulExec

In the long term, there is no reason DirectExec should be concerned with
C4AulScript/C4ScriptHost. In the meantime, the lookup code from Fneval can
be moved into the function.

This allows eval in scenario script to access scenario script locals, but
that seems harmless.
epoxy
Günther Brammer 2015-02-01 22:20:52 +01:00
parent 7cc1334963
commit 20c22582ec
9 changed files with 29 additions and 34 deletions

View File

@ -234,18 +234,16 @@ void C4ControlScript::Execute() const
if (!Game.Parameters.AllowDebug) return;
// execute
C4Object *pObj = NULL;
C4PropList *pPropList = NULL;
C4AulScript *pScript;
if (iTargetObj == SCOPE_Console)
pScript = &::GameScript;
pPropList = ::GameScript.GetPropList();
else if (iTargetObj == SCOPE_Global)
pScript = &::ScriptEngine;
else if ((pObj = ::Objects.SafeObjectPointer(iTargetObj)))
pScript = &(pObj->Def->Script);
else
pPropList = ::ScriptEngine.GetPropList();
else if (!(pPropList = ::Objects.SafeObjectPointer(iTargetObj)))
// default: Fallback to global context
pScript = &::ScriptEngine;
C4Value rVal(pScript->DirectExec(pObj, szScript, "console script", false, fUseVarsFromCallerContext ? AulExec.GetContext(AulExec.GetContextDepth()-1) : NULL));
pPropList = ::ScriptEngine.GetPropList();
C4Value rVal(AulExec.DirectExec(pPropList, szScript, "console script", false, fUseVarsFromCallerContext ? AulExec.GetContext(AulExec.GetContextDepth()-1) : NULL));
#ifndef NOAULDEBUG
C4AulDebug* pDebug;
if ( (pDebug = C4AulDebug::GetDebugger()) )
@ -255,10 +253,7 @@ void C4ControlScript::Execute() const
#endif
// show messages
// print script
if (pObj)
LogF("-> %s::%s", pObj->Def->GetName(), szScript);
else
LogF("-> %s", szScript);
LogF("-> %s::%s", pPropList->GetName(), szScript);
// print result
if (!LocalControl())
{
@ -331,7 +326,7 @@ void C4ControlMsgBoardCmd::Execute() const
}
// Run script
C4Value rv(::ScriptEngine.DirectExec(nullptr, script.getData(), "message board command"));
C4Value rv(::AulExec.DirectExec(::ScriptEngine.GetPropList(), script.getData(), "message board command"));
#ifndef NOAULDEBUG
C4AulDebug* pDebug = C4AulDebug::GetDebugger();
if (pDebug)

View File

@ -20,6 +20,7 @@
#include <C4Include.h>
#include <C4Object.h>
#include <C4AulExec.h>
#include <C4DefList.h>
#include <C4Effect.h>
#include <C4ObjectInfo.h>
@ -2564,7 +2565,7 @@ bool C4Object::MenuCommand(const char *szCommand)
{
// Native script execution
if (!Def || !Status) return false;
return !! Def->Script.DirectExec(this, szCommand, "MenuCommand");
return !! ::AulExec.DirectExec(this, szCommand, "MenuCommand");
}
C4Object *C4Object::ComposeContents(C4ID id)

View File

@ -29,7 +29,7 @@
#include "C4Game.h"
#include "C4PlayerList.h"
#include "C4GameObjects.h"
#include "C4AulExec.h"
// -----------------------------------------------------------
// C4ObjectMenu
@ -304,7 +304,7 @@ bool C4ObjectMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand)
case CB_Scenario:
// Object menu with scenario script callback
::GameScript.DirectExec(NULL, szCommand, "MenuCommand");
::AulExec.DirectExec(NULL, szCommand, "MenuCommand");
break;
case CB_None:

View File

@ -148,7 +148,6 @@ public:
virtual C4PropListStatic * GetPropList() { return 0; }
virtual C4ScriptHost * GetScriptHost() { return 0; }
C4Value DirectExec(C4Object *pObj, const char *szScript, const char *szContext, bool fPassErrors = false, C4AulScriptContext* context = NULL); // directly parse uncompiled script (WARG! CYCLES!)
virtual void ResetProfilerTimes(); // zero all profiler times of owned functions
virtual void CollectProfilerTimes(class C4AulProfiler &rProfiler);

View File

@ -1025,28 +1025,33 @@ void C4AulProfiler::Show()
// done!
}
C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char *szContext, bool fPassErrors, C4AulScriptContext* context)
C4Value C4AulExec::DirectExec(C4PropList *p, const char *szScript, const char *szContext, bool fPassErrors, C4AulScriptContext* context)
{
#ifdef DEBUGREC_SCRIPT
if (Config.General.DebugRec)
{
AddDbgRec(RCT_DirectExec, szScript, strlen(szScript)+1);
int32_t iObjNumber = pObj ? pObj->Number : -1;
int32_t iObjNumber = p && p->GetPropListNumbered() ? p->GetPropListNumbered()->Number : -1;
AddDbgRec(RCT_DirectExec, &iObjNumber, sizeof(int32_t));
}
#endif
// profiler
AulExec.StartDirectExec();
StartDirectExec();
C4AulScript * script = &::GameScript;
if (p == ::ScriptEngine.GetPropList())
script = &::ScriptEngine;
else if (p && p->GetDef())
script = &p->GetDef()->Script;
// Add a new function
C4AulScriptFunc *pFunc = new C4AulScriptFunc(GetPropList(), GetScriptHost(), 0, szScript);
C4AulScriptFunc *pFunc = new C4AulScriptFunc(script->GetPropList(), script->GetScriptHost(), 0, szScript);
// Parse function
try
{
pFunc->ParseFn(context);
C4Value vRetVal(AulExec.Exec(pFunc, pObj, NULL, fPassErrors));
C4Value vRetVal(Exec(pFunc, p, NULL, fPassErrors));
delete pFunc; pFunc = 0;
// profiler
AulExec.StopDirectExec();
StopDirectExec();
return vRetVal;
}
catch (C4AulError &ex)

View File

@ -76,6 +76,7 @@ private:
public:
C4Value Exec(C4AulScriptFunc *pSFunc, C4PropList * p, C4Value pPars[], bool fPassErrors);
C4Value Exec(C4AulBCC *pCPos, bool fPassErrors);
C4Value DirectExec(C4PropList *p, const char *szScript, const char *szContext, bool fPassErrors = false, C4AulScriptContext* context = NULL);
void StartTrace();
void StartProfiling(C4AulScript *pScript); // resets profling times and starts recording the times

View File

@ -581,13 +581,7 @@ static Nillable<long> FnGetChar(C4PropList * _this, C4String *pString, long iInd
static C4Value Fneval(C4PropList * _this, C4String *strScript)
{
// execute script in the same object
if (Object(_this))
return Object(_this)->Def->Script.DirectExec(Object(_this), FnStringPar(strScript), "eval", true);
else if (_this && _this->GetDef())
return _this->GetDef()->Script.DirectExec(0, FnStringPar(strScript), "eval", true);
else
return ::GameScript.DirectExec(0, FnStringPar(strScript), "eval", true);
return ::AulExec.DirectExec(_this, FnStringPar(strScript), "eval", true);
}
static bool FnLocateFunc(C4PropList * _this, C4String *funcname, C4PropList * p)

View File

@ -15,16 +15,14 @@
#include <C4Include.h>
#include "script/C4Aul.h"
#include "script/C4AulExec.h"
#include <gtest/gtest.h>
TEST(DirectExecTest, SanityTests)
{
C4AulScript * pScript = new C4AulScript();
ASSERT_TRUE(pScript);
C4Value rVal(pScript->DirectExec(nullptr, "5*8", "unit test script", false, nullptr));
C4Value rVal(AulExec.DirectExec(nullptr, "5*8", "unit test script", false, nullptr));
EXPECT_EQ(rVal, C4Value(5*8));
delete pScript;
}
template<typename T>

View File

@ -121,4 +121,6 @@ TEST_F(AulTest, Locals)
TEST_F(AulTest, Eval)
{
EXPECT_EQ(C4VInt(42), RunExpr("eval(\"42\")"));
EXPECT_EQ(C4VInt(42), RunCode("local i = 42; func Main() { return eval(\"this.i\"); }", false));
EXPECT_EQ(C4VInt(42), RunCode("local i; func Main() { eval(\"this.i = 42\"); return i; }", false));
}