4 * Created on: Sep 11, 2012
10 #include "Interpreter.h"
28 Compiler::Compiler(const Interpreter &intp)
31 int headerSize(sizeof(ObjectFileHeader) + (intp.Values().size() * sizeof(TypeOffset)));
33 fileHeader.exportsBegin = headerSize + Remaining(headerSize, 16);
34 fileHeader.exportsEnd = fileHeader.exportsBegin + (intp.ExportedIdentifiers().size() * sizeof(Export));
36 fileHeader.externalsBegin = fileHeader.exportsEnd + Remaining(fileHeader.exportsEnd, 16);
37 fileHeader.externalsEnd = fileHeader.externalsBegin + (intp.PostponedDefinitions().size() * sizeof(External));
39 fileHeader.exportStringsBegin = fileHeader.externalsEnd + Remaining(fileHeader.externalsEnd, 16);
40 fileHeader.exportStringsEnd = fileHeader.exportStringsBegin;
41 for (set<string>::const_iterator i(intp.ExportedIdentifiers().begin()), end(intp.ExportedIdentifiers().end()); i != end; ++i) {
42 fileHeader.exportStringsEnd += i->size() + 1;
45 fileHeader.externalStringsBegin = fileHeader.exportStringsEnd + Remaining(fileHeader.exportStringsEnd, 16);
46 fileHeader.externalStringsEnd = fileHeader.externalStringsBegin;
47 for(vector<Interpreter::PostponedDefinition>::const_iterator i(intp.PostponedDefinitions().begin()), end(intp.PostponedDefinitions().end()); i != end; ++i) {
48 fileHeader.externalStringsEnd += std::strlen(i->identifier) + 1;
51 fileHeader.imagesBegin = fileHeader.externalStringsEnd + Remaining(fileHeader.externalStringsEnd, 16);
52 fileHeader.imagesEnd = fileHeader.imagesBegin + (intp.Images().size() * sizeof(ImageProperties));
53 for (map<string, SDL_Surface *>::const_iterator i(intp.Images().begin()), end(intp.Images().end()); i != end; ++i) {
54 fileHeader.imagesEnd += i->second->w * i->second->h * i->second->format->BytesPerPixel;
57 fileHeader.objectsBegin = fileHeader.imagesEnd + Remaining(fileHeader.imagesEnd, 16);
58 fileHeader.objectsEnd = fileHeader.objectsBegin;
59 for (map<int, vector<void *> >::const_iterator i(intp.Values().begin()), end(intp.Values().end()); i != end; ++i) {
60 const TypeDescription &td(TypeDescription::Get(i->first));
61 objectOffsets[i->first] = fileHeader.objectsEnd;
62 fileHeader.objectsEnd += td.Size() * i->second.size();
63 fileHeader.objectsEnd += Remaining(fileHeader.objectsEnd, 16);
67 void Compiler::Write(ostream &out) {
74 WriteExportStrings(out);
76 WriteExternalStrings(out);
84 void Compiler::WriteHeader(ostream &out) {
85 Write(out, reinterpret_cast<const char *>(&fileHeader), sizeof(ObjectFileHeader));
86 for(map<int, vector<void *> >::const_iterator i(intp.Values().begin()), end(intp.Values().end()); i != end; ++i) {
89 to.begin = GetTypeOffset(i->first);
90 to.end = to.begin + (i->second.size() * TypeDescription::Get(i->first).Size());
91 Write(out, reinterpret_cast<const char *>(&to), sizeof(TypeOffset));
97 Write(out, reinterpret_cast<const char *>(&to), sizeof(TypeOffset));
100 void Compiler::WriteExports(ostream &out) {
101 int nameOffset(fileHeader.externalStringsBegin);
102 for (set<string>::const_iterator i(intp.ExportedIdentifiers().begin()), end(intp.ExportedIdentifiers().end()); i != end; ++i) {
103 const Interpreter::ParsedDefinition &dfn(intp.GetDefinition(*i));
105 exp.nameOffset = nameOffset;
106 exp.typeId = dfn.type;
107 exp.dataOffset = ObjectOffset(dfn.type, dfn.id);
108 Write(out, reinterpret_cast<char *>(&exp), sizeof(Export));
109 nameOffset += i->size() + 1;
113 void Compiler::WriteExternals(ostream &out) {
114 int nameOffset(fileHeader.exportStringsBegin);
115 for(vector<Interpreter::PostponedDefinition>::const_iterator i(intp.PostponedDefinitions().begin()), end(intp.PostponedDefinitions().end()); i != end; ++i) {
117 ext.nameOffset = nameOffset;
118 ext.referenceOffset = ReferenceOffset(i->type, i->id, i->offset);
119 ext.inlined = i->inlined ? 1 : 0;
120 Write(out, reinterpret_cast<char *>(&ext), sizeof(External));
121 nameOffset += std::strlen(i->identifier) + 1;
125 void Compiler::WriteExportStrings(ostream &out) {
126 for (set<string>::const_iterator i(intp.ExportedIdentifiers().begin()), end(intp.ExportedIdentifiers().end()); i != end; ++i) {
127 Write(out, i->c_str(), i->size() + 1);
131 void Compiler::WriteExternalStrings(ostream &out) {
132 for(vector<Interpreter::PostponedDefinition>::const_iterator i(intp.PostponedDefinitions().begin()), end(intp.PostponedDefinitions().end()); i != end; ++i) {
133 Write(out, i->identifier, std::strlen(i->identifier) + 1);
137 void Compiler::WriteImages(ostream &out) {
138 for (map<string, SDL_Surface *>::const_iterator i(intp.Images().begin()), end(intp.Images().end()); i != end; ++i) {
140 ip.flags = i->second->flags;
141 ip.width = i->second->w;
142 ip.height = i->second->h;
143 ip.depth = i->second->format->BitsPerPixel;
144 ip.pitch = i->second->pitch;
145 ip.rmask = i->second->format->Rmask;
146 ip.gmask = i->second->format->Gmask;
147 ip.bmask = i->second->format->Bmask;
148 ip.amask = i->second->format->Amask;
149 Write(out, reinterpret_cast<char *>(&ip), sizeof(ImageProperties));
150 SDL_LockSurface(i->second);
151 Write(out, reinterpret_cast<char *>(i->second->pixels), ip.width * ip.height * (ip.depth / CHAR_BIT + (ip.depth % CHAR_BIT ? 1 : 0)));
152 // TODO: store palette too?
153 SDL_UnlockSurface(i->second);
157 void Compiler::WriteObjects(ostream &out) {
158 for (map<int, vector<void *> >::const_iterator i(intp.Values().begin()), end(intp.Values().end()); i != end; ++i) {
159 const TypeDescription &td(TypeDescription::Get(i->first));
160 for (vector<void *>::const_iterator j(i->second.begin()), jend(i->second.end()); j != jend; ++j) {
161 Write(out, reinterpret_cast<char *>(*j), td.Size());
168 void Compiler::Write(ostream &out, const char *data, int amount) {
169 out.write(data, amount);
173 void Compiler::Pad(ostream &out, int to) {
174 for (int remaining(Remaining(cursor, to)); remaining > 0; --remaining) {
180 int Compiler::Remaining(int value, int alignment) {
181 int have(value % alignment);
182 return (have > 0) ? (16 - have) : 0;
186 int Compiler::ReferenceOffset(int typeId, int objectId, std::ptrdiff_t fieldOffset) const {
187 return ObjectOffset(typeId, objectId) + fieldOffset;
190 int Compiler::ObjectOffset(int typeId, int objectId) const {
191 const TypeDescription &td(TypeDescription::Get(typeId));
192 return GetTypeOffset(typeId) + (td.Size() * objectId);
195 int Compiler::GetTypeOffset(int typeId) const {
196 return objectOffsets.at(typeId);