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