Correctly map bytecode to linenumber for global/appended/included functions

The method to get the C4AulScript instance that stores the bytecode of a
function is ridiculous, but at least it's now capsuled in a function. While
at it, this also always stores the bytecode index instead of a bytecode
pointer in the function.
Günther Brammer 2010-12-22 02:10:58 +01:00
parent a8abb445fd
commit 40c24961dd
4 changed files with 30 additions and 16 deletions

View File

@ -310,6 +310,7 @@ public:
C4AulScriptFunc *SFunc() { return this; } // type check func...
protected:
void ParseDesc(); // evaluate desc (i.e. get idImage and Condition
int CodePos; // code pos
public:
C4AulAccess Access;
@ -321,7 +322,6 @@ public:
C4AulFunc *Condition; // func condition
int32_t ControlMethod; // 0 = all, 1 = Classic, 2 = Jump+Run
const char *Script; // script pos
C4AulBCC *Code; // code pos
C4ValueMapNames VarNamed; // list of named vars in this function
C4ValueMapNames ParNamed; // list of named pars in this function
C4V_Type ParType[C4AUL_MAX_Par]; // parameter types
@ -347,6 +347,9 @@ public:
void CopyBody(C4AulScriptFunc &FromFunc); // copy script/code, etc from given func
StdStrBuf GetFullName(); // get a fully classified name (C4ID::Name) for debug output
int GetLineOfCode(C4AulBCC * bcc);
C4AulBCC * GetCode();
C4AulScript * GetCodeOwner();
time_t tProfileTime; // internally set by profiler
@ -469,7 +472,6 @@ public:
// helper functions
void Warn(const char *pMsg, const char *pIdtf);
int GetLineOfCode(C4AulBCC * CPos);
friend class C4AulParseError;
friend class C4AulFunc;

View File

@ -207,6 +207,7 @@ void C4AulDebug::ProcessLine(const StdStrBuf &Line)
// toggle breakpoint
else if (SEqualNoCase(szCmd, "TBR"))
{
// FIXME: this doesn't find functions which were included/appended
StdStrBuf scriptPath;
scriptPath.CopyUntil(szData, ':');
const char* lineStart = szData+1+scriptPath.getLength();
@ -229,7 +230,7 @@ void C4AulDebug::ProcessLine(const StdStrBuf &Line)
{
case AB_DEBUG:
{
int lineOfThisOne = script->GetLineOfCode(chunk);
int lineOfThisOne = SGetLine(scriptText, script->PosForCode[chunk - &script->Code[0]]);
if (lineOfThisOne == line)
{
foundDebugChunk = chunk;
@ -473,7 +474,7 @@ void C4AulDebug::ObtainStackTrace(C4AulScriptContext* pCtx, C4AulBCC* pCPos)
StdStrBuf C4AulDebug::FormatCodePos(C4AulScriptContext *pCtx, C4AulBCC *pCPos)
{
// Get position in script
int iLine = pCtx->Func->pOrgScript->GetLineOfCode(pCPos);
int iLine = pCtx->Func->GetLineOfCode(pCPos);
// Format
return FormatString("%s:%d", RelativePath(pCtx->Func->pOrgScript->ScriptName), iLine);
}

View File

@ -98,7 +98,7 @@ StdStrBuf C4AulScriptContext::ReturnDump(StdStrBuf Dump)
if (!fDirectExec && Func->pOrgScript)
Dump.AppendFormat(" (%s:%d)",
Func->pOrgScript->ScriptName.getData(),
CPos ? Func->pOrgScript->GetLineOfCode(CPos) : SGetLine(Func->pOrgScript->GetScript(), Func->Script));
CPos ? Func->GetLineOfCode(CPos) : SGetLine(Func->pOrgScript->GetScript(), Func->Script));
// Return it
return Dump;
}
@ -144,7 +144,7 @@ C4Value C4AulExec::Exec(C4AulScriptFunc *pSFunc, C4Object *pObj, C4Value *pnPars
PushContext(ctx);
// Execute
return Exec(pSFunc->Code, fPassErrors);
return Exec(pSFunc->GetCode(), fPassErrors);
}
C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
@ -871,11 +871,11 @@ C4AulBCC *C4AulExec::Call(C4AulFunc *pFunc, C4Value *pReturn, C4Value *pPars, C4
#ifndef NOAULDEBUG
// Notify debugger
if (C4AulDebug *pDebug = ::ScriptEngine.GetDebugger())
pDebug->DebugStepIn(pSFunc->Code);
pDebug->DebugStepIn(pSFunc->GetCode());
#endif
// Jump to code
return pSFunc->Code;
return pSFunc->GetCode();
}
else
{
@ -1179,7 +1179,7 @@ C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char
delete pScript;
return C4VNull;
}
pFunc->Code = &pScript->Code[1];
pFunc->CodePos = 1;
pScript->State = ASS_PARSED;
// Execute. The TemporaryScript-parameter makes sure the script will be deleted later on.
C4Value vRetVal(AulExec.Exec(pFunc, pObj, NULL, fPassErrors, true));

View File

@ -958,9 +958,19 @@ void C4AulScript::ClearCode()
AddBCC(AB_ERR);
}
int C4AulScript::GetLineOfCode(C4AulBCC * bcc)
int C4AulScriptFunc::GetLineOfCode(C4AulBCC * bcc)
{
return SGetLine(GetScript(), PosForCode[bcc - &Code[0]]);
return SGetLine(GetCodeOwner()->GetScript(), GetCodeOwner()->PosForCode[bcc - &GetCodeOwner()->Code[0]]);
}
C4AulBCC * C4AulScriptFunc::GetCode()
{
return &GetCodeOwner()->Code[CodePos];
}
C4AulScript * C4AulScriptFunc::GetCodeOwner()
{
return Owner == Owner->Engine ? LinkedTo->Owner : Owner;
}
bool C4AulScript::Preparse()
@ -1368,7 +1378,8 @@ void C4AulScript::ParseFn(C4AulScriptFunc *Fn, bool fExprOnly, C4AulScriptContex
// store byte code pos
// (relative position to code start; code pointer may change while
// parsing)
Fn->Code = (C4AulBCC *) (CPos - &Code[0]);
assert(Fn->GetCodeOwner() == this);
Fn->CodePos = CPos - &Code[0];
// parse
C4AulParseState state(Fn, this, C4AulParseState::PARSER);
state.ContextToExecIn = context;
@ -3138,7 +3149,7 @@ bool C4AulScript::Parse()
delete err;
// make all jumps that don't have their destination yet jump here
// intptr_t to make it work on 64bit
for (intptr_t i = reinterpret_cast<intptr_t>(Fn->Code); i < CPos - &Code[0]; i++)
for (int i = Fn->CodePos; i < CPos - &Code[0]; i++)
{
C4AulBCC *pBCC = &Code[i];
if (IsJump(pBCC->bccType))
@ -3168,7 +3179,7 @@ bool C4AulScript::Parse()
if (Fn) if (Fn->Owner != Engine) Fn=NULL;
}
if (Fn)
Fn->Code = &Code[(intptr_t) Fn->Code];
assert(Fn->GetCodeOwner() == this);
}
// save line count
@ -3187,10 +3198,10 @@ bool C4AulScript::Parse()
if (!Fn)
continue;
fprintf(stderr, "%s:\n", Fn->Name);
for (C4AulBCC *pBCC = Fn->Code;; pBCC++)
for (C4AulBCC *pBCC = Fn->GetCode();; pBCC++)
{
C4AulBCCType eType = pBCC->bccType;
fprintf(stderr, "\t%d\t%s", GetLineOfCode(pBCC), GetTTName(eType));
fprintf(stderr, "\t%d\t%s", Fn->GetLineOfCode(pBCC), GetTTName(eType));
switch (eType)
{
case AB_FUNC: