databuffer.h

changeset 48
976c57f153b3
parent 45
e1d3b7ea975c
child 49
8e2f7a031410
equal deleted inserted replaced
47:d84d82213137 48:976c57f153b3
44 #include <string.h> 44 #include <string.h>
45 #include "common.h" 45 #include "common.h"
46 46
47 #define MAX_MARKS 256 47 #define MAX_MARKS 256
48 48
49 extern int g_NextMark;
50
49 // ============================================================================ 51 // ============================================================================
50 // DataBuffer: A dynamic data buffer. 52 // DataBuffer: A dynamic data buffer.
51 class DataBuffer { 53 class DataBuffer {
52 public: 54 public:
53 // The actual buffer 55 // The actual buffer
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
210 r->num = marknum; 227 r->num = marknum;
211 r->pos = writesize; 228 r->pos = writesize;
212 refs[u] = r; 229 refs[u] = r;
213 230
214 // Write a dummy placeholder for the reference 231 // Write a dummy placeholder for the reference
215 Write<word> (1234); 232 if (placeholder)
233 Write<word> (1234);
216 234
217 return u; 235 return u;
218 } 236 }
219 237
220 // Delete a mark and all references to it. 238 // Delete a mark and all references to it.

mercurial