From 82978b282d70f99cdc7e756cbf41d093bc8cd014 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Sat, 2 Dec 2023 18:56:30 +0100 Subject: [PATCH] C4AulScript: Replace Code and related members with std::vector --- src/C4Aul.cpp | 6 +-- src/C4Aul.h | 8 ++-- src/C4AulExec.cpp | 2 +- src/C4AulLink.cpp | 4 +- src/C4AulParse.cpp | 99 ++++++++++++++++++---------------------------- 5 files changed, 47 insertions(+), 72 deletions(-) diff --git a/src/C4Aul.cpp b/src/C4Aul.cpp index 6b7c8c479..b87cec549 100644 --- a/src/C4Aul.cpp +++ b/src/C4Aul.cpp @@ -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 @@ -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; } diff --git a/src/C4Aul.h b/src/C4Aul.h index fbcef77b0..26a0ef8cc 100644 --- a/src/C4Aul.h +++ b/src/C4Aul.h @@ -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 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 @@ -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 diff --git a/src/C4AulExec.cpp b/src/C4AulExec.cpp index b1714e07e..45dd385aa 100644 --- a/src/C4AulExec.cpp +++ b/src/C4AulExec.cpp @@ -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)); diff --git a/src/C4AulLink.cpp b/src/C4AulLink.cpp index d0068e79c..599236019 100644 --- a/src/C4AulLink.cpp +++ b/src/C4AulLink.cpp @@ -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); @@ -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; diff --git a/src/C4AulParse.cpp b/src/C4AulParse.cpp index 7c4762eec..28289c646 100644 --- a/src/C4AulParse.cpp +++ b/src/C4AulParse.cpp @@ -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() @@ -933,7 +915,7 @@ bool C4AulScript::Preparse() // clear stuff Includes.clear(); Appends.clear(); - CPos = Code; + Code.clear(); while (Func0) { // belongs to this script? @@ -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; } @@ -1126,14 +1105,14 @@ 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::reverse_iterator &CPos, std::vector &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: @@ -1141,17 +1120,17 @@ namespace 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; @@ -1159,7 +1138,7 @@ namespace case AB_ARRAY: { const auto size = CPos->bccX; - --CPos; + ++CPos; SkipExpressions(size, CPos, Code); --n; break; @@ -1168,7 +1147,7 @@ namespace case AB_MAP: { const auto size = 2 * CPos->bccX; - --CPos; + ++CPos; SkipExpressions(size, CPos, Code); --n; break; @@ -1176,7 +1155,7 @@ namespace } case AB_PAR_R: case AB_PAR_V: case AB_VAR_R: case AB_VAR_V: - --CPos; + ++CPos; SkipExpressions(1, CPos, Code); --n; break; @@ -1184,28 +1163,28 @@ namespace case AB_FUNC: { const auto pars = reinterpret_cast(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; } @@ -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; @@ -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(CPos - Code); + Fn->Code = reinterpret_cast(Code.size()); // parse C4AulParseState state(Fn, this, C4AulParseState::PARSER); // get first token @@ -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) { @@ -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; @@ -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(Fn->Code); i < CPos - Code; i++) + for (std::intptr_t i = reinterpret_cast(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); @@ -3558,7 +3537,7 @@ bool C4AulScript::Parse() if (Fn) if (Fn->Owner != Engine) Fn = nullptr; } if (Fn) - Fn->Code = Code + reinterpret_cast(Fn->Code); + Fn->Code = &Code[reinterpret_cast(Fn->Code)]; } // save line count