+void Compiler::Relocate(iostream &out) {
+ int bufferSize = TypeDescription::GetMaxSize();
+ char *buffer = new char[bufferSize];
+ for (;out && out.tellg() < fileHeader.objectsEnd;) {
+ Object object;
+ out.read(reinterpret_cast<char *>(&object), sizeof(Object));
+ const TypeDescription &td = TypeDescription::Get(object.typeId);
+ unsigned int pos = out.tellg();
+
+ out.read(buffer, object.size);
+ Relocate(pos, buffer, td);
+ out.seekp(pos);
+ out.write(buffer, object.size);
+ out.seekg(out.tellp());
+ }
+ delete[] buffer;
+ out.seekg(fileHeader.arraysBegin);
+ Array array;
+ for (; out && out.tellg() < fileHeader.arraysEnd;) {
+ out.read(reinterpret_cast<char *>(&array), sizeof(Array));
+ buffer = new char[array.size];
+ unsigned int pos = out.tellg();
+ out.read(buffer, array.size);
+ if (array.ref) {
+ RelocateArray(buffer, array.size);
+ } else {
+ const TypeDescription &td = TypeDescription::Get(array.typeId);
+ for (char *i = buffer, *end = buffer + array.size;
+ i < end; i += td.Size()) {
+ Relocate(pos + (i - buffer), i, td);
+ }
+ }
+ out.seekp(pos);
+ out.write(buffer, array.size);
+ 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) {
+ for (char *i = array, *end = array + size;
+ i < end; i += sizeof(void *)) {
+ char **dest = reinterpret_cast<char **>(i);
+ if (!*dest) {
+ continue;
+ }
+ map<const void *, unsigned int>::const_iterator
+ entry(addressMap.find(*dest));
+ if (entry == addressMap.end()) {
+ throw runtime_error("unable to relocate array member");
+ }
+ unsigned int destOffset = entry->second;
+ *dest = reinterpret_cast<char *>(destOffset);
+ }