134 // ==================================================================== |
136 // ==================================================================== |
135 // Merge another data buffer into this one. |
137 // Merge another data buffer into this one. |
136 void Merge (DataBuffer* other) { |
138 void Merge (DataBuffer* other) { |
137 if (!other) |
139 if (!other) |
138 return; |
140 return; |
|
141 int oldsize = writesize; |
139 |
142 |
140 for (unsigned int x = 0; x < other->writesize; x++) |
143 for (unsigned int x = 0; x < other->writesize; x++) |
141 Write<unsigned char> (*(other->buffer+x)); |
144 Write<byte> (*(other->buffer+x)); |
142 |
145 |
143 // Merge its marks and references |
146 // Merge its marks and references |
144 unsigned int u = 0; |
147 unsigned int u = 0; |
145 for (u = 0; u < MAX_MARKS; u++) { |
148 for (u = 0; u < MAX_MARKS; u++) { |
146 if (other->marks[u]) { |
149 if (other->marks[u]) { |
147 // Add the mark and offset its position. |
150 // Add the mark and offset its position. |
148 unsigned int u = AddMark (other->marks[u]->name); |
151 /* str name = other->marks[u]->name; |
149 marks[u]->pos += other->writesize; |
152 unsigned int x = AddMark (name); |
|
153 marks[x]->pos = other->marks[u]->pos + oldsize; |
|
154 */ |
|
155 |
|
156 if (marks[u]) |
|
157 error ("DataBuffer: duplicate mark %d!\n"); |
|
158 |
|
159 marks[u] = other->marks[u]; |
|
160 marks[u]->pos += oldsize; |
|
161 |
|
162 // The original mark becomes NULL so that the deconstructor |
|
163 // will not delete it prematurely. (should it delete any |
|
164 // marks in the first place since there is no such thing |
|
165 // as at temporary mark?) |
|
166 other->marks[u] = NULL; |
150 } |
167 } |
151 |
168 |
152 if (other->refs[u]) { |
169 if (other->refs[u]) { |
153 // Same for references |
170 // Same for references |
154 unsigned int r = AddMarkReference (other->refs[u]->num); |
171 unsigned int r = AddMarkReference (other->refs[u]->num, false); |
155 refs[r]->pos += other->writesize; |
172 refs[r]->pos = other->refs[u]->pos + oldsize; |
156 } |
173 } |
157 } |
174 } |
158 |
175 |
159 delete other; |
176 delete other; |
160 } |
177 } |
172 // position in the bytecode. The actual permanent position cannot |
189 // position in the bytecode. The actual permanent position cannot |
173 // be predicted in any way or form, thus these things will be used |
190 // be predicted in any way or form, thus these things will be used |
174 // to "mark" a position like that for future use. |
191 // to "mark" a position like that for future use. |
175 unsigned int AddMark (str name) { |
192 unsigned int AddMark (str name) { |
176 // Find a free slot for the mark |
193 // Find a free slot for the mark |
177 unsigned int u; |
194 unsigned int u = g_NextMark++; |
178 for (u = 0; u < MAX_MARKS; u++) |
195 |
179 if (!marks[u]) |
196 if (marks[u]) |
180 break; |
197 error ("DataBuffer: attempted to re-create mark %u!\n", u); |
181 |
198 |
182 if (u >= MAX_MARKS) |
199 if (u >= MAX_MARKS) |
183 error ("mark quota exceeded, all labels, if-structs and loops add marks\n"); |
200 error ("mark quota exceeded, all labels, if-structs and loops add marks\n"); |
184 |
201 |
185 ScriptMark* m = new ScriptMark; |
202 ScriptMark* m = new ScriptMark; |
191 |
208 |
192 // ==================================================================== |
209 // ==================================================================== |
193 // A ref is another "mark" that references a mark. When the bytecode |
210 // A ref is another "mark" that references a mark. When the bytecode |
194 // is written to file, they are changed into their marks' current |
211 // is written to file, they are changed into their marks' current |
195 // positions. Marks themselves are never written to files, only refs are |
212 // positions. Marks themselves are never written to files, only refs are |
196 unsigned int AddMarkReference (unsigned int marknum) { |
213 unsigned int AddMarkReference (unsigned int marknum, bool placeholder = true) { |
197 unsigned int u; |
214 unsigned int u; |
198 for (u = 0; u < MAX_MARKS; u++) |
215 for (u = 0; u < MAX_MARKS; u++) |
199 if (!refs[u]) |
216 if (!refs[u]) |
200 break; |
217 break; |
201 |
218 |