#include "Interpreter.h"
#include "TypeDescription.h"
+#include "../common/Script.h"
#include <climits>
#include <cstring>
using std::make_pair;
using std::map;
using std::ostream;
+using std::pair;
using std::runtime_error;
using std::set;
using std::string;
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);
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<common::Script *>(*j);
+ scripts.push_back(make_pair(const_cast<char *>(script->text), script->textlen));
+ }
}
}
}
}
}
+void Compiler::WriteScripts(ostream &out) {
+ for (vector<pair<const char *, unsigned int> >::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
out.seekg(out.tellp());
delete[] buffer;
}
+ Script script;
+ for (; out && out.tellg() < fileHeader.scriptsEnd;) {
+ out.read(reinterpret_cast<char *>(&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) {
}
}
+void Compiler::RelocateScript(char *text, unsigned int textlen) {
+ for (char *i = text, *end = text + textlen; i < end;) {
+ common::Script::Code *code =
+ reinterpret_cast<common::Script::Code *>(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 void *, unsigned int>::const_iterator
+ found(addressMap.find(*reinterpret_cast<void **>(addr)));
+ if (found == addressMap.end()) {
+ throw std::runtime_error("unable to relocate script code");
+ }
+ *reinterpret_cast<unsigned int *>(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 void *, unsigned int>::const_iterator
+ found(addressMap.find(*reinterpret_cast<void **>(addr)));
+ if (found == addressMap.end()) {
+ throw std::runtime_error("unable to relocate script code");
+ }
+ *reinterpret_cast<unsigned int *>(addr) = found->second;
+ }
+ }
+ i += code->Size();
+ }
+}
+
void Compiler::Write(ostream &out, const void *data, int amount) {
out.write(reinterpret_cast<const char *>(data), amount);