Skip to content

Commit

Permalink
C4AulScript: Replace Code and related members with std::vector
Browse files Browse the repository at this point in the history
  • Loading branch information
maxmitti committed Dec 2, 2023
1 parent ee441e5 commit 82978b2
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 72 deletions.
6 changes: 2 additions & 4 deletions src/C4Aul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ void C4AulScript::Default()
// not compiled
State = ASS_NONE;
Script.Clear();
Code = CPos = nullptr;
CodeSize = CodeBufSize = 0;
Code.clear();
IncludesResolved = false;

// defaults
Expand Down Expand Up @@ -226,8 +225,7 @@ void C4AulScript::Clear()
while (Func0) delete Func0;
// delete script+code
Script.Clear();
delete[] Code; Code = nullptr;
CodeSize = CodeBufSize = 0;
Code.clear();
// reset flags
State = ASS_NONE;
}
Expand Down
8 changes: 3 additions & 5 deletions src/C4Aul.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,8 @@ class C4AulScript
C4AulScript *Owner, *Prev, *Next, *Child0, *ChildL; // tree structure

StdStrBuf Script; // script
C4AulBCC *Code, *CPos; // compiled script (/pos)
std::vector<C4AulBCC> Code; // compiled script
C4AulScriptState State; // script state
int CodeSize; // current number of byte code chunks in Code
int CodeBufSize; // size of Code buffer
bool Preparsing; // set while preparse
bool Resolving; // set while include-resolving, to catch circular includes

Expand Down Expand Up @@ -486,8 +484,8 @@ class C4AulScript

C4AulScript *FindFirstNonStrictScript(); // find first script that is not #strict

size_t GetCodePos() const { return CPos - Code; }
C4AulBCC *GetCodeByPos(size_t iPos) { return Code + iPos; }
size_t GetCodePos() const { return Code.size(); }
C4AulBCC *GetCodeByPos(size_t iPos) { return &Code[iPos]; }

public:
StdStrBuf ScriptName; // script name
Expand Down
2 changes: 1 addition & 1 deletion src/C4AulExec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1687,7 +1687,7 @@ C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char
delete pScript;
return C4VNull;
}
pFunc->Code = pScript->Code;
pFunc->Code = pScript->Code.data();
pScript->State = ASS_PARSED;
// Execute. The TemporaryScript-parameter makes sure the script will be deleted later on.
C4Value vRetVal(AulExec.Exec(pFunc, pObj, nullptr, fPassErrors, true));
Expand Down
4 changes: 2 additions & 2 deletions src/C4AulLink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ void C4AulScript::AppendTo(C4AulScript &Scr, bool bHighPrio)
}
// mark as linked
// increase code size needed
Scr.CodeSize += CodeSize + 1;
//Scr.CodeSize += CodeSize + 1;
// append all local vars (if any existing)
assert(!Def || this == &Def->Script);
assert(!Scr.Def || &Scr.Def->Script == &Scr);
Expand All @@ -166,7 +166,7 @@ void C4AulScript::UnLink()
if (Temporary) return;

// check if byte code needs to be freed
delete[] Code; Code = nullptr;
Code.clear();

// delete included/appended functions
C4AulFunc *pFunc = Func0;
Expand Down
99 changes: 39 additions & 60 deletions src/C4AulParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,25 +904,7 @@ static const char *GetTTName(C4AulBCCType e)

void C4AulScript::AddBCC(C4AulBCCType eType, std::intptr_t X, const char *SPos)
{
// range check
if (CodeSize >= CodeBufSize)
{
// create new buffer
CodeBufSize = CodeBufSize ? 2 * CodeBufSize : C4AUL_CodeBufSize;
C4AulBCC *nCode = new C4AulBCC[CodeBufSize];
// copy data
memcpy(nCode, Code, sizeof(*Code) * CodeSize);
// replace buffer
delete[] Code;
Code = nCode;
// adjust pointer
CPos = Code + CodeSize;
}
// store chunk
CPos->bccType = eType;
CPos->bccX = X;
CPos->SPos = SPos;
CPos++; CodeSize++;
Code.emplace_back(C4AulBCC{eType, X, SPos});
}

bool C4AulScript::Preparse()
Expand All @@ -933,7 +915,7 @@ bool C4AulScript::Preparse()

// clear stuff
Includes.clear(); Appends.clear();
CPos = Code;
Code.clear();
while (Func0)
{
// belongs to this script?
Expand Down Expand Up @@ -1098,20 +1080,17 @@ void C4AulParseState::AddBCC(C4AulBCCType eType, std::intptr_t X)
}

// Join checks only if it's not a jump target
if (!fJump)
// Join together stack operations
if (!fJump && eType == AB_STACK && !a->Code.empty())
{
// Join together stack operations
if (eType == AB_STACK &&
a->CPos > a->Code &&
(a->CPos - 1)->bccType == AB_STACK
&& (X <= 0 || (a->CPos - 1)->bccX >= 0))
auto &back = a->Code.back();
if (back.bccType == AB_STACK && (X <= 0 || back.bccX >= 0))
{
(a->CPos - 1)->bccX += X;
back.bccX += X;
// Empty? Remove it.
if (!(a->CPos - 1)->bccX)
if (back.bccX == 0)
{
a->CPos--;
a->CodeSize--;
a->Code.pop_back();
}
return;
}
Expand All @@ -1126,40 +1105,40 @@ void C4AulParseState::AddBCC(C4AulBCCType eType, std::intptr_t X)

namespace
{
void SkipExpressions(intptr_t n, C4AulBCC *&CPos, C4AulBCC *const Code)
void SkipExpressions(intptr_t n, std::vector<C4AulBCC>::reverse_iterator &CPos, std::vector<C4AulBCC> &Code)
{
while (n > 0 && CPos > Code)
while (n > 0 && CPos != Code.rend())
{
switch (CPos->bccType)
{
case AB_STACK:
if (CPos->bccX > 0) n -= CPos--->bccX;
if (CPos->bccX > 0) n -= CPos++->bccX;
break;

case AB_INT: case AB_BOOL: case AB_STRING: case AB_C4ID:
case AB_PARN_R: case AB_PARN_V: case AB_VARN_R: case AB_VARN_V:
case AB_LOCALN_R: case AB_LOCALN_V:
case AB_GLOBALN_R: case AB_GLOBALN_V:
--n;
--CPos;
++CPos;
break;

case AB_MAPA_R: case AB_MAPA_V: case AB_ARRAY_APPEND:
--CPos;
++CPos;
SkipExpressions(1, CPos, Code);
--n;
break;

case AB_ARRAYA_R: case AB_ARRAYA_V:
--CPos;
++CPos;
SkipExpressions(2, CPos, Code);
--n;
break;

case AB_ARRAY:
{
const auto size = CPos->bccX;
--CPos;
++CPos;
SkipExpressions(size, CPos, Code);
--n;
break;
Expand All @@ -1168,44 +1147,44 @@ namespace
case AB_MAP:
{
const auto size = 2 * CPos->bccX;
--CPos;
++CPos;
SkipExpressions(size, CPos, Code);
--n;
break;

}

case AB_PAR_R: case AB_PAR_V: case AB_VAR_R: case AB_VAR_V:
--CPos;
++CPos;
SkipExpressions(1, CPos, Code);
--n;
break;

case AB_FUNC:
{
const auto pars = reinterpret_cast<C4AulFunc *>(CPos->bccX)->GetParCount();
--CPos;
++CPos;
SkipExpressions(pars, CPos, Code);
--n;
break;
}

case AB_CALLNS:
--CPos;
++CPos;
break;

case AB_CALL: case AB_CALLFS: case AB_CALLGLOBAL:
--CPos;
++CPos;
SkipExpressions(C4AUL_MAX_Par + (CPos->bccType != AB_CALLGLOBAL ? 1 : 0), CPos, Code);
--n;
break;

default:
// operator?
if (Inside(CPos->bccType, AB_Inc1, AB_Set) && CPos > Code)
if (Inside(CPos->bccType, AB_Inc1, AB_Set) && CPos != Code.rend())
{
const auto &op = C4ScriptOpMap[CPos->bccX];
--CPos;
++CPos;
SkipExpressions(op.NoSecondStatement || !op.Postfix ? 1 : 2, CPos, Code);
--n;
}
Expand All @@ -1219,18 +1198,18 @@ namespace
void C4AulParseState::SetNoRef()
{
if (Type != PARSER) return;
for(C4AulBCC *CPos = a->CPos - 1; CPos >= a->Code; )
for(auto CPos = a->Code.rbegin(); CPos != a->Code.rend(); )
{
switch (CPos->bccType)
{
case AB_MAPA_R:
CPos->bccType = AB_MAPA_V;
--CPos;
++CPos;
// propagate back to the accessed map
break;
case AB_ARRAYA_R:
CPos->bccType = AB_ARRAYA_V;
--CPos;
++CPos;
// propagate back to the accessed array
SkipExpressions(1, CPos, a->Code);
break;
Expand Down Expand Up @@ -1390,7 +1369,7 @@ void C4AulScript::ParseFn(C4AulScriptFunc *Fn, bool fExprOnly)
// store byte code pos
// (relative position to code start; code pointer may change while
// parsing)
Fn->Code = reinterpret_cast<C4AulBCC *>(CPos - Code);
Fn->Code = reinterpret_cast<C4AulBCC *>(Code.size());
// parse
C4AulParseState state(Fn, this, C4AulParseState::PARSER);
// get first token
Expand Down Expand Up @@ -2882,11 +2861,14 @@ void C4AulParseState::Parse_Expression(int iParentPrio)
break;
// negate constant?
if (Type == PARSER && SEqual(C4ScriptOpMap[OpID].Identifier, "-"))
if ((a->CPos - 1)->bccType == AB_INT)
{
auto &back = a->Code.back();
if (back.bccType == AB_INT)
{
(a->CPos - 1)->bccX = -(a->CPos - 1)->bccX;
back.bccX = -back.bccX;
break;
}
}

if (C4ScriptOpMap[OpID].Type1 != C4V_pC4Value)
{
Expand Down Expand Up @@ -3490,10 +3472,7 @@ bool C4AulScript::Parse()
// don't parse global funcs again, as they're parsed already through links
if (this == Engine) return false;
// delete existing code
delete[] Code;
CodeSize = CodeBufSize = 0;
// reset code and script pos
CPos = Code;
Code.clear();

// parse script funcs
C4AulFunc *f;
Expand Down Expand Up @@ -3529,12 +3508,12 @@ bool C4AulScript::Parse()
}
// make all jumps that don't have their destination yet jump here
// std::intptr_t to make it work on 64bit
for (std::intptr_t i = reinterpret_cast<std::intptr_t>(Fn->Code); i < CPos - Code; i++)
for (std::intptr_t i = reinterpret_cast<std::intptr_t>(Fn->Code); i < Code.size(); i++)
{
C4AulBCC *pBCC = Code + i;
if (IsJumpType(pBCC->bccType))
if (!pBCC->bccX)
pBCC->bccX = CPos - Code - i;
C4AulBCC &bcc = Code[i];
if (IsJumpType(bcc.bccType))
if (bcc.bccX == 0)
bcc.bccX = Code.size() - i;
}
// add an error chunk
AddBCC(AB_ERR);
Expand All @@ -3558,7 +3537,7 @@ bool C4AulScript::Parse()
if (Fn) if (Fn->Owner != Engine) Fn = nullptr;
}
if (Fn)
Fn->Code = Code + reinterpret_cast<std::intptr_t>(Fn->Code);
Fn->Code = &Code[reinterpret_cast<std::intptr_t>(Fn->Code)];
}

// save line count
Expand Down

0 comments on commit 82978b2

Please sign in to comment.