X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Floader%2FCompiler.cpp;h=13f3dfc24ba0b1416ef87bfdd2976b9f9c8003dd;hb=abfa371d1d2c14052d4cbfc885b8383c6da7d499;hp=b2d23be9c5cb984ee969ae3402706fbe02cf6289;hpb=8ef435410d1f8aff339e4afef87a5757e77eba45;p=l2e.git diff --git a/src/loader/Compiler.cpp b/src/loader/Compiler.cpp index b2d23be..13f3dfc 100644 --- a/src/loader/Compiler.cpp +++ b/src/loader/Compiler.cpp @@ -2,6 +2,7 @@ #include "Interpreter.h" #include "TypeDescription.h" +#include "../common/Script.h" #include #include @@ -18,6 +19,7 @@ using std::iostream; using std::make_pair; using std::map; using std::ostream; +using std::pair; using std::runtime_error; using std::set; using std::string; @@ -51,6 +53,9 @@ void Compiler::Write(iostream &out) { fileHeader.arraysBegin = out.tellp(); WriteArrays(out); fileHeader.arraysEnd = out.tellp(); + fileHeader.scriptsBegin = out.tellp(); + WriteScripts(out); + fileHeader.scriptsEnd = out.tellp(); out.seekp(0); WriteHeader(out); WriteExports(out); @@ -148,6 +153,11 @@ void Compiler::WriteObjects(ostream &out) { Write(out, &object, sizeof(Object)); addressMap.insert(make_pair(*j, out.tellp())); Write(out, *j, object.size); + + if (td.TypeId() == Interpreter::SCRIPT_ID) { + common::Script *script = reinterpret_cast(*j); + scripts.push_back(make_pair(const_cast(script->text), script->textlen)); + } } } } @@ -180,6 +190,18 @@ void Compiler::WriteImages(ostream &out) { } } +void Compiler::WriteScripts(ostream &out) { + for (vector >::const_iterator + i(scripts.begin()), end(scripts.end()); + i != end; ++i) { + Script s; + s.size = i->second; + Write(out, &s, sizeof(Script)); + addressMap.insert(make_pair(i->first, out.tellp())); + Write(out, i->first, s.size); + } +} + void Compiler::PrepareExport(Export &exp, const string &str) { const Interpreter::ParsedDefinition &dfn @@ -253,6 +275,18 @@ void Compiler::Relocate(iostream &out) { out.seekg(out.tellp()); delete[] buffer; } + Script script; + for (; out && out.tellg() < fileHeader.scriptsEnd;) { + out.read(reinterpret_cast(&script), sizeof(Script)); + buffer = new char[script.size]; + unsigned int pos = out.tellg(); + out.read(buffer, script.size); + RelocateScript(buffer, script.size); + out.seekp(pos); + out.write(buffer, script.size); + out.seekg(out.tellp()); + delete[] buffer; + } } void Compiler::RelocateArray(char *array, int size) { @@ -306,6 +340,38 @@ void Compiler::Relocate( } } +void Compiler::RelocateScript(char *text, unsigned int textlen) { + for (char *i = text, *end = text + textlen; i < end;) { + common::Script::Code *code = + reinterpret_cast(i); + if (code->type == common::Script::TYPE_ADDRESS && code->numParams > 0) { + if (code->reg1 == 7) { + char *addr = i + sizeof(common::Script::Code); + std::map::const_iterator + found(addressMap.find(*reinterpret_cast(addr))); + if (found == addressMap.end()) { + throw std::runtime_error("unable to relocate script code"); + } + *reinterpret_cast(addr) = found->second; + } + + if (code->numParams > 1 && code->reg2 == 7) { + char *addr = i + sizeof(common::Script::Code); + if (code->reg1 == 7) { + addr += sizeof(void *); + } + std::map::const_iterator + found(addressMap.find(*reinterpret_cast(addr))); + if (found == addressMap.end()) { + throw std::runtime_error("unable to relocate script code"); + } + *reinterpret_cast(addr) = found->second; + } + } + i += code->Size(); + } +} + void Compiler::Write(ostream &out, const void *data, int amount) { out.write(reinterpret_cast(data), amount);