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