Mercurial > projects > ddmd
annotate dmd/backend/glue.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | 1475fd394c9e |
children | cd48cb899aee |
rev | line source |
---|---|
0 | 1 module dmd.backend.glue; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Array; |
5 import dmd.Dsymbol; | |
6 import dmd.File; | |
7 import dmd.FileName; | |
8 import dmd.Library; | |
9 import dmd.OutBuffer; | |
10 import dmd.Module; | |
11 import dmd.Identifier; | |
12 import dmd.AssertExp; | |
13 import dmd.TOK; | |
14 import dmd.Global; | |
15 import dmd.Param; | |
16 import dmd.backend.Config; | |
17 import dmd.backend.Configv; | |
18 import dmd.backend.StringTab; | |
19 | |
20 import core.stdc.string; | |
21 | |
79 | 22 version (Windows) |
23 { | |
25 | 24 extern (C++) extern |
25 { | |
26 int go_flag(char* cp); | |
27 void util_set64(); | |
28 void util_set386(); | |
29 } | |
79 | 30 } |
31 else version (linux) | |
32 { | |
33 extern (C++) | |
25 | 34 { |
35 int go_flag(char* cp); | |
36 void util_set64(); | |
37 void util_set386(); | |
38 } | |
0 | 39 } |
79 | 40 else |
41 { | |
42 static assert(false, "fix this"); | |
43 } | |
0 | 44 |
34 | 45 import std.exception; |
0 | 46 import std.string; |
47 | |
48 struct Outbuffer | |
49 { | |
50 ubyte* buf; // the buffer itself | |
51 ubyte* pend; // pointer past the end of the buffer | |
52 ubyte* p; // current position in buffer | |
53 uint len; // size of buffer | |
54 uint inc; // default increment size | |
55 | |
56 this(uint inc) | |
57 { | |
58 assert(false); | |
59 } | |
178 | 60 |
0 | 61 ~this() |
62 { | |
63 } | |
178 | 64 |
0 | 65 void reset() |
66 { | |
67 assert(false); | |
68 } | |
69 | |
70 // Reserve nbytes in buffer | |
71 void reserve(uint nbytes) | |
72 { | |
73 assert(false); | |
74 } | |
75 | |
76 // Write n zeros; return pointer to start of zeros | |
77 void* writezeros(uint n) | |
78 { | |
79 assert(false); | |
80 } | |
81 | |
82 // Position buffer to accept the specified number of bytes at offset | |
83 int position(uint offset, uint nbytes); | |
84 | |
85 // Write an array to the buffer, no reserve check | |
86 void writen(const(void)* b, int len) | |
87 { | |
88 memcpy(p,b,len); | |
89 p += len; | |
90 } | |
91 | |
92 // Clear bytes, no reserve check | |
93 void clearn(int len) | |
94 { | |
95 int i; | |
96 for (i=0; i< len; i++) | |
97 *p++ = 0; | |
98 } | |
99 | |
100 // Write an array to the buffer. | |
101 void write(const void *b, int len) | |
102 { | |
103 assert(false); | |
104 } | |
105 | |
106 void write(Outbuffer* b) | |
107 { | |
108 write(b.buf, b.p - b.buf); | |
109 } | |
110 | |
111 /** | |
112 * Flushes the stream. This will write any buffered | |
113 * output bytes. | |
114 */ | |
115 void flush() { } | |
116 | |
117 /** | |
118 * Writes an 8 bit byte, no reserve check. | |
119 */ | |
120 void writeByten(char v) | |
121 { | |
122 *p++ = v; | |
123 } | |
124 | |
125 /** | |
126 * Writes an 8 bit byte. | |
127 */ | |
128 void writeByte(int v) | |
129 { | |
130 assert(false); | |
131 } | |
132 | |
133 /** | |
134 * Writes a 16 bit little-end short, no reserve check. | |
135 */ | |
136 void writeWordn(int v) | |
137 { | |
138 version (_WIN32) { | |
139 *cast(ushort*)p = cast(short)v; | |
140 } else { | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
141 assert(0, "Check this"); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
142 p[0] = cast(ubyte)v; |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
143 p[1] = cast(ubyte)(v >> 8); |
0 | 144 } |
145 p += 2; | |
146 } | |
147 | |
148 /** | |
149 * Writes a 16 bit little-end short. | |
150 */ | |
151 void writeWord(int v) | |
152 { | |
153 reserve(2); | |
154 writeWordn(v); | |
155 } | |
156 | |
157 /** | |
158 * Writes a 16 bit big-end short. | |
159 */ | |
160 void writeShort(int v) | |
161 { | |
162 if (pend - p < 2) | |
163 reserve(2); | |
164 | |
165 static if (false) { | |
166 p[0] = (cast(ubyte*)&v)[1]; | |
167 p[1] = v; | |
168 } else { | |
169 ubyte* q = p; | |
170 q[0] = cast(ubyte)(v >> 8); | |
171 q[1] = cast(ubyte)v; | |
172 } | |
173 p += 2; | |
174 } | |
175 | |
176 /** | |
177 * Writes a 16 bit char. | |
178 */ | |
179 void writeChar(int v) | |
180 { | |
181 writeShort(v); | |
182 } | |
183 | |
184 /** | |
185 * Writes a 32 bit int. | |
186 */ | |
187 void write32(long v) | |
188 { | |
189 assert(false); | |
190 } | |
191 | |
192 /** | |
193 * Writes a 64 bit long. | |
194 */ | |
195 ///#if __INTSIZE == 4 | |
196 void write64(long v) | |
197 { | |
198 assert(false); | |
199 } | |
200 ///#endif | |
201 | |
202 /** | |
203 * Writes a 32 bit float. | |
204 */ | |
205 void writeFloat(float v) | |
206 { | |
207 assert(false); | |
208 } | |
209 | |
210 /** | |
211 * Writes a 64 bit double. | |
212 */ | |
213 void writeDouble(double v) | |
214 { | |
215 assert(false); | |
216 } | |
217 | |
218 void write(const(char)* s) | |
219 { | |
220 assert(false); | |
221 } | |
222 | |
223 void write(const(ubyte)* s) | |
224 { | |
225 assert(false); | |
226 } | |
227 | |
228 void writeString(const(char)* s) | |
229 { | |
230 assert(false); | |
231 } | |
232 | |
233 void prependBytes(const(char)* s) | |
234 { | |
235 assert(false); | |
236 } | |
237 | |
238 void bracket(char c1, char c2) | |
239 { | |
240 assert(false); | |
241 } | |
242 | |
243 /** | |
244 * Returns the number of bytes written. | |
245 */ | |
246 int size() | |
247 { | |
248 return p - buf; | |
249 } | |
250 | |
251 char* toString() | |
252 { | |
253 assert(false); | |
254 } | |
178 | 255 |
0 | 256 void setsize(uint size) |
257 { | |
258 assert(false); | |
259 } | |
260 | |
261 void writesLEB128(long value) | |
262 { | |
263 assert(false); | |
264 } | |
178 | 265 |
0 | 266 void writeuLEB128(uint value) |
267 { | |
268 assert(false); | |
269 } | |
270 } | |
271 | |
272 /************************************** | |
273 * Append s to list of object files to generate later. | |
274 */ | |
178 | 275 |
0 | 276 void obj_append(Dsymbol s) |
277 { | |
176 | 278 global.obj_symbols_towrite.push(cast(void*)s); |
0 | 279 } |
280 | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
281 version (Bug4059) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
282 { |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
283 private extern (C) void _Z8obj_initP9OutbufferPKcS2_(Outbuffer* objbuf, const(char)* filename, const(char)* csegname); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
284 void obj_init(Outbuffer* objbuf, const(char)* filename, const(char)* csegname) { return _Z8obj_initP9OutbufferPKcS2_(objbuf, filename, csegname); } |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
285 } |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
286 else |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
287 { |
25 | 288 extern (C++) { |
178 | 289 void obj_init(Outbuffer* objbuf, const(char)* filename, const(char)* csegname); |
25 | 290 } |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
291 } |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
292 |
0 | 293 extern (C++) { |
294 void backend_init(); | |
295 void backend_term(); | |
296 void obj_term(); | |
297 void rtlsym_reset(); | |
298 void slist_reset(); | |
299 void el_reset(); | |
300 void cg87_reset(); | |
301 void out_reset(); | |
302 } | |
303 | |
304 void clearStringTab() | |
305 { | |
306 //printf("clearStringTab()\n"); | |
176 | 307 memset(global.stringTab.ptr, 0, global.stringTab.sizeof); |
308 global.stidx = 0; | |
0 | 309 |
165
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
140
diff
changeset
|
310 // assertexp_sfilename = null; |
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
140
diff
changeset
|
311 // assertexp_name = null; |
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
140
diff
changeset
|
312 // assertexp_mn = null; |
0 | 313 } |
314 | |
315 void obj_start(char *srcfile) | |
316 { | |
317 //printf("obj_start()\n"); | |
318 | |
319 out_config_init(); | |
320 | |
321 rtlsym_reset(); | |
322 slist_reset(); | |
323 clearStringTab(); | |
324 | |
176 | 325 obj_init(&global.objbuf, srcfile, null); |
0 | 326 |
327 el_reset(); | |
328 cg87_reset(); | |
329 out_reset(); | |
330 } | |
331 | |
332 void obj_end(Library library, File objfile) | |
333 { | |
334 obj_term(); | |
178 | 335 |
176 | 336 auto objbuf = &global.objbuf; |
0 | 337 |
338 if (library) | |
339 { | |
340 // Transfer image to library | |
341 library.addObject(objfile.name.toChars(), objbuf.buf, objbuf.p - objbuf.buf); | |
342 objbuf.buf = null; | |
343 } | |
344 else | |
345 { | |
346 // Transfer image to file | |
347 objfile.setbuffer(objbuf.buf, objbuf.p - objbuf.buf); | |
348 objbuf.buf = null; | |
349 | |
350 string p = FileName.path(objfile.name.toChars()); | |
351 FileName.ensurePathExists(p); | |
352 //mem.free(p); | |
353 | |
354 //printf("write obj %s\n", objfile.name.toChars()); | |
355 objfile.writev(); | |
356 } | |
357 | |
358 objbuf.pend = null; | |
359 objbuf.p = null; | |
360 objbuf.len = 0; | |
361 objbuf.inc = 0; | |
362 } | |
363 | |
364 void obj_write_deferred(Library library) | |
365 { | |
176 | 366 auto obj_symbols_towrite = global.obj_symbols_towrite; |
0 | 367 for (int i = 0; i < obj_symbols_towrite.dim; i++) |
178 | 368 { |
0 | 369 Dsymbol s = cast(Dsymbol)obj_symbols_towrite.data[i]; |
370 Module m = s.getModule(); | |
371 | |
372 string mname; | |
373 if (m) | |
178 | 374 { |
0 | 375 mname = m.srcfile.toChars(); |
176 | 376 global.lastmname = mname; |
0 | 377 } |
378 else | |
379 { | |
380 //mname = s->ident->toChars(); | |
176 | 381 mname = global.lastmname; |
0 | 382 assert(mname.length != 0); |
383 } | |
384 | |
385 obj_start(cast(char*)toStringz(mname)); | |
386 | |
176 | 387 int count = ++global.count; // sequence for generating names |
0 | 388 |
389 /* Create a module that's a doppelganger of m, with just | |
390 * enough to be able to create the moduleinfo. | |
391 */ | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
34
diff
changeset
|
392 auto idbuf = new OutBuffer(); |
0 | 393 idbuf.printf("%s.%d", m ? m.ident.toChars() : mname, count); |
394 string idstr = idbuf.extractString(); | |
395 idbuf.data = null; | |
396 Identifier id = new Identifier(idstr, TOK.TOKidentifier); | |
397 | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
34
diff
changeset
|
398 auto md = new Module(mname, id, 0, 0); |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
34
diff
changeset
|
399 md.members = new Dsymbols(); |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
34
diff
changeset
|
400 md.members.push(s); // its only 'member' is s |
0 | 401 if (m) |
402 { | |
403 md.doppelganger = 1; // identify this module as doppelganger | |
404 md.md = m.md; | |
405 md.aimports.push(cast(void*)m); // it only 'imports' m | |
406 md.massert = m.massert; | |
407 md.marray = m.marray; | |
408 } | |
409 | |
410 md.genobjfile(0); | |
411 | |
412 /* Set object file name to be source name with sequence number, | |
413 * as mangled symbol names get way too long. | |
414 */ | |
415 string fname = FileName.removeExt(mname); | |
178 | 416 |
0 | 417 OutBuffer namebuf = new OutBuffer(); |
418 uint hash = 0; | |
419 foreach (char c; s.toChars()) | |
420 hash += c; | |
421 | |
422 namebuf.printf("%s_%x_%x.%s", fname, count, hash, global.obj_ext); | |
423 fname = namebuf.extractString(); | |
424 | |
425 //printf("writing '%s'\n", fname); | |
426 File objfile = new File(fname); | |
427 obj_end(library, objfile); | |
428 } | |
429 | |
430 obj_symbols_towrite.dim = 0; | |
431 } | |
432 | |
433 /************************************** | |
434 * Initialize config variables. | |
435 */ | |
436 | |
437 void out_config_init() | |
438 { | |
439 Param* params = &global.params; | |
440 | |
441 if (!config.target_cpu) | |
442 { | |
443 config.target_cpu = TARGET_PentiumPro; | |
444 config.target_scheduler = config.target_cpu; | |
445 } | |
446 config.fulltypes = CVNONE; | |
447 config.inline8087 = 1; | |
448 config.memmodel = 0; | |
449 config.flags |= CFGuchar; // make sure TYchar is unsigned | |
450 version (TARGET_WINDOS) { | |
451 if (params.isX86_64) | |
452 config.exe = EX_WIN64; | |
453 else | |
454 config.exe = EX_NT; | |
455 | |
456 // Win32 eh | |
457 config.flags2 |= CFG2seh; | |
458 | |
459 if (params.run) | |
460 config.wflags |= WFexe; // EXE file only optimizations | |
461 else if (params.link && !global.params.deffile) | |
462 config.wflags |= WFexe; // EXE file only optimizations | |
463 else if (params.exefile) // if writing out EXE file | |
178 | 464 { |
0 | 465 size_t len = params.exefile.length; |
466 if (len >= 4 && icmp(params.exefile[len-3..len], "exe") == 0) | |
467 config.wflags |= WFexe; | |
468 } | |
469 config.flags4 |= CFG4underscore; | |
470 } | |
471 version (TARGET_LINUX) { | |
472 if (params.isX86_64) | |
473 config.exe = EX_LINUX64; | |
474 else | |
475 config.exe = EX_LINUX; | |
476 config.flags |= CFGnoebp; | |
477 config.flags |= CFGalwaysframe; | |
478 if (params.pic) | |
479 config.flags3 |= CFG3pic; | |
480 } | |
481 version (TARGET_OSX) { | |
482 if (params.isX86_64) | |
483 config.exe = EX_OSX64; | |
484 else | |
485 config.exe = EX_OSX; | |
486 config.flags |= CFGnoebp; | |
487 config.flags |= CFGalwaysframe; | |
488 if (params.pic) | |
489 config.flags3 |= CFG3pic; | |
490 } | |
491 version (TARGET_FREEBSD) { | |
492 if (params.isX86_64) | |
493 config.exe = EX_FREEBSD64; | |
494 else | |
495 config.exe = EX_FREEBSD; | |
496 config.flags |= CFGnoebp; | |
497 config.flags |= CFGalwaysframe; | |
498 if (params.pic) | |
499 config.flags3 |= CFG3pic; | |
500 } | |
501 version (TARGET_SOLARIS) { | |
502 if (params.isX86_64) | |
503 config.exe = EX_SOLARIS64; | |
504 else | |
505 config.exe = EX_SOLARIS; | |
506 config.flags |= CFGnoebp; | |
507 config.flags |= CFGalwaysframe; | |
508 if (params.pic) | |
509 config.flags3 |= CFG3pic; | |
510 } | |
511 config.flags2 |= CFG2nodeflib; // no default library | |
512 config.flags3 |= CFG3eseqds; | |
513 static if (false) { | |
514 if (env.getEEcontext().EEcompile != 2) | |
515 config.flags4 |= CFG4allcomdat; | |
516 if (env.nochecks()) | |
517 config.flags4 |= CFG4nochecks; // no runtime checking | |
518 } else version (TARGET_OSX) { | |
519 } else { | |
520 config.flags4 |= CFG4allcomdat; | |
521 } | |
522 if (params.trace) | |
523 config.flags |= CFGtrace; // turn on profiler | |
524 if (params.nofloat) | |
525 config.flags3 |= CFG3wkfloat; | |
526 | |
527 configv.verbose = params.verbose; | |
528 | |
529 if (params.optimize) | |
530 go_flag(cast(char*)"-o".ptr); | |
531 | |
532 if (params.symdebug) | |
533 { | |
534 version (ELFOBJ_OR_MACHOBJ) { | |
535 configv.addlinenumbers = 1; | |
536 config.fulltypes = (params.symdebug == 1) ? CVDWARF_D : CVDWARF_C; | |
537 } | |
538 version (OMFOBJ) { | |
539 configv.addlinenumbers = 1; | |
540 config.fulltypes = CV4; | |
541 } | |
542 if (!params.optimize) | |
543 config.flags |= CFGalwaysframe; | |
544 } | |
545 else | |
546 { | |
547 configv.addlinenumbers = 0; | |
548 config.fulltypes = CVNONE; | |
549 //config.flags &= ~CFGalwaysframe; | |
550 } | |
551 | |
552 if (params.isX86_64) | |
553 { | |
554 util_set64(); | |
555 cod3_set64(); | |
556 } | |
557 else | |
558 { | |
559 util_set386(); | |
560 cod3_set386(); | |
561 } | |
562 | |
563 debug { | |
564 debugb = params.debugb; | |
565 debugc = params.debugc; | |
566 debugf = params.debugf; | |
567 debugr = params.debugr; | |
568 debugw = params.debugw; | |
569 debugx = params.debugx; | |
570 debugy = params.debugy; | |
571 } | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
572 } |