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