mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 12:58:00 +03:00
Replace mwscript program serialization into a vector with simple struct
Mostly to avoid string literal lookup by index with iteration over all preciding literals and calling strlen. This is very inefficient. In genral this makes code much more straightforward but also makes it portable since now int and float of different sizes are properly supported.
This commit is contained in:
parent
60eede6a1d
commit
b88f0d2dbd
21 changed files with 93 additions and 162 deletions
|
@ -17,9 +17,9 @@ namespace Compiler
|
|||
return mName;
|
||||
}
|
||||
|
||||
void FileParser::getCode(std::vector<Interpreter::Type_Code>& code) const
|
||||
Interpreter::Program FileParser::getProgram() const
|
||||
{
|
||||
mScriptParser.getCode(code);
|
||||
return mScriptParser.getProgram();
|
||||
}
|
||||
|
||||
const Locals& FileParser::getLocals() const
|
||||
|
|
|
@ -31,8 +31,7 @@ namespace Compiler
|
|||
std::string getName() const;
|
||||
///< Return script name.
|
||||
|
||||
void getCode(std::vector<Interpreter::Type_Code>& code) const;
|
||||
///< store generated code in \a code.
|
||||
Interpreter::Program getProgram() const;
|
||||
|
||||
const Locals& getLocals() const;
|
||||
///< get local variable declarations.
|
||||
|
|
|
@ -1,56 +1,10 @@
|
|||
#include "literals.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
int Literals::getIntegerSize() const
|
||||
{
|
||||
return static_cast<int>(mIntegers.size() * sizeof(Interpreter::Type_Integer));
|
||||
}
|
||||
|
||||
int Literals::getFloatSize() const
|
||||
{
|
||||
return static_cast<int>(mFloats.size() * sizeof(Interpreter::Type_Float));
|
||||
}
|
||||
|
||||
int Literals::getStringSize() const
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter(mStrings.begin()); iter != mStrings.end(); ++iter)
|
||||
size += static_cast<int>(iter->size()) + 1;
|
||||
|
||||
if (size % 4) // padding
|
||||
size += 4 - size % 4;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void Literals::append(std::vector<Interpreter::Type_Code>& code) const
|
||||
{
|
||||
for (const int& mInteger : mIntegers)
|
||||
code.push_back(*reinterpret_cast<const Interpreter::Type_Code*>(&mInteger));
|
||||
|
||||
for (const float& mFloat : mFloats)
|
||||
code.push_back(*reinterpret_cast<const Interpreter::Type_Code*>(&mFloat));
|
||||
|
||||
int stringBlockSize = getStringSize();
|
||||
int size = static_cast<int>(code.size());
|
||||
|
||||
code.resize(size + stringBlockSize / 4);
|
||||
|
||||
size_t offset = 0;
|
||||
|
||||
for (const auto& mString : mStrings)
|
||||
{
|
||||
size_t stringSize = mString.size() + 1;
|
||||
|
||||
std::copy(mString.c_str(), mString.c_str() + stringSize, reinterpret_cast<char*>(&code[size]) + offset);
|
||||
offset += stringSize;
|
||||
}
|
||||
}
|
||||
|
||||
int Literals::addInteger(Interpreter::Type_Integer value)
|
||||
{
|
||||
int index = static_cast<int>(mIntegers.size());
|
||||
|
|
|
@ -17,18 +17,11 @@ namespace Compiler
|
|||
std::vector<std::string> mStrings;
|
||||
|
||||
public:
|
||||
int getIntegerSize() const;
|
||||
///< Return size of integer block (in bytes).
|
||||
const std::vector<Interpreter::Type_Integer>& getIntegers() const { return mIntegers; }
|
||||
|
||||
int getFloatSize() const;
|
||||
///< Return size of float block (in bytes).
|
||||
const std::vector<Interpreter::Type_Float>& getFloats() const { return mFloats; }
|
||||
|
||||
int getStringSize() const;
|
||||
///< Return size of string block (in bytes).
|
||||
|
||||
void append(std::vector<Interpreter::Type_Code>& code) const;
|
||||
///< Apepnd literal blocks to code.
|
||||
/// \note code blocks will be padded for 32-bit alignment.
|
||||
const std::vector<std::string>& getStrings() const { return mStrings; }
|
||||
|
||||
int addInteger(Interpreter::Type_Integer value);
|
||||
///< add integer liternal and return index.
|
||||
|
|
|
@ -13,27 +13,14 @@ namespace Compiler
|
|||
{
|
||||
}
|
||||
|
||||
void Output::getCode(std::vector<Interpreter::Type_Code>& code) const
|
||||
Interpreter::Program Output::getProgram() const
|
||||
{
|
||||
code.clear();
|
||||
|
||||
// header
|
||||
code.push_back(static_cast<Interpreter::Type_Code>(mCode.size()));
|
||||
|
||||
assert(mLiterals.getIntegerSize() % 4 == 0);
|
||||
code.push_back(static_cast<Interpreter::Type_Code>(mLiterals.getIntegerSize() / 4));
|
||||
|
||||
assert(mLiterals.getFloatSize() % 4 == 0);
|
||||
code.push_back(static_cast<Interpreter::Type_Code>(mLiterals.getFloatSize() / 4));
|
||||
|
||||
assert(mLiterals.getStringSize() % 4 == 0);
|
||||
code.push_back(static_cast<Interpreter::Type_Code>(mLiterals.getStringSize() / 4));
|
||||
|
||||
// code
|
||||
std::copy(mCode.begin(), mCode.end(), std::back_inserter(code));
|
||||
|
||||
// literals
|
||||
mLiterals.append(code);
|
||||
return Interpreter::Program{
|
||||
.mInstructions = mCode,
|
||||
.mIntegers = mLiterals.getIntegers(),
|
||||
.mFloats = mLiterals.getFloats(),
|
||||
.mStrings = mLiterals.getStrings(),
|
||||
};
|
||||
}
|
||||
|
||||
const Literals& Output::getLiterals() const
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include <components/interpreter/program.hpp>
|
||||
#include <components/interpreter/types.hpp>
|
||||
|
||||
namespace Compiler
|
||||
|
@ -20,8 +21,7 @@ namespace Compiler
|
|||
public:
|
||||
Output(Locals& locals);
|
||||
|
||||
void getCode(std::vector<Interpreter::Type_Code>& code) const;
|
||||
///< store generated code in \a code.
|
||||
Interpreter::Program getProgram() const;
|
||||
|
||||
const Literals& getLiterals() const;
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ namespace Compiler
|
|||
{
|
||||
}
|
||||
|
||||
void ScriptParser::getCode(std::vector<Interpreter::Type_Code>& code) const
|
||||
Interpreter::Program ScriptParser::getProgram() const
|
||||
{
|
||||
mOutput.getCode(code);
|
||||
return mOutput.getProgram();
|
||||
}
|
||||
|
||||
bool ScriptParser::parseName(const std::string& name, const TokenLoc& loc, Scanner& scanner)
|
||||
|
|
|
@ -23,8 +23,7 @@ namespace Compiler
|
|||
/// \param end of script is marked by end keyword.
|
||||
ScriptParser(ErrorHandler& errorHandler, const Context& context, Locals& locals, bool end = false);
|
||||
|
||||
void getCode(std::vector<Interpreter::Type_Code>& code) const;
|
||||
///< store generated code in \a code.
|
||||
Interpreter::Program getProgram() const;
|
||||
|
||||
bool parseName(const std::string& name, const TokenLoc& loc, Scanner& scanner) override;
|
||||
///< Handle a name token.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue