comparison runtime/ldc2.diff @ 763:9a9f403ab399

D2 changes! Removed druntime from the repository again.. Sorry :/ Updated the druntime port a bit, now requires druntime from trunk. Added info in runtime/README on how to get druntime from trunk. Added patch to add LDC support to druntime. Removed some debug logging from D2 builds. Fixed broken typeinfo for const/invariant in D2.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 12 Nov 2008 07:22:05 +0100
parents
children af04bbae8553
comparison
equal deleted inserted replaced
762:d7aae6f09754 763:9a9f403ab399
1 Index: src/common/core/bitmanip.d
2 ===================================================================
3 --- src/common/core/bitmanip.d (revision 46)
4 +++ src/common/core/bitmanip.d (working copy)
5 @@ -171,6 +171,10 @@
6 */
7 uint outpl( uint port_address, uint value );
8 }
9 +else version( LDC )
10 +{
11 + public import ldc.bitmanip;
12 +}
13 else
14 {
15 public import std.intrinsic;
16 Index: src/common/core/thread.d
17 ===================================================================
18 --- src/common/core/thread.d (revision 46)
19 +++ src/common/core/thread.d (working copy)
20 @@ -275,8 +275,50 @@
21 }
22 body
23 {
24 - version( D_InlineAsm_X86 )
25 + version( LDC )
26 {
27 + version(X86)
28 + {
29 + uint eax,ecx,edx,ebx,ebp,esi,edi;
30 + asm
31 + {
32 + mov eax[EBP], EAX ;
33 + mov ecx[EBP], ECX ;
34 + mov edx[EBP], EDX ;
35 + mov ebx[EBP], EBX ;
36 + mov ebp[EBP], EBP ;
37 + mov esi[EBP], ESI ;
38 + mov edi[EBP], EDI ;
39 + }
40 + }
41 + else version (X86_64)
42 + {
43 + ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r10,r11,r12,r13,r14,r15;
44 + asm
45 + {
46 + movq rax[RBP], RAX ;
47 + movq rbx[RBP], RBX ;
48 + movq rcx[RBP], RCX ;
49 + movq rdx[RBP], RDX ;
50 + movq rbp[RBP], RBP ;
51 + movq rsi[RBP], RSI ;
52 + movq rdi[RBP], RDI ;
53 + movq rsp[RBP], RSP ;
54 + movq r10[RBP], R10 ;
55 + movq r11[RBP], R11 ;
56 + movq r12[RBP], R12 ;
57 + movq r13[RBP], R13 ;
58 + movq r14[RBP], R14 ;
59 + movq r15[RBP], R15 ;
60 + }
61 + }
62 + else
63 + {
64 + static assert( false, "Architecture not supported." );
65 + }
66 + }
67 + else version( D_InlineAsm_X86 )
68 + {
69 asm
70 {
71 pushad;
72 @@ -328,8 +370,12 @@
73 }
74 }
75
76 - version( D_InlineAsm_X86 )
77 + version( LDC )
78 {
79 + // nothing to pop
80 + }
81 + else version( D_InlineAsm_X86 )
82 + {
83 asm
84 {
85 popad;
86 @@ -2259,6 +2305,18 @@
87 version = AsmPPC_Posix;
88 }
89
90 + version( LLVM_InlineAsm_X86 )
91 + {
92 + version( Win32 )
93 + version = LLVM_AsmX86_Win32;
94 + else version( Posix )
95 + version = LLVM_AsmX86_Posix;
96 + }
97 + else version( LLVM_InlineAsm_X86_64 )
98 + {
99 + version( Posix )
100 + version = LLVM_AsmX86_64_Posix;
101 + }
102
103 version( Posix )
104 {
105 @@ -2269,6 +2327,10 @@
106 version( AsmX86_Win32 ) {} else
107 version( AsmX86_Posix ) {} else
108 version( AsmPPC_Posix ) {} else
109 + version( LLVM_AsmX86_Win32 ) {} else
110 + version( LLVM_AsmX86_Posix ) {} else
111 + //TODO: Enable when x86-64 Posix supports fibers
112 + //version( LLVM_AsmX86_64_Posix ) {} else
113 {
114 // NOTE: The ucontext implementation requires architecture specific
115 // data definitions to operate so testing for it must be done
116 @@ -2423,6 +2485,28 @@
117 ret;
118 }
119 }
120 + else version( LLVM_AsmX86_Posix )
121 + {
122 + asm
123 + {
124 + // clobber registers to save
125 + inc EBX;
126 + inc ESI;
127 + inc EDI;
128 +
129 + // store oldp again with more acc
130 + mov EAX, oldp;
131 + mov [EAX], ESP;
132 + // load newp to begin context swi
133 + mov ESP, newp;
134 + }
135 + }
136 +/+
137 + version( LLVM_AsmX86_64_Posix )
138 + {
139 + //TODO: Fiber implementation here
140 + }
141 ++/
142 else static if( is( ucontext_t ) )
143 {
144 Fiber cfib = Fiber.getThis();
145 @@ -3088,6 +3172,22 @@
146 push( 0x00000000 ); // ESI
147 push( 0x00000000 ); // EDI
148 }
149 + else version( LLVM_AsmX86_Posix )
150 + {
151 + push( cast(size_t) &fiber_entryPoint ); // EIP
152 + push( 0x00000000 ); // newp
153 + push( 0x00000000 ); // oldp
154 + push( 0x00000000 ); // EBP
155 + push( 0x00000000 ); // EBX
156 + push( 0x00000000 ); // ESI
157 + push( 0x00000000 ); // EDI
158 + }
159 +//TODO: Implement x86-64 fibers
160 +/+
161 + else version( LLVM_AsmX86_Posix )
162 + {
163 + }
164 ++/
165 else version( AsmPPC_Posix )
166 {
167 version( StackGrowsDown )
168 Index: src/common/ldc.mak
169 ===================================================================
170 --- src/common/ldc.mak (revision 0)
171 +++ src/common/ldc.mak (revision 0)
172 @@ -0,0 +1,139 @@
173 +# Makefile to build the D runtime library core components for Posix
174 +# Designed to work with GNU make
175 +# Targets:
176 +# make
177 +# Same as make all
178 +# make lib
179 +# Build the common library
180 +# make doc
181 +# Generate documentation
182 +# make clean
183 +# Delete unneeded files created by build process
184 +
185 +LIB_TARGET=libdruntime-core.a
186 +LIB_MASK=libdruntime-core*.a
187 +
188 +CP=cp -f
189 +RM=rm -f
190 +MD=mkdir -p
191 +
192 +ADD_CFLAGS=
193 +ADD_DFLAGS=
194 +
195 +CFLAGS=-O $(ADD_CFLAGS)
196 +#CFLAGS=-g $(ADD_CFLAGS)
197 +
198 +DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
199 +#DFLAGS=-g -w $(ADD_DFLAGS)
200 +
201 +TFLAGS=-O -inline -w $(ADD_DFLAGS)
202 +#TFLAGS=-g -w $(ADD_DFLAGS)
203 +
204 +DOCFLAGS=-version=DDoc
205 +
206 +CC=gcc
207 +LC=$(AR) -qsv
208 +DC=ldc2
209 +
210 +INC_DEST=../../import
211 +LIB_DEST=../../lib
212 +DOC_DEST=../../doc
213 +
214 +.SUFFIXES: .s .S .c .cpp .d .html .o
215 +
216 +.s.o:
217 + $(CC) -c $(CFLAGS) $< -o$@
218 +
219 +.S.o:
220 + $(CC) -c $(CFLAGS) $< -o$@
221 +
222 +.c.o:
223 + $(CC) -c $(CFLAGS) $< -o$@
224 +
225 +.cpp.o:
226 + g++ -c $(CFLAGS) $< -o$@
227 +
228 +.d.o:
229 + $(DC) -c $(DFLAGS) -Hf$*.di $< -of$@
230 +# $(DC) -c $(DFLAGS) $< -of$@
231 +
232 +.d.html:
233 + $(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
234 +
235 +targets : lib doc
236 +all : lib doc
237 +core : lib
238 +lib : core.lib
239 +doc : core.doc
240 +
241 +######################################################
242 +
243 +OBJ_CORE= \
244 + core/bitmanip.o \
245 + core/exception.o \
246 + core/memory_.o \
247 + core/runtime.o \
248 + core/thread.o
249 +
250 +OBJ_STDC= \
251 + core/stdc/errno.o
252 +
253 +ALL_OBJS= \
254 + $(OBJ_CORE) \
255 + $(OBJ_STDC)
256 +
257 +######################################################
258 +
259 +DOC_CORE= \
260 + core/bitmanip.html \
261 + core/exception.html \
262 + core/memory.html \
263 + core/runtime.html \
264 + core/thread.html
265 +
266 +
267 +ALL_DOCS=
268 +
269 +######################################################
270 +
271 +core.lib : $(LIB_TARGET)
272 +
273 +$(LIB_TARGET) : $(ALL_OBJS)
274 + $(RM) $@
275 + $(LC) $@ $(ALL_OBJS)
276 +
277 +core.doc : $(ALL_DOCS)
278 + echo Documentation generated.
279 +
280 +######################################################
281 +
282 +### bitmanip
283 +
284 +core/bitmanip.o : core/bitmanip.d
285 + $(DC) -c $(DFLAGS) core/bitmanip.d -of$@
286 +
287 +### memory
288 +
289 +core/memory_.o : core/memory.d
290 + $(DC) -c $(DFLAGS) -Hf$*.di $< -of$@
291 +
292 +### thread
293 +
294 +core/thread.o : core/thread.d
295 + $(DC) -c $(DFLAGS) -d -Hf$*.di core/thread.d -of$@
296 +
297 +######################################################
298 +
299 +clean :
300 + find . -name "*.di" | xargs $(RM)
301 + $(RM) $(ALL_OBJS)
302 + $(RM) $(ALL_DOCS)
303 + find . -name "$(LIB_MASK)" | xargs $(RM)
304 +
305 +install :
306 + $(MD) $(INC_DEST)
307 + find . -name "*.di" -exec cp -f {} $(INC_DEST)/{} \;
308 + $(MD) $(DOC_DEST)
309 + find . -name "*.html" -exec cp -f {} $(DOC_DEST)/{} \;
310 + $(MD) $(LIB_DEST)
311 + find . -name "$(LIB_MASK)" -exec cp -f {} $(LIB_DEST)/{} \;
312 Index: src/ldc2.conf
313 ===================================================================
314 --- src/ldc2.conf (revision 0)
315 +++ src/ldc2.conf (revision 0)
316 @@ -0,0 +1,2 @@
317 +[Environment]
318 +DFLAGS="-I%HOME%/common" "-I%HOME%/../import"
319 Index: src/build-ldc.sh
320 ===================================================================
321 --- src/build-ldc.sh (revision 0)
322 +++ src/build-ldc.sh (revision 0)
323 @@ -0,0 +1,19 @@
324 +#!/usr/bin/env bash
325 +
326 +OLDHOME=$HOME
327 +export HOME=`pwd`
328 +
329 +goerror(){
330 + export HOME=$OLDHOME
331 + echo "="
332 + echo "= *** Error ***"
333 + echo "="
334 + exit 1
335 +}
336 +
337 +make clean -fldc.mak || goerror
338 +make lib doc install -fldc.mak || goerror
339 +make clean -fldc.mak || goerror
340 +chmod 644 ../import/*.di || goerror
341 +
342 +export HOME=$OLDHOME
343 Index: src/gc/basic/gcx.d
344 ===================================================================
345 --- src/gc/basic/gcx.d (revision 46)
346 +++ src/gc/basic/gcx.d (working copy)
347 @@ -66,6 +66,12 @@
348 private import gcc.builtins; // for __builtin_unwind_init
349 }
350
351 +struct BlkInfo
352 +{
353 + void* base;
354 + size_t size;
355 + uint attr;
356 +}
357
358 private
359 {
360 @@ -77,13 +83,6 @@
361 ALL_BITS = 0b1111_1111
362 }
363
364 - struct BlkInfo
365 - {
366 - void* base;
367 - size_t size;
368 - uint attr;
369 - }
370 -
371 extern (C) void* rt_stackBottom();
372 extern (C) void* rt_stackTop();
373
374 @@ -1468,7 +1467,7 @@
375 void initialize()
376 { int dummy;
377
378 - (cast(byte*)&this)[0 .. Gcx.sizeof] = 0;
379 + (cast(byte*)this)[0 .. Gcx.sizeof] = 0;
380 stackBottom = cast(char*)&dummy;
381 log_init();
382 debug (THREADINVARIANT)
383 Index: src/gc/basic/ldc.mak
384 ===================================================================
385 --- src/gc/basic/ldc.mak (revision 0)
386 +++ src/gc/basic/ldc.mak (revision 0)
387 @@ -0,0 +1,100 @@
388 +# Makefile to build the garbage collector D library for Posix
389 +# Designed to work with GNU make
390 +# Targets:
391 +# make
392 +# Same as make all
393 +# make lib
394 +# Build the garbage collector library
395 +# make doc
396 +# Generate documentation
397 +# make clean
398 +# Delete unneeded files created by build process
399 +
400 +LIB_TARGET=libdruntime-gc-basic.a
401 +LIB_MASK=libdruntime-gc-basic*.a
402 +
403 +CP=cp -f
404 +RM=rm -f
405 +MD=mkdir -p
406 +
407 +ADD_CFLAGS=
408 +ADD_DFLAGS=
409 +
410 +CFLAGS=-O $(ADD_CFLAGS)
411 +#CFLAGS=-g $(ADD_CFLAGS)
412 +
413 +DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
414 +#DFLAGS=-g -w $(ADD_DFLAGS)
415 +
416 +TFLAGS=-O -inline -w $(ADD_DFLAGS)
417 +#TFLAGS=-g -w $(ADD_DFLAGS)
418 +
419 +DOCFLAGS=-version=DDoc
420 +
421 +CC=gcc
422 +LC=$(AR) -qsv
423 +DC=ldc2
424 +
425 +LIB_DEST=../../../lib
426 +
427 +.SUFFIXES: .s .S .c .cpp .d .html .o
428 +
429 +.s.o:
430 + $(CC) -c $(CFLAGS) $< -o$@
431 +
432 +.S.o:
433 + $(CC) -c $(CFLAGS) $< -o$@
434 +
435 +.c.o:
436 + $(CC) -c $(CFLAGS) $< -o$@
437 +
438 +.cpp.o:
439 + g++ -c $(CFLAGS) $< -o$@
440 +
441 +.d.o:
442 + $(DC) -c $(DFLAGS) $< -of$@
443 +
444 +.d.html:
445 + $(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
446 +# $(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
447 +
448 +targets : lib doc
449 +all : lib doc
450 +lib : basic.lib
451 +doc : basic.doc
452 +
453 +######################################################
454 +
455 +ALL_OBJS= \
456 + gc.o \
457 + gcalloc.o \
458 + gcbits.o \
459 + gcstats.o \
460 + gcx.o
461 +
462 +######################################################
463 +
464 +ALL_DOCS=
465 +
466 +######################################################
467 +
468 +basic.lib : $(LIB_TARGET)
469 +
470 +$(LIB_TARGET) : $(ALL_OBJS)
471 + $(RM) $@
472 + $(LC) $@ $(ALL_OBJS)
473 +
474 +basic.doc : $(ALL_DOCS)
475 + echo No documentation available.
476 +
477 +######################################################
478 +
479 +clean :
480 + find . -name "*.di" | xargs $(RM)
481 + $(RM) $(ALL_OBJS)
482 + $(RM) $(ALL_DOCS)
483 + $(RM) $(LIB_MASK)
484 +
485 +install :
486 + $(MD) $(LIB_DEST)
487 + $(CP) $(LIB_MASK) $(LIB_DEST)/.
488 Index: src/gc/stub/ldc.mak
489 ===================================================================
490 --- src/gc/stub/ldc.mak (revision 0)
491 +++ src/gc/stub/ldc.mak (revision 0)
492 @@ -0,0 +1,98 @@
493 +# Makefile to build the garbage collector D library for Posix
494 +# Designed to work with GNU make
495 +# Targets:
496 +# make
497 +# Same as make all
498 +# make lib
499 +# Build the garbage collector library
500 +# make doc
501 +# Generate documentation
502 +# make clean
503 +# Delete unneeded files created by build process
504 +
505 +LIB_TARGET=druntime-gc-stub.a
506 +LIB_MASK=druntime-gc-stub*.a
507 +
508 +CP=cp -f
509 +RM=rm -f
510 +MD=mkdir -p
511 +
512 +ADD_CFLAGS=
513 +ADD_DFLAGS=
514 +
515 +CFLAGS=-O -m32 $(ADD_CFLAGS)
516 +#CFLAGS=-g -m32 $(ADD_CFLAGS)
517 +
518 +### warnings disabled because gcx has issues ###
519 +
520 +DFLAGS=-release -O -inline $(ADD_DFLAGS)
521 +#DFLAGS=-g $(ADD_DFLAGS)
522 +
523 +TFLAGS=-O -inline $(ADD_DFLAGS)
524 +#TFLAGS=-g $(ADD_DFLAGS)
525 +
526 +DOCFLAGS=-version=DDoc
527 +
528 +CC=gcc
529 +LC=$(AR) -qsv
530 +DC=ldc2
531 +
532 +LIB_DEST=..
533 +
534 +.SUFFIXES: .s .S .c .cpp .d .html .o
535 +
536 +.s.o:
537 + $(CC) -c $(CFLAGS) $< -o$@
538 +
539 +.S.o:
540 + $(CC) -c $(CFLAGS) $< -o$@
541 +
542 +.c.o:
543 + $(CC) -c $(CFLAGS) $< -o$@
544 +
545 +.cpp.o:
546 + g++ -c $(CFLAGS) $< -o$@
547 +
548 +.d.o:
549 + $(DC) -c $(DFLAGS) $< -of$@
550 +
551 +.d.html:
552 + $(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
553 +# $(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
554 +
555 +targets : lib doc
556 +all : lib doc
557 +lib : stub.lib
558 +doc : stub.doc
559 +
560 +######################################################
561 +
562 +ALL_OBJS= \
563 + gc.o
564 +
565 +######################################################
566 +
567 +ALL_DOCS=
568 +
569 +######################################################
570 +
571 +stub.lib : $(LIB_TARGET)
572 +
573 +$(LIB_TARGET) : $(ALL_OBJS)
574 + $(RM) $@
575 + $(LC) $@ $(ALL_OBJS)
576 +
577 +stub.doc : $(ALL_DOCS)
578 + echo No documentation available.
579 +
580 +######################################################
581 +
582 +clean :
583 + find . -name "*.di" | xargs $(RM)
584 + $(RM) $(ALL_OBJS)
585 + $(RM) $(ALL_DOCS)
586 + $(RM) $(LIB_MASK)
587 +
588 +install :
589 + $(MD) $(LIB_DEST)
590 + $(CP) $(LIB_MASK) $(LIB_DEST)/.
591 Index: src/ldc.mak
592 ===================================================================
593 --- src/ldc.mak (revision 0)
594 +++ src/ldc.mak (revision 0)
595 @@ -0,0 +1,78 @@
596 +# Makefile to build the composite D runtime library for Linux
597 +# Designed to work with GNU make
598 +# Targets:
599 +# make
600 +# Same as make all
601 +# make lib
602 +# Build the runtime library
603 +# make doc
604 +# Generate documentation
605 +# make clean
606 +# Delete unneeded files created by build process
607 +
608 +LIB_TARGET=libdruntime-ldc.a
609 +DUP_TARGET=libdruntime.a
610 +LIB_MASK=libdruntime*.a
611 +
612 +DIR_RT=compiler/ldc
613 +DIR_CC=common
614 +DIR_GC=gc/basic
615 +
616 +CP=cp -f
617 +RM=rm -f
618 +MD=mkdir -p
619 +
620 +CC=gcc
621 +LC=$(AR) -qsv
622 +DC=ldc2
623 +
624 +LIB_DEST=../lib
625 +
626 +ADD_CFLAGS=
627 +ADD_DFLAGS=
628 +
629 +targets : lib doc
630 +all : lib doc
631 +
632 +######################################################
633 +
634 +ALL_OBJS=
635 +
636 +######################################################
637 +
638 +ALL_DOCS=
639 +
640 +######################################################
641 +
642 +lib : $(ALL_OBJS)
643 + make -C $(DIR_RT) -fldc.mak lib DC=$(DC) ADD_DFLAGS="$(ADD_DFLAGS)" ADD_CFLAGS="$(ADD_CFLAGS)"
644 + make -C $(DIR_CC) -fldc.mak lib DC=$(DC) ADD_DFLAGS="$(ADD_DFLAGS)" ADD_CFLAGS="$(ADD_CFLAGS)"
645 + make -C $(DIR_GC) -fldc.mak lib DC=$(DC) ADD_DFLAGS="$(ADD_DFLAGS)" ADD_CFLAGS="$(ADD_CFLAGS)"
646 + $(RM) $(LIB_TARGET)
647 + $(LC) $(LIB_TARGET) `find $(DIR_RT) -name "*.o" | xargs echo`
648 + $(LC) $(LIB_TARGET) `find $(DIR_CC) -name "*.o" | xargs echo`
649 + $(LC) $(LIB_TARGET) `find $(DIR_GC) -name "*.o" | xargs echo`
650 + $(RM) $(DUP_TARGET)
651 + $(CP) $(LIB_TARGET) $(DUP_TARGET)
652 +
653 +doc : $(ALL_DOCS)
654 + make -C $(DIR_RT) -fldc.mak doc DC=$(DC)
655 + make -C $(DIR_CC) -fldc.mak doc DC=$(DC)
656 + make -C $(DIR_GC) -fldc.mak doc DC=$(DC)
657 +
658 +######################################################
659 +
660 +clean :
661 + find . -name "*.di" | xargs $(RM)
662 + $(RM) $(ALL_OBJS)
663 + $(RM) $(ALL_DOCS)
664 + make -C $(DIR_RT) -fldc.mak clean
665 + make -C $(DIR_CC) -fldc.mak clean
666 + make -C $(DIR_GC) -fldc.mak clean
667 + $(RM) $(LIB_MASK)
668 +
669 +install :
670 + make -C $(DIR_RT) -fldc.mak install
671 + make -C $(DIR_CC) -fldc.mak install
672 + make -C $(DIR_GC) -fldc.mak install
673 + $(CP) $(LIB_MASK) $(LIB_DEST)/.
674 Index: src/compiler/ldc/adi.d
675 ===================================================================
676 --- src/compiler/ldc/adi.d (revision 0)
677 +++ src/compiler/ldc/adi.d (revision 0)
678 @@ -0,0 +1,602 @@
679 +//_ adi.d
680 +
681 +/**
682 + * Part of the D programming language runtime library.
683 + * Dynamic array property support routines
684 + */
685 +
686 +/*
687 + * Copyright (C) 2000-2006 by Digital Mars, www.digitalmars.com
688 + * Written by Walter Bright
689 + *
690 + * This software is provided 'as-is', without any express or implied
691 + * warranty. In no event will the authors be held liable for any damages
692 + * arising from the use of this software.
693 + *
694 + * Permission is granted to anyone to use this software for any purpose,
695 + * including commercial applications, and to alter it and redistribute it
696 + * freely, in both source and binary form, subject to the following
697 + * restrictions:
698 + *
699 + * o The origin of this software must not be misrepresented; you must not
700 + * claim that you wrote the original software. If you use this software
701 + * in a product, an acknowledgment in the product documentation would be
702 + * appreciated but is not required.
703 + * o Altered source versions must be plainly marked as such, and must not
704 + * be misrepresented as being the original software.
705 + * o This notice may not be removed or altered from any source
706 + * distribution.
707 + */
708 +
709 +/*
710 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
711 + */
712 +
713 +
714 +//debug=adi; // uncomment to turn on debugging printf's
715 +
716 +private
717 +{
718 + version( D_Version2 )
719 + {
720 + import core.stdc.stdlib;
721 + import core.stdc.string;
722 + }
723 + else
724 + {
725 + import tango.stdc.stdlib;
726 + import tango.stdc.string;
727 + }
728 + import util.utf;
729 +
730 + enum BlkAttr : uint
731 + {
732 + FINALIZE = 0b0000_0001,
733 + NO_SCAN = 0b0000_0010,
734 + NO_MOVE = 0b0000_0100,
735 + ALL_BITS = 0b1111_1111
736 + }
737 +
738 + extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
739 + extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
740 + extern (C) void gc_free( void* p );
741 +}
742 +
743 +
744 +/**********************************************
745 + * Reverse array of chars.
746 + * Handled separately because embedded multibyte encodings should not be
747 + * reversed.
748 + */
749 +
750 +extern (C) char[] _adReverseChar(char[] a)
751 +{
752 + if (a.length > 1)
753 + {
754 + char[6] tmp;
755 + char[6] tmplo;
756 + char* lo = a.ptr;
757 + char* hi = &a[length - 1];
758 +
759 + while (lo < hi)
760 + { auto clo = *lo;
761 + auto chi = *hi;
762 +
763 + debug(adi) printf("lo = %d, hi = %d\n", lo, hi);
764 + if (clo <= 0x7F && chi <= 0x7F)
765 + {
766 + debug(adi) printf("\tascii\n");
767 + *lo = chi;
768 + *hi = clo;
769 + lo++;
770 + hi--;
771 + continue;
772 + }
773 +
774 + uint stridelo = UTF8stride[clo];
775 + // don't barf on invalid strides, just ignore it
776 + if (stridelo == 0xFF)
777 + stridelo = 1;
778 +
779 + uint stridehi = 1;
780 + while ((chi & 0xC0) == 0x80)
781 + {
782 + chi = *--hi;
783 + stridehi++;
784 + assert(hi >= lo);
785 + }
786 + if (lo == hi)
787 + break;
788 +
789 + debug(adi) printf("\tstridelo = %d, stridehi = %d\n", stridelo, stridehi);
790 + if (stridelo == stridehi)
791 + {
792 +
793 + memcpy(tmp.ptr, lo, stridelo);
794 + memcpy(lo, hi, stridelo);
795 + memcpy(hi, tmp.ptr, stridelo);
796 + lo += stridelo;
797 + hi--;
798 + continue;
799 + }
800 +
801 + /* Shift the whole array. This is woefully inefficient
802 + */
803 + memcpy(tmp.ptr, hi, stridehi);
804 + memcpy(tmplo.ptr, lo, stridelo);
805 + memmove(lo + stridehi, lo + stridelo , cast(size_t)(hi - lo) - stridelo);
806 + memcpy(lo, tmp.ptr, stridehi);
807 + memcpy(hi + stridehi - stridelo, tmplo.ptr, stridelo);
808 +
809 + lo += stridehi;
810 + hi = hi - 1 + (stridehi - stridelo);
811 + }
812 + }
813 + return a;
814 +}
815 +
816 +unittest
817 +{
818 + char[] a = "abcd"c;
819 +
820 + char[] r = a.dup.reverse;
821 + //writefln(r);
822 + assert(r == "dcba");
823 +
824 + a = "a\u1235\u1234c";
825 + //writefln(a);
826 + r = a.dup.reverse;
827 + //writefln(r);
828 + assert(r == "c\u1234\u1235a");
829 +
830 + a = "ab\u1234c";
831 + //writefln(a);
832 + r = a.dup.reverse;
833 + //writefln(r);
834 + assert(r == "c\u1234ba");
835 +
836 + a = "\u3026\u2021\u3061\n";
837 + r = a.dup.reverse;
838 + assert(r == "\n\u3061\u2021\u3026");
839 +}
840 +
841 +
842 +/**********************************************
843 + * Reverse array of wchars.
844 + * Handled separately because embedded multiword encodings should not be
845 + * reversed.
846 + */
847 +
848 +extern (C) wchar[] _adReverseWchar(wchar[] a)
849 +{
850 + if (a.length > 1)
851 + {
852 + wchar[2] tmp;
853 + wchar* lo = a.ptr;
854 + wchar* hi = &a[length - 1];
855 +
856 + while (lo < hi)
857 + { auto clo = *lo;
858 + auto chi = *hi;
859 +
860 + if ((clo < 0xD800 || clo > 0xDFFF) &&
861 + (chi < 0xD800 || chi > 0xDFFF))
862 + {
863 + *lo = chi;
864 + *hi = clo;
865 + lo++;
866 + hi--;
867 + continue;
868 + }
869 +
870 + int stridelo = 1 + (clo >= 0xD800 && clo <= 0xDBFF);
871 +
872 + int stridehi = 1;
873 + if (chi >= 0xDC00 && chi <= 0xDFFF)
874 + {
875 + chi = *--hi;
876 + stridehi++;
877 + assert(hi >= lo);
878 + }
879 + if (lo == hi)
880 + break;
881 +
882 + if (stridelo == stridehi)
883 + { int stmp;
884 +
885 + assert(stridelo == 2);
886 + assert(stmp.sizeof == 2 * (*lo).sizeof);
887 + stmp = *cast(int*)lo;
888 + *cast(int*)lo = *cast(int*)hi;
889 + *cast(int*)hi = stmp;
890 + lo += stridelo;
891 + hi--;
892 + continue;
893 + }
894 +
895 + /* Shift the whole array. This is woefully inefficient
896 + */
897 + memcpy(tmp.ptr, hi, stridehi * wchar.sizeof);
898 + memcpy(hi + stridehi - stridelo, lo, stridelo * wchar.sizeof);
899 + memmove(lo + stridehi, lo + stridelo , (hi - (lo + stridelo)) * wchar.sizeof);
900 + memcpy(lo, tmp.ptr, stridehi * wchar.sizeof);
901 +
902 + lo += stridehi;
903 + hi = hi - 1 + (stridehi - stridelo);
904 + }
905 + }
906 + return a;
907 +}
908 +
909 +unittest
910 +{
911 + wchar[] a = "abcd";
912 + wchar[] r;
913 +
914 + r = a.dup.reverse;
915 + assert(r == "dcba");
916 +
917 + a = "a\U00012356\U00012346c";
918 + r = a.dup.reverse;
919 + assert(r == "c\U00012346\U00012356a");
920 +
921 + a = "ab\U00012345c";
922 + r = a.dup.reverse;
923 + assert(r == "c\U00012345ba");
924 +}
925 +
926 +
927 +/**********************************************
928 + * Support for array.reverse property.
929 + * The actual type is painted on the return value by the frontend
930 + * Given and returned length are number of elements
931 + */
932 +
933 +extern (C) void[] _adReverse(void[] a, size_t szelem)
934 + out (result)
935 + {
936 + assert(result.ptr is a.ptr);
937 + }
938 + body
939 + {
940 + if (a.length >= 2)
941 + {
942 + byte* tmp;
943 + byte[16] buffer;
944 +
945 + void* lo = a.ptr;
946 + void* hi = a.ptr + (a.length - 1) * szelem;
947 +
948 + tmp = buffer.ptr;
949 + if (szelem > 16)
950 + {
951 + //version (Win32)
952 + //tmp = cast(byte*) alloca(szelem);
953 + //else
954 + tmp = cast(byte*) gc_malloc(szelem);
955 + }
956 +
957 + for (; lo < hi; lo += szelem, hi -= szelem)
958 + {
959 + memcpy(tmp, lo, szelem);
960 + memcpy(lo, hi, szelem);
961 + memcpy(hi, tmp, szelem);
962 + }
963 +
964 + version (Win32)
965 + {
966 + }
967 + else
968 + {
969 + //if (szelem > 16)
970 + // BUG: bad code is generate for delete pointer, tries
971 + // to call delclass.
972 + //gc_free(tmp);
973 + }
974 + }
975 + return a.ptr[0 .. a.length];
976 + }
977 +
978 +unittest
979 +{
980 + debug(adi) printf("array.reverse.unittest\n");
981 +
982 + int[] a = new int[5];
983 + int[] b;
984 + size_t i;
985 +
986 + for (i = 0; i < 5; i++)
987 + a[i] = i;
988 + b = a.reverse;
989 + assert(b is a);
990 + for (i = 0; i < 5; i++)
991 + assert(a[i] == 4 - i);
992 +
993 + struct X20
994 + { // More than 16 bytes in size
995 + int a;
996 + int b, c, d, e;
997 + }
998 +
999 + X20[] c = new X20[5];
1000 + X20[] d;
1001 +
1002 + for (i = 0; i < 5; i++)
1003 + { c[i].a = i;
1004 + c[i].e = 10;
1005 + }
1006 + d = c.reverse;
1007 + assert(d is c);
1008 + for (i = 0; i < 5; i++)
1009 + {
1010 + assert(c[i].a == 4 - i);
1011 + assert(c[i].e == 10);
1012 + }
1013 +}
1014 +
1015 +/**********************************************
1016 + * Sort array of chars.
1017 + */
1018 +
1019 +extern (C) char[] _adSortChar(char[] a)
1020 +{
1021 + if (a.length > 1)
1022 + {
1023 + dstring da = toUTF32(a);
1024 + da.sort;
1025 + size_t i = 0;
1026 + foreach (dchar d; da)
1027 + { char[4] buf;
1028 + auto t = toUTF8(buf, d);
1029 + a[i .. i + t.length] = t[];
1030 + i += t.length;
1031 + }
1032 + delete da;
1033 + }
1034 + return a;
1035 +}
1036 +
1037 +/**********************************************
1038 + * Sort array of wchars.
1039 + */
1040 +
1041 +extern (C) wchar[] _adSortWchar(wchar[] a)
1042 +{
1043 + if (a.length > 1)
1044 + {
1045 + dstring da = toUTF32(a);
1046 + da.sort;
1047 + size_t i = 0;
1048 + foreach (dchar d; da)
1049 + { wchar[2] buf;
1050 + auto t = toUTF16(buf, d);
1051 + a[i .. i + t.length] = t[];
1052 + i += t.length;
1053 + }
1054 + delete da;
1055 + }
1056 + return a;
1057 +}
1058 +
1059 +/***************************************
1060 + * Support for array equality test.
1061 + * The actual type is painted on the return value by the frontend
1062 + * Given lengths are number of elements
1063 + */
1064 +
1065 +extern (C) int _adEq(void[] a1, void[] a2, TypeInfo ti)
1066 +{
1067 + debug(adi) printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
1068 +
1069 + if (a1.length != a2.length)
1070 + return 0; // not equal
1071 + else if (a1.ptr == a2.ptr)
1072 + return 1; // equal
1073 +
1074 + // let typeinfo decide
1075 + return ti.equals(&a1, &a2);
1076 +}
1077 +
1078 +unittest
1079 +{
1080 + debug(adi) printf("array.Eq unittest\n");
1081 +
1082 + char[] a = "hello"c;
1083 +
1084 + assert(a != "hel");
1085 + assert(a != "helloo");
1086 + assert(a != "betty");
1087 + assert(a == "hello");
1088 + assert(a != "hxxxx");
1089 +}
1090 +
1091 +/***************************************
1092 + * Support for array compare test.
1093 + * The actual type is painted on the return value by the frontend
1094 + * Given lengths are number of elements
1095 + */
1096 +
1097 +extern (C) int _adCmp(void[] a1, void[] a2, TypeInfo ti)
1098 +{
1099 + debug(adi) printf("adCmp()\n");
1100 +
1101 + if (a1.ptr == a2.ptr &&
1102 + a1.length == a2.length)
1103 + return 0;
1104 +
1105 + auto len = a1.length;
1106 + if (a2.length < len)
1107 + len = a2.length;
1108 +
1109 + // let typeinfo decide
1110 + return ti.compare(&a1, &a2);
1111 +}
1112 +
1113 +unittest
1114 +{
1115 + debug(adi) printf("array.Cmp unittest\n");
1116 +
1117 + char[] a = "hello"c;
1118 +
1119 + assert(a > "hel");
1120 + assert(a >= "hel");
1121 + assert(a < "helloo");
1122 + assert(a <= "helloo");
1123 + assert(a > "betty");
1124 + assert(a >= "betty");
1125 + assert(a == "hello");
1126 + assert(a <= "hello");
1127 + assert(a >= "hello");
1128 +}
1129 +
1130 +/***************************************
1131 + * Support for array compare test.
1132 + * The actual type is painted on the return value by the frontend
1133 + * Given lengths are number of elements
1134 + */
1135 +
1136 +extern (C) int _adCmpChar(void[] a1, void[] a2)
1137 +{
1138 + version(D_InlineAsm_X86)
1139 + {
1140 + //version = Asm86;
1141 + }
1142 + version (Asm86)
1143 + {
1144 + asm
1145 + { naked ;
1146 +
1147 + push EDI ;
1148 + push ESI ;
1149 +
1150 + mov ESI,a1+4[4+ESP] ;
1151 + mov EDI,a2+4[4+ESP] ;
1152 +
1153 + mov ECX,a1[4+ESP] ;
1154 + mov EDX,a2[4+ESP] ;
1155 +
1156 + cmp ECX,EDX ;
1157 + jb GotLength ;
1158 +
1159 + mov ECX,EDX ;
1160 +
1161 +GotLength:
1162 + cmp ECX,4 ;
1163 + jb DoBytes ;
1164 +
1165 + // Do alignment if neither is dword aligned
1166 + test ESI,3 ;
1167 + jz Aligned ;
1168 +
1169 + test EDI,3 ;
1170 + jz Aligned ;
1171 +DoAlign:
1172 + mov AL,[ESI] ; //align ESI to dword bounds
1173 + mov DL,[EDI] ;
1174 +
1175 + cmp AL,DL ;
1176 + jnz Unequal ;
1177 +
1178 + inc ESI ;
1179 + inc EDI ;
1180 +
1181 + test ESI,3 ;
1182 +
1183 + lea ECX,[ECX-1] ;
1184 + jnz DoAlign ;
1185 +Aligned:
1186 + mov EAX,ECX ;
1187 +
1188 + // do multiple of 4 bytes at a time
1189 +
1190 + shr ECX,2 ;
1191 + jz TryOdd ;
1192 +
1193 + repe ;
1194 + cmpsd ;
1195 +
1196 + jnz UnequalQuad ;
1197 +
1198 +TryOdd:
1199 + mov ECX,EAX ;
1200 +DoBytes:
1201 + // if still equal and not end of string, do up to 3 bytes slightly
1202 + // slower.
1203 +
1204 + and ECX,3 ;
1205 + jz Equal ;
1206 +
1207 + repe ;
1208 + cmpsb ;
1209 +
1210 + jnz Unequal ;
1211 +Equal:
1212 + mov EAX,a1[4+ESP] ;
1213 + mov EDX,a2[4+ESP] ;
1214 +
1215 + sub EAX,EDX ;
1216 + pop ESI ;
1217 +
1218 + pop EDI ;
1219 + ret ;
1220 +
1221 +UnequalQuad:
1222 + mov EDX,[EDI-4] ;
1223 + mov EAX,[ESI-4] ;
1224 +
1225 + cmp AL,DL ;
1226 + jnz Unequal ;
1227 +
1228 + cmp AH,DH ;
1229 + jnz Unequal ;
1230 +
1231 + shr EAX,16 ;
1232 +
1233 + shr EDX,16 ;
1234 +
1235 + cmp AL,DL ;
1236 + jnz Unequal ;
1237 +
1238 + cmp AH,DH ;
1239 +Unequal:
1240 + sbb EAX,EAX ;
1241 + pop ESI ;
1242 +
1243 + or EAX,1 ;
1244 + pop EDI ;
1245 +
1246 + ret ;
1247 + }
1248 + }
1249 + else
1250 + {
1251 + int len;
1252 + int c;
1253 +
1254 + debug(adi) printf("adCmpChar()\n");
1255 + len = cast(int)a1.length;
1256 + if (a2.length < len)
1257 + len = cast(int)a2.length;
1258 + c = memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len);
1259 + if (!c)
1260 + c = cast(int)a1.length - cast(int)a2.length;
1261 + return c;
1262 + }
1263 +}
1264 +
1265 +unittest
1266 +{
1267 + debug(adi) printf("array.CmpChar unittest\n");
1268 +
1269 + char[] a = "hello"c;
1270 +
1271 + assert(a > "hel");
1272 + assert(a >= "hel");
1273 + assert(a < "helloo");
1274 + assert(a <= "helloo");
1275 + assert(a > "betty");
1276 + assert(a >= "betty");
1277 + assert(a == "hello");
1278 + assert(a <= "hello");
1279 + assert(a >= "hello");
1280 +}
1281 Index: src/compiler/ldc/lifetime.d
1282 ===================================================================
1283 --- src/compiler/ldc/lifetime.d (revision 0)
1284 +++ src/compiler/ldc/lifetime.d (revision 0)
1285 @@ -0,0 +1,1147 @@
1286 +/**
1287 + * This module contains all functions related to an object's lifetime:
1288 + * allocation, resizing, deallocation, and finalization.
1289 + *
1290 + * Copyright: Copyright (C) 2004-2007 Digital Mars, www.digitalmars.com.
1291 + * All rights reserved.
1292 + * License:
1293 + * This software is provided 'as-is', without any express or implied
1294 + * warranty. In no event will the authors be held liable for any damages
1295 + * arising from the use of this software.
1296 + *
1297 + * Permission is granted to anyone to use this software for any purpose,
1298 + * including commercial applications, and to alter it and redistribute it
1299 + * freely, in both source and binary form, subject to the following
1300 + * restrictions:
1301 + *
1302 + * o The origin of this software must not be misrepresented; you must not
1303 + * claim that you wrote the original software. If you use this software
1304 + * in a product, an acknowledgment in the product documentation would be
1305 + * appreciated but is not required.
1306 + * o Altered source versions must be plainly marked as such, and must not
1307 + * be misrepresented as being the original software.
1308 + * o This notice may not be removed or altered from any source
1309 + * distribution.
1310 + * Authors: Walter Bright, Sean Kelly, Tomas Lindquist Olsen
1311 + */
1312 +module lifetime;
1313 +
1314 +//debug=PRINTF;
1315 +//debug=PRINTF2;
1316 +
1317 +private
1318 +{
1319 + version( D_Version2 )
1320 + {
1321 + import core.stdc.stdlib;
1322 + import core.stdc.string;
1323 + import core.stdc.stdarg;
1324 + debug(PRINTF) import core.stdc.stdio;
1325 + else debug(PRINTF2) import core.stdc.stdio;
1326 + }
1327 + else
1328 + {
1329 + import tango.stdc.stdlib;
1330 + import tango.stdc.string;
1331 + import tango.stdc.stdarg;
1332 + debug(PRINTF) import tango.stdc.stdio;
1333 + else debug(PRINTF2) import tango.stdc.stdio;
1334 + }
1335 +}
1336 +
1337 +
1338 +private
1339 +{
1340 + enum BlkAttr : uint
1341 + {
1342 + FINALIZE = 0b0000_0001,
1343 + NO_SCAN = 0b0000_0010,
1344 + NO_MOVE = 0b0000_0100,
1345 + ALL_BITS = 0b1111_1111
1346 + }
1347 +
1348 + struct BlkInfo
1349 + {
1350 + void* base;
1351 + size_t size;
1352 + uint attr;
1353 + }
1354 +
1355 + extern (C) uint gc_getAttr( void* p );
1356 + extern (C) uint gc_setAttr( void* p, uint a );
1357 + extern (C) uint gc_clrAttr( void* p, uint a );
1358 +
1359 + extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
1360 + extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
1361 + extern (C) size_t gc_extend( void* p, size_t mx, size_t sz );
1362 + extern (C) void gc_free( void* p );
1363 +
1364 + extern (C) void* gc_addrOf( void* p );
1365 + extern (C) size_t gc_sizeOf( void* p );
1366 + extern (C) BlkInfo gc_query( void* p );
1367 +
1368 + extern (C) bool onCollectResource( Object o );
1369 + extern (C) void onFinalizeError( ClassInfo c, Exception e );
1370 + extern (C) void onOutOfMemoryError();
1371 +
1372 + extern (C) void _d_monitordelete(Object h, bool det = true);
1373 +
1374 + enum
1375 + {
1376 + PAGESIZE = 4096
1377 + }
1378 +
1379 + alias bool function(Object) CollectHandler;
1380 + CollectHandler collectHandler = null;
1381 +}
1382 +
1383 +
1384 +/**
1385 + *
1386 + */
1387 +extern (C) Object _d_allocclass(ClassInfo ci)
1388 +{
1389 + void* p;
1390 +
1391 + debug(PRINTF2) printf("_d_allocclass(ci = %p, %s)\n", ci, cast(char *)ci.name.ptr);
1392 + /+
1393 + if (ci.flags & 1) // if COM object
1394 + { /* COM objects are not garbage collected, they are reference counted
1395 + * using AddRef() and Release(). They get free'd by C's free()
1396 + * function called by Release() when Release()'s reference count goes
1397 + * to zero.
1398 + */
1399 + p = tango.stdc.stdlib.malloc(ci.init.length);
1400 + if (!p)
1401 + onOutOfMemoryError();
1402 + }
1403 + else
1404 + +/
1405 + {
1406 + p = gc_malloc(ci.init.length,
1407 + BlkAttr.FINALIZE | (ci.flags & 2 ? BlkAttr.NO_SCAN : 0));
1408 + debug(PRINTF2) printf(" p = %p\n", p);
1409 + }
1410 +
1411 + debug(PRINTF2)
1412 + {
1413 + printf("p = %p\n", p);
1414 + printf("ci = %p, ci.init = %p, len = %d\n", ci, ci.init.ptr, ci.init.length);
1415 + printf("vptr = %p\n", *cast(void**) ci.init.ptr);
1416 + printf("vtbl[0] = %p\n", (*cast(void***) ci.init.ptr)[0]);
1417 + printf("vtbl[1] = %p\n", (*cast(void***) ci.init.ptr)[1]);
1418 + printf("init[0] = %p\n", (cast(uint**) ci.init.ptr)[0]);
1419 + printf("init[1] = %p\n", (cast(uint**) ci.init.ptr)[1]);
1420 + printf("init[2] = %p\n", (cast(uint**) ci.init.ptr)[2]);
1421 + printf("init[3] = %p\n", (cast(uint**) ci.init.ptr)[3]);
1422 + printf("init[4] = %p\n", (cast(uint**) ci.init.ptr)[4]);
1423 + }
1424 +
1425 + // initialize it
1426 + // ldc does this inline
1427 + //(cast(byte*) p)[0 .. ci.init.length] = ci.init[];
1428 +
1429 + debug(PRINTF) printf("initialization done\n");
1430 + return cast(Object) p;
1431 +}
1432 +
1433 +/**
1434 + *
1435 + */
1436 +extern (C) void _d_delinterface(void* p)
1437 +{
1438 + if (p)
1439 + {
1440 + Interface* pi = **cast(Interface ***)p;
1441 + Object o = cast(Object)(p - pi.offset);
1442 +
1443 + _d_delclass(o);
1444 + //*p = null;
1445 + }
1446 +}
1447 +
1448 +// used for deletion
1449 +private extern (D) alias void function(Object) fp_t;
1450 +
1451 +
1452 +/**
1453 + *
1454 + */
1455 +extern (C) void _d_delclass(Object p)
1456 +{
1457 + if (p)
1458 + {
1459 + debug(PRINTF) printf("_d_delclass(%p)\n", p);
1460 +
1461 + ClassInfo **pc = cast(ClassInfo **)p;
1462 + if (*pc)
1463 + {
1464 + ClassInfo c = **pc;
1465 +
1466 + rt_finalize(cast(void*) p);
1467 +
1468 + if (c.deallocator)
1469 + {
1470 + fp_t fp = cast(fp_t)c.deallocator;
1471 + (*fp)(p); // call deallocator
1472 + //*p = null;
1473 + return;
1474 + }
1475 + }
1476 + else
1477 + {
1478 + rt_finalize(cast(void*) p);
1479 + }
1480 + gc_free(cast(void*) p);
1481 + //*p = null;
1482 + }
1483 +}
1484 +
1485 +/+
1486 +
1487 +/**
1488 + *
1489 + */
1490 +struct Array
1491 +{
1492 + size_t length;
1493 + void* data;
1494 +}
1495 +
1496 ++/
1497 +
1498 +/**
1499 + * Allocate a new array of length elements.
1500 + * ti is the type of the resulting array, or pointer to element.
1501 + * The resulting array is initialized to 0
1502 + */
1503 +extern (C) void* _d_newarrayT(TypeInfo ti, size_t length)
1504 +{
1505 + void* p;
1506 + auto size = ti.next.tsize(); // array element size
1507 +
1508 + debug(PRINTF) printf("_d_newarrayT(length = %u, size = %d)\n", length, size);
1509 + if (length == 0 || size == 0)
1510 + return null;
1511 +
1512 + version (D_InlineAsm_X86)
1513 + {
1514 + asm
1515 + {
1516 + mov EAX,size ;
1517 + mul EAX,length ;
1518 + mov size,EAX ;
1519 + jc Loverflow ;
1520 + }
1521 + }
1522 + else
1523 + size *= length;
1524 + p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1525 + debug(PRINTF) printf(" p = %p\n", p);
1526 + memset(p, 0, size);
1527 + return p;
1528 +
1529 +Loverflow:
1530 + onOutOfMemoryError();
1531 + return null;
1532 +}
1533 +
1534 +/**
1535 + * As _d_newarrayT, but
1536 + * for when the array has a non-zero initializer.
1537 + */
1538 +extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length)
1539 +{
1540 + void* result;
1541 + auto size = ti.next.tsize(); // array element size
1542 +
1543 + debug(PRINTF) printf("_d_newarrayiT(length = %d, size = %d)\n", length, size);
1544 +
1545 + if (length == 0 || size == 0)
1546 + result = null;
1547 + else
1548 + {
1549 + auto initializer = ti.next.init();
1550 + auto isize = initializer.length;
1551 + auto q = initializer.ptr;
1552 + version (D_InlineAsm_X86)
1553 + {
1554 + asm
1555 + {
1556 + mov EAX,size ;
1557 + mul EAX,length ;
1558 + mov size,EAX ;
1559 + jc Loverflow ;
1560 + }
1561 + }
1562 + else
1563 + size *= length;
1564 + auto p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1565 + debug(PRINTF) printf(" p = %p\n", p);
1566 + if (isize == 1)
1567 + memset(p, *cast(ubyte*)q, size);
1568 + else if (isize == int.sizeof)
1569 + {
1570 + int init = *cast(int*)q;
1571 + size /= int.sizeof;
1572 + for (size_t u = 0; u < size; u++)
1573 + {
1574 + (cast(int*)p)[u] = init;
1575 + }
1576 + }
1577 + else
1578 + {
1579 + for (size_t u = 0; u < size; u += isize)
1580 + {
1581 + memcpy(p + u, q, isize);
1582 + }
1583 + }
1584 + result = p;
1585 + }
1586 + return result;
1587 +
1588 +Loverflow:
1589 + onOutOfMemoryError();
1590 + return null;
1591 +}
1592 +
1593 +/**
1594 + * As _d_newarrayT, but without initialization
1595 + */
1596 +extern (C) void* _d_newarrayvT(TypeInfo ti, size_t length)
1597 +{
1598 + void* p;
1599 + auto size = ti.next.tsize(); // array element size
1600 +
1601 + debug(PRINTF) printf("_d_newarrayvT(length = %u, size = %d)\n", length, size);
1602 + if (length == 0 || size == 0)
1603 + return null;
1604 +
1605 + version (D_InlineAsm_X86)
1606 + {
1607 + asm
1608 + {
1609 + mov EAX,size ;
1610 + mul EAX,length ;
1611 + mov size,EAX ;
1612 + jc Loverflow ;
1613 + }
1614 + }
1615 + else
1616 + size *= length;
1617 + p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1618 + debug(PRINTF) printf(" p = %p\n", p);
1619 + return p;
1620 +
1621 +Loverflow:
1622 + onOutOfMemoryError();
1623 + return null;
1624 +}
1625 +
1626 +/**
1627 + * Allocate a new array of arrays of arrays of arrays ...
1628 + * ti is the type of the resulting array.
1629 + * ndims is the number of nested arrays.
1630 + * dims it the array of dimensions, its size is ndims.
1631 + * The resulting array is initialized to 0
1632 + */
1633 +extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
1634 +{
1635 + void* result;
1636 +
1637 + debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims);
1638 + if (ndims == 0)
1639 + result = null;
1640 + else
1641 + {
1642 + static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
1643 + {
1644 + size_t dim = *pdim;
1645 + void[] p;
1646 +
1647 + debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
1648 + if (ndims == 1)
1649 + {
1650 + auto r = _d_newarrayT(ti, dim);
1651 + return r[0 .. dim];
1652 + }
1653 + else
1654 + {
1655 + p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
1656 + for (int i = 0; i < dim; i++)
1657 + {
1658 + (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
1659 + }
1660 + }
1661 + return p;
1662 + }
1663 +
1664 + result = foo(ti, dims, ndims).ptr;
1665 + debug(PRINTF) printf("result = %p\n", result);
1666 +
1667 + version (none)
1668 + {
1669 + for (int i = 0; i < ndims; i++)
1670 + {
1671 + printf("index %d: %d\n", i, *dims++);
1672 + }
1673 + }
1674 + }
1675 + return result;
1676 +}
1677 +
1678 +
1679 +/**
1680 + * As _d_newarraymT, but
1681 + * for when the array has a non-zero initializer.
1682 + */
1683 +extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
1684 +{
1685 + void* result;
1686 +
1687 + debug(PRINTF) printf("_d_newarraymiT(ndims = %d)\n", ndims);
1688 + if (ndims == 0)
1689 + result = null;
1690 + else
1691 + {
1692 + static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
1693 + {
1694 + size_t dim = *pdim;
1695 + void[] p;
1696 +
1697 + if (ndims == 1)
1698 + {
1699 + auto r = _d_newarrayiT(ti, dim);
1700 + p = r[0 .. dim];
1701 + }
1702 + else
1703 + {
1704 + p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
1705 + for (int i = 0; i < dim; i++)
1706 + {
1707 + (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
1708 + }
1709 + }
1710 + return p;
1711 + }
1712 +
1713 + result = foo(ti, dims, ndims).ptr;
1714 + debug(PRINTF) printf("result = %p\n", result);
1715 +
1716 + version (none)
1717 + {
1718 + for (int i = 0; i < ndims; i++)
1719 + {
1720 + printf("index %d: %d\n", i, *dims++);
1721 + printf("init = %d\n", *dims++);
1722 + }
1723 + }
1724 + }
1725 + return result;
1726 +}
1727 +
1728 +/**
1729 + * As _d_newarraymT, but without initialization
1730 + */
1731 +extern (C) void* _d_newarraymvT(TypeInfo ti, int ndims, size_t* dims)
1732 +{
1733 + void* result;
1734 +
1735 + debug(PRINTF) printf("_d_newarraymvT(ndims = %d)\n", ndims);
1736 + if (ndims == 0)
1737 + result = null;
1738 + else
1739 + {
1740 + static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
1741 + {
1742 + size_t dim = *pdim;
1743 + void[] p;
1744 +
1745 + debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
1746 + if (ndims == 1)
1747 + {
1748 + auto r = _d_newarrayvT(ti, dim);
1749 + return r[0 .. dim];
1750 + }
1751 + else
1752 + {
1753 + p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
1754 + for (int i = 0; i < dim; i++)
1755 + {
1756 + (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
1757 + }
1758 + }
1759 + return p;
1760 + }
1761 +
1762 + result = foo(ti, dims, ndims).ptr;
1763 + debug(PRINTF) printf("result = %p\n", result);
1764 +
1765 + version (none)
1766 + {
1767 + for (int i = 0; i < ndims; i++)
1768 + {
1769 + printf("index %d: %d\n", i, *dims++);
1770 + }
1771 + }
1772 + }
1773 + return result;
1774 +}
1775 +
1776 +/+
1777 +
1778 +/**
1779 + *
1780 + */
1781 +void* _d_allocmemory(size_t nbytes)
1782 +{
1783 + return gc_malloc(nbytes);
1784 +}
1785 +
1786 ++/
1787 +
1788 +/**
1789 + * for allocating a single POD value
1790 + */
1791 +extern (C) void* _d_allocmemoryT(TypeInfo ti)
1792 +{
1793 + return gc_malloc(ti.tsize(), !(ti.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1794 +}
1795 +
1796 +/**
1797 + *
1798 + */
1799 +extern (C) void _d_delarray(size_t plength, void* pdata)
1800 +{
1801 +// if (p)
1802 +// {
1803 + assert(!plength || pdata);
1804 +
1805 + if (pdata)
1806 + gc_free(pdata);
1807 +// p.data = null;
1808 +// p.length = 0;
1809 +// }
1810 +}
1811 +
1812 +/**
1813 + *
1814 + */
1815 +extern (C) void _d_delmemory(void* p)
1816 +{
1817 + if (p)
1818 + {
1819 + gc_free(p);
1820 + //*p = null;
1821 + }
1822 +}
1823 +
1824 +/**
1825 + *
1826 + */
1827 +extern (C) void _d_callinterfacefinalizer(void *p)
1828 +{
1829 + if (p)
1830 + {
1831 + Interface *pi = **cast(Interface ***)p;
1832 + Object o = cast(Object)(p - pi.offset);
1833 + rt_finalize(cast(void*)o);
1834 + }
1835 +}
1836 +
1837 +/**
1838 + *
1839 + */
1840 +extern (C) void _d_callfinalizer(void* p)
1841 +{
1842 + rt_finalize( p );
1843 +}
1844 +
1845 +
1846 +/**
1847 + *
1848 + */
1849 +extern (C) void rt_setCollectHandler(CollectHandler h)
1850 +{
1851 + collectHandler = h;
1852 +}
1853 +
1854 +/**
1855 + *
1856 + */
1857 +extern (C) void rt_finalize(void* p, bool det = true)
1858 +{
1859 + debug(PRINTF) printf("rt_finalize(p = %p)\n", p);
1860 +
1861 + if (p) // not necessary if called from gc
1862 + {
1863 + ClassInfo** pc = cast(ClassInfo**)p;
1864 +
1865 + if (*pc)
1866 + {
1867 + ClassInfo c = **pc;
1868 +
1869 + try
1870 + {
1871 + if (det || collectHandler is null || collectHandler(cast(Object)p))
1872 + {
1873 + do
1874 + {
1875 + if (c.destructor)
1876 + {
1877 + debug(PRINTF) printf("calling dtor of %.*s\n", c.name.length, c.name.ptr);
1878 + fp_t fp = cast(fp_t)c.destructor;
1879 + (*fp)(cast(Object)p); // call destructor
1880 + }
1881 + c = c.base;
1882 + } while (c);
1883 + }
1884 + if ((cast(void**)p)[1]) // if monitor is not null
1885 + _d_monitordelete(cast(Object)p, det);
1886 + }
1887 + catch (Exception e)
1888 + {
1889 + onFinalizeError(**pc, e);
1890 + }
1891 + finally
1892 + {
1893 + *pc = null; // zero vptr
1894 + }
1895 + }
1896 + }
1897 +}
1898 +
1899 +/**
1900 + * Resize dynamic arrays with 0 initializers.
1901 + */
1902 +extern (C) byte* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
1903 +in
1904 +{
1905 + assert(ti);
1906 + assert(!plength || pdata);
1907 +}
1908 +body
1909 +{
1910 + byte* newdata;
1911 + size_t sizeelem = ti.next.tsize();
1912 +
1913 + debug(PRINTF)
1914 + {
1915 + printf("_d_arraysetlengthT(sizeelem = %d, newlength = %d)\n", sizeelem, newlength);
1916 + printf("\tp.data = %p, p.length = %d\n", pdata, plength);
1917 + }
1918 +
1919 + if (newlength)
1920 + {
1921 + version (D_InlineAsm_X86)
1922 + {
1923 + size_t newsize = void;
1924 +
1925 + asm
1926 + {
1927 + mov EAX, newlength;
1928 + mul EAX, sizeelem;
1929 + mov newsize, EAX;
1930 + jc Loverflow;
1931 + }
1932 + }
1933 + else
1934 + {
1935 + size_t newsize = sizeelem * newlength;
1936 +
1937 + if (newsize / newlength != sizeelem)
1938 + goto Loverflow;
1939 + }
1940 +
1941 + debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
1942 +
1943 + if (pdata)
1944 + {
1945 + newdata = pdata;
1946 + if (newlength > plength)
1947 + {
1948 + size_t size = plength * sizeelem;
1949 + auto info = gc_query(pdata);
1950 +
1951 + if (info.size <= newsize || info.base != pdata)
1952 + {
1953 + if (info.size >= PAGESIZE && info.base == pdata)
1954 + { // Try to extend in-place
1955 + auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
1956 + if (u)
1957 + {
1958 + goto L1;
1959 + }
1960 + }
1961 + newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
1962 + newdata[0 .. size] = pdata[0 .. size];
1963 + }
1964 + L1:
1965 + newdata[size .. newsize] = 0;
1966 + }
1967 + }
1968 + else
1969 + {
1970 + newdata = cast(byte *)gc_calloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1971 + }
1972 + }
1973 + else
1974 + {
1975 + newdata = pdata;
1976 + }
1977 +
1978 + return newdata;
1979 +
1980 +Loverflow:
1981 + onOutOfMemoryError();
1982 + return null;
1983 +}
1984 +
1985 +
1986 +/**
1987 + * Resize arrays for non-zero initializers.
1988 + * p pointer to array lvalue to be updated
1989 + * newlength new .length property of array
1990 + * sizeelem size of each element of array
1991 + * initsize size of initializer
1992 + * ... initializer
1993 + */
1994 +extern (C) byte* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
1995 +in
1996 +{
1997 + assert(!plength || pdata);
1998 +}
1999 +body
2000 +{
2001 + byte* newdata;
2002 + TypeInfo tinext = ti.next;
2003 + size_t sizeelem = tinext.tsize();
2004 + void[] initializer = tinext.init();
2005 + size_t initsize = initializer.length;
2006 +
2007 + assert(sizeelem);
2008 + assert(initsize);
2009 + assert(initsize <= sizeelem);
2010 + assert((sizeelem / initsize) * initsize == sizeelem);
2011 +
2012 + debug(PRINTF)
2013 + {
2014 + printf("_d_arraysetlengthiT(sizeelem = %d, newlength = %d, initsize = %d)\n", sizeelem, newlength, initsize);
2015 + printf("\tp.data = %p, p.length = %d\n", pdata, plength);
2016 + }
2017 +
2018 + if (newlength)
2019 + {
2020 + version (D_InlineAsm_X86)
2021 + {
2022 + size_t newsize = void;
2023 +
2024 + asm
2025 + {
2026 + mov EAX,newlength ;
2027 + mul EAX,sizeelem ;
2028 + mov newsize,EAX ;
2029 + jc Loverflow ;
2030 + }
2031 + }
2032 + else
2033 + {
2034 + size_t newsize = sizeelem * newlength;
2035 +
2036 + if (newsize / newlength != sizeelem)
2037 + goto Loverflow;
2038 + }
2039 + debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
2040 +
2041 + size_t size = plength * sizeelem;
2042 +
2043 + if (pdata)
2044 + {
2045 + newdata = pdata;
2046 + if (newlength > plength)
2047 + {
2048 + auto info = gc_query(pdata);
2049 +
2050 + if (info.size <= newsize || info.base != pdata)
2051 + {
2052 + if (info.size >= PAGESIZE && info.base == pdata)
2053 + { // Try to extend in-place
2054 + auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
2055 + if (u)
2056 + {
2057 + goto L1;
2058 + }
2059 + }
2060 + newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
2061 + newdata[0 .. size] = pdata[0 .. size];
2062 + L1: ;
2063 + }
2064 + }
2065 + }
2066 + else
2067 + {
2068 + newdata = cast(byte *)gc_malloc(newsize + 1, !(tinext.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2069 + }
2070 +
2071 + auto q = initializer.ptr; // pointer to initializer
2072 +
2073 + if (newsize > size)
2074 + {
2075 + if (initsize == 1)
2076 + {
2077 + debug(PRINTF) printf("newdata = %p, size = %d, newsize = %d, *q = %d\n", newdata, size, newsize, *cast(byte*)q);
2078 + newdata[size .. newsize] = *(cast(byte*)q);
2079 + }
2080 + else
2081 + {
2082 + for (size_t u = size; u < newsize; u += initsize)
2083 + {
2084 + memcpy(newdata + u, q, initsize);
2085 + }
2086 + }
2087 + }
2088 + }
2089 + else
2090 + {
2091 + newdata = pdata;
2092 + }
2093 +
2094 + return newdata;
2095 +
2096 +Loverflow:
2097 + onOutOfMemoryError();
2098 + return null;
2099 +}
2100 +
2101 +/+
2102 +
2103 +/**
2104 + * Append y[] to array x[].
2105 + * size is size of each array element.
2106 + */
2107 +extern (C) long _d_arrayappendT(TypeInfo ti, Array *px, byte[] y)
2108 +{
2109 + auto sizeelem = ti.next.tsize(); // array element size
2110 + auto info = gc_query(px.data);
2111 + auto length = px.length;
2112 + auto newlength = length + y.length;
2113 + auto newsize = newlength * sizeelem;
2114 +
2115 + if (info.size < newsize || info.base != px.data)
2116 + { byte* newdata;
2117 +
2118 + if (info.size >= PAGESIZE && info.base == px.data)
2119 + { // Try to extend in-place
2120 + auto u = gc_extend(px.data, (newsize + 1) - info.size, (newsize + 1) - info.size);
2121 + if (u)
2122 + {
2123 + goto L1;
2124 + }
2125 + }
2126 + newdata = cast(byte *)gc_malloc(newCapacity(newlength, sizeelem) + 1, info.attr);
2127 + memcpy(newdata, px.data, length * sizeelem);
2128 + px.data = newdata;
2129 + }
2130 + L1:
2131 + px.length = newlength;
2132 + memcpy(px.data + length * sizeelem, y.ptr, y.length * sizeelem);
2133 + return *cast(long*)px;
2134 +}
2135 +
2136 +
2137 +/**
2138 + *
2139 + */
2140 +size_t newCapacity(size_t newlength, size_t size)
2141 +{
2142 + version(none)
2143 + {
2144 + size_t newcap = newlength * size;
2145 + }
2146 + else
2147 + {
2148 + /*
2149 + * Better version by Dave Fladebo:
2150 + * This uses an inverse logorithmic algorithm to pre-allocate a bit more
2151 + * space for larger arrays.
2152 + * - Arrays smaller than PAGESIZE bytes are left as-is, so for the most
2153 + * common cases, memory allocation is 1 to 1. The small overhead added
2154 + * doesn't affect small array perf. (it's virtually the same as
2155 + * current).
2156 + * - Larger arrays have some space pre-allocated.
2157 + * - As the arrays grow, the relative pre-allocated space shrinks.
2158 + * - The logorithmic algorithm allocates relatively more space for
2159 + * mid-size arrays, making it very fast for medium arrays (for
2160 + * mid-to-large arrays, this turns out to be quite a bit faster than the
2161 + * equivalent realloc() code in C, on Linux at least. Small arrays are
2162 + * just as fast as GCC).
2163 + * - Perhaps most importantly, overall memory usage and stress on the GC
2164 + * is decreased significantly for demanding environments.
2165 + */
2166 + size_t newcap = newlength * size;
2167 + size_t newext = 0;
2168 +
2169 + if (newcap > PAGESIZE)
2170 + {
2171 + //double mult2 = 1.0 + (size / log10(pow(newcap * 2.0,2.0)));
2172 +
2173 + // redo above line using only integer math
2174 +
2175 + static int log2plus1(size_t c)
2176 + { int i;
2177 +
2178 + if (c == 0)
2179 + i = -1;
2180 + else
2181 + for (i = 1; c >>= 1; i++)
2182 + {
2183 + }
2184 + return i;
2185 + }
2186 +
2187 + /* The following setting for mult sets how much bigger
2188 + * the new size will be over what is actually needed.
2189 + * 100 means the same size, more means proportionally more.
2190 + * More means faster but more memory consumption.
2191 + */
2192 + //long mult = 100 + (1000L * size) / (6 * log2plus1(newcap));
2193 + long mult = 100 + (1000L * size) / log2plus1(newcap);
2194 +
2195 + // testing shows 1.02 for large arrays is about the point of diminishing return
2196 + if (mult < 102)
2197 + mult = 102;
2198 + newext = cast(size_t)((newcap * mult) / 100);
2199 + newext -= newext % size;
2200 + debug(PRINTF) printf("mult: %2.2f, alloc: %2.2f\n",mult/100.0,newext / cast(double)size);
2201 + }
2202 + newcap = newext > newcap ? newext : newcap;
2203 + debug(PRINTF) printf("newcap = %d, newlength = %d, size = %d\n", newcap, newlength, size);
2204 + }
2205 + return newcap;
2206 +}
2207 +
2208 +
2209 +/**
2210 + *
2211 + */
2212 +extern (C) byte[] _d_arrayappendcT(TypeInfo ti, inout byte[] x, ...)
2213 +{
2214 + auto sizeelem = ti.next.tsize(); // array element size
2215 + auto info = gc_query(x.ptr);
2216 + auto length = x.length;
2217 + auto newlength = length + 1;
2218 + auto newsize = newlength * sizeelem;
2219 +
2220 + assert(info.size == 0 || length * sizeelem <= info.size);
2221 +
2222 + debug(PRINTF) printf("_d_arrayappendcT(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, info.size);
2223 +
2224 + if (info.size <= newsize || info.base != x.ptr)
2225 + { byte* newdata;
2226 +
2227 + if (info.size >= PAGESIZE && info.base == x.ptr)
2228 + { // Try to extend in-place
2229 + auto u = gc_extend(x.ptr, (newsize + 1) - info.size, (newsize + 1) - info.size);
2230 + if (u)
2231 + {
2232 + goto L1;
2233 + }
2234 + }
2235 + debug(PRINTF) printf("_d_arrayappendcT(length = %d, newlength = %d, cap = %d)\n", length, newlength, info.size);
2236 + auto newcap = newCapacity(newlength, sizeelem);
2237 + assert(newcap >= newlength * sizeelem);
2238 + newdata = cast(byte *)gc_malloc(newcap + 1, info.attr);
2239 + memcpy(newdata, x.ptr, length * sizeelem);
2240 + (cast(void**)(&x))[1] = newdata;
2241 + }
2242 + L1:
2243 + byte *argp = cast(byte *)(&ti + 2);
2244 +
2245 + *cast(size_t *)&x = newlength;
2246 + x.ptr[length * sizeelem .. newsize] = argp[0 .. sizeelem];
2247 + assert((cast(size_t)x.ptr & 15) == 0);
2248 + assert(gc_sizeOf(x.ptr) > x.length * sizeelem);
2249 + return x;
2250 +}
2251 +
2252 +
2253 +/**
2254 + *
2255 + */
2256 +extern (C) byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y)
2257 +out (result)
2258 +{
2259 + auto sizeelem = ti.next.tsize(); // array element size
2260 + debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d => %d,%p)\n", x.length, x.ptr, y.length, y.ptr, sizeelem, result.length, result.ptr);
2261 + assert(result.length == x.length + y.length);
2262 + for (size_t i = 0; i < x.length * sizeelem; i++)
2263 + assert((cast(byte*)result)[i] == (cast(byte*)x)[i]);
2264 + for (size_t i = 0; i < y.length * sizeelem; i++)
2265 + assert((cast(byte*)result)[x.length * sizeelem + i] == (cast(byte*)y)[i]);
2266 +
2267 + size_t cap = gc_sizeOf(result.ptr);
2268 + assert(!cap || cap > result.length * sizeelem);
2269 +}
2270 +body
2271 +{
2272 + version (none)
2273 + {
2274 + /* Cannot use this optimization because:
2275 + * char[] a, b;
2276 + * char c = 'a';
2277 + * b = a ~ c;
2278 + * c = 'b';
2279 + * will change the contents of b.
2280 + */
2281 + if (!y.length)
2282 + return x;
2283 + if (!x.length)
2284 + return y;
2285 + }
2286 +
2287 + debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p)\n", x.length, x.ptr, y.length, y.ptr);
2288 + auto sizeelem = ti.next.tsize(); // array element size
2289 + debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d)\n", x.length, x.ptr, y.length, y.ptr, sizeelem);
2290 + size_t xlen = x.length * sizeelem;
2291 + size_t ylen = y.length * sizeelem;
2292 + size_t len = xlen + ylen;
2293 +
2294 + if (!len)
2295 + return null;
2296 +
2297 + byte* p = cast(byte*)gc_malloc(len + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2298 + memcpy(p, x.ptr, xlen);
2299 + memcpy(p + xlen, y.ptr, ylen);
2300 + p[len] = 0;
2301 + return p[0 .. x.length + y.length];
2302 +}
2303 +
2304 +
2305 +/**
2306 + *
2307 + */
2308 +extern (C) byte[] _d_arraycatnT(TypeInfo ti, uint n, ...)
2309 +{ void* a;
2310 + size_t length;
2311 + byte[]* p;
2312 + uint i;
2313 + byte[] b;
2314 + auto size = ti.next.tsize(); // array element size
2315 +
2316 + p = cast(byte[]*)(&n + 1);
2317 +
2318 + for (i = 0; i < n; i++)
2319 + {
2320 + b = *p++;
2321 + length += b.length;
2322 + }
2323 + if (!length)
2324 + return null;
2325 +
2326 + a = gc_malloc(length * size, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2327 + p = cast(byte[]*)(&n + 1);
2328 +
2329 + uint j = 0;
2330 + for (i = 0; i < n; i++)
2331 + {
2332 + b = *p++;
2333 + if (b.length)
2334 + {
2335 + memcpy(a + j, b.ptr, b.length * size);
2336 + j += b.length * size;
2337 + }
2338 + }
2339 +
2340 + byte[] result;
2341 + *cast(int *)&result = length; // jam length
2342 + (cast(void **)&result)[1] = a; // jam ptr
2343 + return result;
2344 +}
2345 +
2346 +
2347 +/**
2348 + *
2349 + */
2350 +extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...)
2351 +{
2352 + auto sizeelem = ti.next.tsize(); // array element size
2353 + void* result;
2354 +
2355 + debug(PRINTF) printf("_d_arrayliteralT(sizeelem = %d, length = %d)\n", sizeelem, length);
2356 + if (length == 0 || sizeelem == 0)
2357 + result = null;
2358 + else
2359 + {
2360 + result = gc_malloc(length * sizeelem, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2361 +
2362 + va_list q;
2363 + va_start!(size_t)(q, length);
2364 +
2365 + size_t stacksize = (sizeelem + int.sizeof - 1) & ~(int.sizeof - 1);
2366 +
2367 + if (stacksize == sizeelem)
2368 + {
2369 + memcpy(result, q, length * sizeelem);
2370 + }
2371 + else
2372 + {
2373 + for (size_t i = 0; i < length; i++)
2374 + {
2375 + memcpy(result + i * sizeelem, q, sizeelem);
2376 + q += stacksize;
2377 + }
2378 + }
2379 +
2380 + va_end(q);
2381 + }
2382 + return result;
2383 +}
2384 +
2385 ++/
2386 +
2387 +
2388 +/**
2389 + * Support for array.dup property.
2390 + * The actual type is painted on the return value by the frontend
2391 + * Given length is number of elements
2392 + * Returned length is number of elements
2393 + */
2394 +
2395 +
2396 +/**
2397 + *
2398 + */
2399 +extern (C) void[] _adDupT(TypeInfo ti, void[] a)
2400 +out (result)
2401 +{
2402 + auto sizeelem = ti.next.tsize(); // array element size
2403 + assert(memcmp(result.ptr, a.ptr, a.length * sizeelem) == 0);
2404 +}
2405 +body
2406 +{
2407 + void* ptr;
2408 +
2409 + if (a.length)
2410 + {
2411 + auto sizeelem = ti.next.tsize(); // array element size
2412 + auto size = a.length * sizeelem;
2413 + ptr = gc_malloc(size, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2414 + memcpy(ptr, a.ptr, size);
2415 + }
2416 + return ptr[0 .. a.length];
2417 +}
2418 +
2419 +
2420 +unittest
2421 +{
2422 + int[] a;
2423 + int[] b;
2424 + int i;
2425 +
2426 + a = new int[3];
2427 + a[0] = 1; a[1] = 2; a[2] = 3;
2428 + b = a.dup;
2429 + assert(b.length == 3);
2430 + for (i = 0; i < 3; i++)
2431 + assert(b[i] == i + 1);
2432 +}
2433 Index: src/compiler/ldc/switch.d
2434 ===================================================================
2435 --- src/compiler/ldc/switch.d (revision 0)
2436 +++ src/compiler/ldc/switch.d (revision 0)
2437 @@ -0,0 +1,428 @@
2438 +/*
2439 + * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
2440 + * Written by Walter Bright
2441 + *
2442 + * This software is provided 'as-is', without any express or implied
2443 + * warranty. In no event will the authors be held liable for any damages
2444 + * arising from the use of this software.
2445 + *
2446 + * Permission is granted to anyone to use this software for any purpose,
2447 + * including commercial applications, and to alter it and redistribute it
2448 + * freely, in both source and binary form, subject to the following
2449 + * restrictions:
2450 + *
2451 + * o The origin of this software must not be misrepresented; you must not
2452 + * claim that you wrote the original software. If you use this software
2453 + * in a product, an acknowledgment in the product documentation would be
2454 + * appreciated but is not required.
2455 + * o Altered source versions must be plainly marked as such, and must not
2456 + * be misrepresented as being the original software.
2457 + * o This notice may not be removed or altered from any source
2458 + * distribution.
2459 + */
2460 +
2461 +/*
2462 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
2463 + */
2464 +
2465 +version( D_Version2 )
2466 +private import core.stdc.string;
2467 +else
2468 +private import tango.stdc.string;
2469 +//private import tango.stdc.stdio;
2470 +
2471 +/******************************************************
2472 + * Support for switch statements switching on strings.
2473 + * Input:
2474 + * table[] sorted array of strings generated by compiler
2475 + * ca string to look up in table
2476 + * Output:
2477 + * result index of match in table[]
2478 + * -1 if not in table
2479 + */
2480 +
2481 +extern (C):
2482 +
2483 +int _d_switch_string(char[][] table, char[] ca)
2484 +in
2485 +{
2486 + //printf("in _d_switch_string()\n");
2487 + assert(table.length >= 0);
2488 + assert(ca.length >= 0);
2489 +
2490 + // Make sure table[] is sorted correctly
2491 + int j;
2492 +
2493 + for (j = 1; j < table.length; j++)
2494 + {
2495 + size_t len1 = table[j - 1].length;
2496 + size_t len2 = table[j].length;
2497 +
2498 + assert(len1 <= len2);
2499 + if (len1 == len2)
2500 + {
2501 + int ci;
2502 +
2503 + ci = memcmp(table[j - 1].ptr, table[j].ptr, len1);
2504 + assert(ci < 0); // ci==0 means a duplicate
2505 + }
2506 + }
2507 +}
2508 +out (result)
2509 +{
2510 + int i;
2511 + int cj;
2512 +
2513 + //printf("out _d_switch_string()\n");
2514 + if (result == -1)
2515 + {
2516 + // Not found
2517 + for (i = 0; i < table.length; i++)
2518 + {
2519 + if (table[i].length == ca.length)
2520 + { cj = memcmp(table[i].ptr, ca.ptr, ca.length);
2521 + assert(cj != 0);
2522 + }
2523 + }
2524 + }
2525 + else
2526 + {
2527 + assert(0 <= result && result < table.length);
2528 + for (i = 0; 1; i++)
2529 + {
2530 + assert(i < table.length);
2531 + if (table[i].length == ca.length)
2532 + {
2533 + cj = memcmp(table[i].ptr, ca.ptr, ca.length);
2534 + if (cj == 0)
2535 + {
2536 + assert(i == result);
2537 + break;
2538 + }
2539 + }
2540 + }
2541 + }
2542 +}
2543 +body
2544 +{
2545 + //printf("body _d_switch_string(%.*s)\n", ca.length, ca.ptr);
2546 + size_t low;
2547 + size_t high;
2548 + size_t mid;
2549 + ptrdiff_t c;
2550 + char[] pca;
2551 +
2552 + low = 0;
2553 + high = table.length;
2554 +
2555 + version (none)
2556 + {
2557 + // Print table
2558 + printf("ca[] = '%s'\n", cast(char *)ca);
2559 + for (mid = 0; mid < high; mid++)
2560 + {
2561 + pca = table[mid];
2562 + printf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
2563 + }
2564 + }
2565 + if (high &&
2566 + ca.length >= table[0].length &&
2567 + ca.length <= table[high - 1].length)
2568 + {
2569 + // Looking for 0 length string, which would only be at the beginning
2570 + if (ca.length == 0)
2571 + return 0;
2572 +
2573 + char c1 = ca[0];
2574 +
2575 + // Do binary search
2576 + while (low < high)
2577 + {
2578 + mid = (low + high) >> 1;
2579 + pca = table[mid];
2580 + c = cast(ptrdiff_t)(ca.length - pca.length);
2581 + if (c == 0)
2582 + {
2583 + c = cast(ubyte)c1 - cast(ubyte)pca[0];
2584 + if (c == 0)
2585 + {
2586 + c = memcmp(ca.ptr, pca.ptr, ca.length);
2587 + if (c == 0)
2588 + { //printf("found %d\n", mid);
2589 + return cast(int)mid;
2590 + }
2591 + }
2592 + }
2593 + if (c < 0)
2594 + {
2595 + high = mid;
2596 + }
2597 + else
2598 + {
2599 + low = mid + 1;
2600 + }
2601 + }
2602 + }
2603 +
2604 + //printf("not found\n");
2605 + return -1; // not found
2606 +}
2607 +
2608 +unittest
2609 +{
2610 + switch (cast(char []) "c")
2611 + {
2612 + case "coo":
2613 + default:
2614 + break;
2615 + }
2616 +}
2617 +
2618 +/**********************************
2619 + * Same thing, but for wide chars.
2620 + */
2621 +
2622 +int _d_switch_ustring(wchar[][] table, wchar[] ca)
2623 +in
2624 +{
2625 + //printf("in _d_switch_ustring()\n");
2626 + assert(table.length >= 0);
2627 + assert(ca.length >= 0);
2628 +
2629 + // Make sure table[] is sorted correctly
2630 + int j;
2631 +
2632 + for (j = 1; j < table.length; j++)
2633 + {
2634 + size_t len1 = table[j - 1].length;
2635 + size_t len2 = table[j].length;
2636 +
2637 + assert(len1 <= len2);
2638 + if (len1 == len2)
2639 + {
2640 + int c;
2641 +
2642 + c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof);
2643 + assert(c < 0); // c==0 means a duplicate
2644 + }
2645 + }
2646 +}
2647 +out (result)
2648 +{
2649 + int i;
2650 + int c;
2651 +
2652 + //printf("out _d_switch_string()\n");
2653 + if (result == -1)
2654 + {
2655 + // Not found
2656 + for (i = 0; i < table.length; i++)
2657 + {
2658 + if (table[i].length == ca.length)
2659 + { c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
2660 + assert(c != 0);
2661 + }
2662 + }
2663 + }
2664 + else
2665 + {
2666 + assert(0 <= result && result < table.length);
2667 + for (i = 0; 1; i++)
2668 + {
2669 + assert(i < table.length);
2670 + if (table[i].length == ca.length)
2671 + {
2672 + c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
2673 + if (c == 0)
2674 + {
2675 + assert(i == result);
2676 + break;
2677 + }
2678 + }
2679 + }
2680 + }
2681 +}
2682 +body
2683 +{
2684 + //printf("body _d_switch_ustring()\n");
2685 + size_t low;
2686 + size_t high;
2687 + size_t mid;
2688 + ptrdiff_t c;
2689 + wchar[] pca;
2690 +
2691 + low = 0;
2692 + high = table.length;
2693 +
2694 +/*
2695 + // Print table
2696 + wprintf("ca[] = '%.*s'\n", ca);
2697 + for (mid = 0; mid < high; mid++)
2698 + {
2699 + pca = table[mid];
2700 + wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
2701 + }
2702 +*/
2703 +
2704 + // Do binary search
2705 + while (low < high)
2706 + {
2707 + mid = (low + high) >> 1;
2708 + pca = table[mid];
2709 + c = cast(ptrdiff_t)(ca.length - pca.length);
2710 + if (c == 0)
2711 + {
2712 + c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof);
2713 + if (c == 0)
2714 + { //printf("found %d\n", mid);
2715 + return cast(int)mid;
2716 + }
2717 + }
2718 + if (c < 0)
2719 + {
2720 + high = mid;
2721 + }
2722 + else
2723 + {
2724 + low = mid + 1;
2725 + }
2726 + }
2727 + //printf("not found\n");
2728 + return -1; // not found
2729 +}
2730 +
2731 +
2732 +unittest
2733 +{
2734 + switch (cast(wchar []) "c")
2735 + {
2736 + case "coo":
2737 + default:
2738 + break;
2739 + }
2740 +}
2741 +
2742 +
2743 +/**********************************
2744 + * Same thing, but for wide chars.
2745 + */
2746 +
2747 +int _d_switch_dstring(dchar[][] table, dchar[] ca)
2748 +in
2749 +{
2750 + //printf("in _d_switch_dstring()\n");
2751 + assert(table.length >= 0);
2752 + assert(ca.length >= 0);
2753 +
2754 + // Make sure table[] is sorted correctly
2755 + int j;
2756 +
2757 + for (j = 1; j < table.length; j++)
2758 + {
2759 + size_t len1 = table[j - 1].length;
2760 + size_t len2 = table[j].length;
2761 +
2762 + assert(len1 <= len2);
2763 + if (len1 == len2)
2764 + {
2765 + int c;
2766 +
2767 + c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof);
2768 + assert(c < 0); // c==0 means a duplicate
2769 + }
2770 + }
2771 +}
2772 +out (result)
2773 +{
2774 + int i;
2775 + int c;
2776 +
2777 + //printf("out _d_switch_string()\n");
2778 + if (result == -1)
2779 + {
2780 + // Not found
2781 + for (i = 0; i < table.length; i++)
2782 + {
2783 + if (table[i].length == ca.length)
2784 + { c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
2785 + assert(c != 0);
2786 + }
2787 + }
2788 + }
2789 + else
2790 + {
2791 + assert(0 <= result && result < table.length);
2792 + for (i = 0; 1; i++)
2793 + {
2794 + assert(i < table.length);
2795 + if (table[i].length == ca.length)
2796 + {
2797 + c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
2798 + if (c == 0)
2799 + {
2800 + assert(i == result);
2801 + break;
2802 + }
2803 + }
2804 + }
2805 + }
2806 +}
2807 +body
2808 +{
2809 + //printf("body _d_switch_ustring()\n");
2810 + size_t low;
2811 + size_t high;
2812 + size_t mid;
2813 + ptrdiff_t c;
2814 + dchar[] pca;
2815 +
2816 + low = 0;
2817 + high = table.length;
2818 +
2819 +/*
2820 + // Print table
2821 + wprintf("ca[] = '%.*s'\n", ca);
2822 + for (mid = 0; mid < high; mid++)
2823 + {
2824 + pca = table[mid];
2825 + wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
2826 + }
2827 +*/
2828 +
2829 + // Do binary search
2830 + while (low < high)
2831 + {
2832 + mid = (low + high) >> 1;
2833 + pca = table[mid];
2834 + c = cast(ptrdiff_t)(ca.length - pca.length);
2835 + if (c == 0)
2836 + {
2837 + c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);
2838 + if (c == 0)
2839 + { //printf("found %d\n", mid);
2840 + return cast(int)mid;
2841 + }
2842 + }
2843 + if (c < 0)
2844 + {
2845 + high = mid;
2846 + }
2847 + else
2848 + {
2849 + low = mid + 1;
2850 + }
2851 + }
2852 + //printf("not found\n");
2853 + return -1; // not found
2854 +}
2855 +
2856 +
2857 +unittest
2858 +{
2859 + switch (cast(dchar []) "c")
2860 + {
2861 + case "coo":
2862 + default:
2863 + break;
2864 + }
2865 +}
2866 Index: src/compiler/ldc/arrayInit.d
2867 ===================================================================
2868 --- src/compiler/ldc/arrayInit.d (revision 0)
2869 +++ src/compiler/ldc/arrayInit.d (revision 0)
2870 @@ -0,0 +1,158 @@
2871 +private import ldc.intrinsics;
2872 +
2873 +extern(C):
2874 +
2875 +int memcmp(void*,void*,size_t);
2876 +size_t strlen(char*);
2877 +
2878 +version(LLVM64)
2879 +alias llvm_memcpy_i64 llvm_memcpy;
2880 +else
2881 +alias llvm_memcpy_i32 llvm_memcpy;
2882 +
2883 +// per-element array init routines
2884 +
2885 +void _d_array_init_i1(bool* a, size_t n, bool v)
2886 +{
2887 + auto p = a;
2888 + auto end = a+n;
2889 + while (p !is end)
2890 + *p++ = v;
2891 +}
2892 +
2893 +void _d_array_init_i8(ubyte* a, size_t n, ubyte v)
2894 +{
2895 + auto p = a;
2896 + auto end = a+n;
2897 + while (p !is end)
2898 + *p++ = v;
2899 +}
2900 +
2901 +void _d_array_init_i16(ushort* a, size_t n, ushort v)
2902 +{
2903 + auto p = a;
2904 + auto end = a+n;
2905 + while (p !is end)
2906 + *p++ = v;
2907 +}
2908 +
2909 +void _d_array_init_i32(uint* a, size_t n, uint v)
2910 +{
2911 + auto p = a;
2912 + auto end = a+n;
2913 + while (p !is end)
2914 + *p++ = v;
2915 +}
2916 +
2917 +void _d_array_init_i64(ulong* a, size_t n, ulong v)
2918 +{
2919 + auto p = a;
2920 + auto end = a+n;
2921 + while (p !is end)
2922 + *p++ = v;
2923 +}
2924 +
2925 +void _d_array_init_float(float* a, size_t n, float v)
2926 +{
2927 + auto p = a;
2928 + auto end = a+n;
2929 + while (p !is end)
2930 + *p++ = v;
2931 +}
2932 +
2933 +void _d_array_init_double(double* a, size_t n, double v)
2934 +{
2935 + auto p = a;
2936 + auto end = a+n;
2937 + while (p !is end)
2938 + *p++ = v;
2939 +}
2940 +
2941 +void _d_array_init_real(real* a, size_t n, real v)
2942 +{
2943 + auto p = a;
2944 + auto end = a+n;
2945 + while (p !is end)
2946 + *p++ = v;
2947 +}
2948 +
2949 +void _d_array_init_cfloat(cfloat* a, size_t n, cfloat v)
2950 +{
2951 + auto p = a;
2952 + auto end = a+n;
2953 + while (p !is end)
2954 + *p++ = v;
2955 +}
2956 +
2957 +void _d_array_init_cdouble(cdouble* a, size_t n, cdouble v)
2958 +{
2959 + auto p = a;
2960 + auto end = a+n;
2961 + while (p !is end)
2962 + *p++ = v;
2963 +}
2964 +
2965 +void _d_array_init_creal(creal* a, size_t n, creal v)
2966 +{
2967 + auto p = a;
2968 + auto end = a+n;
2969 + while (p !is end)
2970 + *p++ = v;
2971 +}
2972 +
2973 +void _d_array_init_pointer(void** a, size_t n, void* v)
2974 +{
2975 + auto p = a;
2976 + auto end = a+n;
2977 + while (p !is end)
2978 + *p++ = v;
2979 +}
2980 +
2981 +void _d_array_init_mem(void* a, size_t na, void* v, size_t nv)
2982 +{
2983 + auto p = a;
2984 + auto end = a + na*nv;
2985 + while (p !is end) {
2986 + llvm_memcpy(p,v,nv,0);
2987 + p += nv;
2988 + }
2989 +}
2990 +
2991 +/*
2992 +void _d_array_init(TypeInfo ti, void* a)
2993 +{
2994 + auto initializer = ti.next.init();
2995 + auto isize = initializer.length;
2996 + auto q = initializer.ptr;
2997 +
2998 + if (isize == 1)
2999 + memset(p, *cast(ubyte*)q, size);
3000 + else if (isize == int.sizeof)
3001 + {
3002 + int init = *cast(int*)q;
3003 + size /= int.sizeof;
3004 + for (size_t u = 0; u < size; u++)
3005 + {
3006 + (cast(int*)p)[u] = init;
3007 + }
3008 + }
3009 + else
3010 + {
3011 + for (size_t u = 0; u < size; u += isize)
3012 + {
3013 + memcpy(p + u, q, isize);
3014 + }
3015 + }
3016 +}*/
3017 +
3018 +// for array cast
3019 +size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
3020 +{
3021 + if (newelemsz == 1) {
3022 + return len*elemsz;
3023 + }
3024 + else if ((len*elemsz) % newelemsz) {
3025 + throw new Exception("Bad array cast");
3026 + }
3027 + return (len*elemsz)/newelemsz;
3028 +}
3029 Index: src/compiler/ldc/genobj.d
3030 ===================================================================
3031 --- src/compiler/ldc/genobj.d (revision 0)
3032 +++ src/compiler/ldc/genobj.d (revision 0)
3033 @@ -0,0 +1,1525 @@
3034 +/**
3035 + * Part of the D programming language runtime library.
3036 + * Forms the symbols available to all D programs. Includes
3037 + * Object, which is the root of the class object hierarchy.
3038 + *
3039 + * This module is implicitly imported.
3040 + * Macros:
3041 + * WIKI = Object
3042 + */
3043 +
3044 +/*
3045 + * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
3046 + * Written by Walter Bright
3047 + *
3048 + * This software is provided 'as-is', without any express or implied
3049 + * warranty. In no event will the authors be held liable for any damages
3050 + * arising from the use of this software.
3051 + *
3052 + * Permission is granted to anyone to use this software for any purpose,
3053 + * including commercial applications, and to alter it and redistribute it
3054 + * freely, in both source and binary form, subject to the following
3055 + * restrictions:
3056 + *
3057 + * o The origin of this software must not be misrepresented; you must not
3058 + * claim that you wrote the original software. If you use this software
3059 + * in a product, an acknowledgment in the product documentation would be
3060 + * appreciated but is not required.
3061 + * o Altered source versions must be plainly marked as such, and must not
3062 + * be misrepresented as being the original software.
3063 + * o This notice may not be removed or altered from any source
3064 + * distribution.
3065 + */
3066 +
3067 +/*
3068 + * Modified by Sean Kelly for use with the D Runtime Project
3069 + */
3070 +
3071 +/*
3072 + * Modified by Tomas Lindquist Olsen for use with the LLVM D Compiler
3073 + */
3074 +
3075 +module object;
3076 +
3077 +private
3078 +{
3079 + import core.stdc.string;
3080 + import core.stdc.stdlib;
3081 + import util.string;
3082 + debug(PRINTF) import stdc.stdio;
3083 +
3084 + extern (C) void onOutOfMemoryError();
3085 + extern (C) Object _d_allocclass(ClassInfo ci);
3086 +}
3087 +
3088 +// NOTE: For some reason, this declaration method doesn't work
3089 +// in this particular file (and this file only). It must
3090 +// be a DMD thing.
3091 +//alias typeof(int.sizeof) size_t;
3092 +//alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
3093 +
3094 +version(X86_64)
3095 +{
3096 + alias ulong size_t;
3097 + alias long ptrdiff_t;
3098 +}
3099 +else
3100 +{
3101 + alias uint size_t;
3102 + alias int ptrdiff_t;
3103 +}
3104 +
3105 +alias size_t hash_t;
3106 +alias bool equals_t;
3107 +
3108 +alias invariant(char)[] string;
3109 +alias invariant(wchar)[] wstring;
3110 +alias invariant(dchar)[] dstring;
3111 +
3112 +/**
3113 + * All D class objects inherit from Object.
3114 + */
3115 +class Object
3116 +{
3117 + /**
3118 + * Convert Object to a human readable string.
3119 + */
3120 + string toString()
3121 + {
3122 + return this.classinfo.name;
3123 + }
3124 +
3125 + /**
3126 + * Compute hash function for Object.
3127 + */
3128 + hash_t toHash()
3129 + {
3130 + // BUG: this prevents a compacting GC from working, needs to be fixed
3131 + return cast(hash_t)cast(void*)this;
3132 + }
3133 +
3134 + /**
3135 + * Compare with another Object obj.
3136 + * Returns:
3137 + * $(TABLE
3138 + * $(TR $(TD this &lt; obj) $(TD &lt; 0))
3139 + * $(TR $(TD this == obj) $(TD 0))
3140 + * $(TR $(TD this &gt; obj) $(TD &gt; 0))
3141 + * )
3142 + */
3143 + int opCmp(Object o)
3144 + {
3145 + // BUG: this prevents a compacting GC from working, needs to be fixed
3146 + //return cast(int)cast(void*)this - cast(int)cast(void*)o;
3147 +
3148 + throw new Exception("need opCmp for class " ~ this.classinfo.name);
3149 + //return this !is o;
3150 + }
3151 +
3152 + /**
3153 + * Returns !=0 if this object does have the same contents as obj.
3154 + */
3155 + equals_t opEquals(Object o)
3156 + {
3157 + return this is o;
3158 + }
3159 +
3160 + interface Monitor
3161 + {
3162 + void lock();
3163 + void unlock();
3164 + }
3165 +
3166 + /**
3167 + * Create instance of class specified by classname.
3168 + * The class must either have no constructors or have
3169 + * a default constructor.
3170 + * Returns:
3171 + * null if failed
3172 + */
3173 + static Object factory(string classname)
3174 + {
3175 + auto ci = ClassInfo.find(classname);
3176 + if (ci)
3177 + {
3178 + return ci.create();
3179 + }
3180 + return null;
3181 + }
3182 +}
3183 +
3184 +/**
3185 + * Information about an interface.
3186 + * When an object is accessed via an interface, an Interface* appears as the
3187 + * first entry in its vtbl.
3188 + */
3189 +struct Interface
3190 +{
3191 + ClassInfo classinfo; /// .classinfo for this interface (not for containing class)
3192 + void*[] vtbl;
3193 + ptrdiff_t offset; /// offset to Interface 'this' from Object 'this'
3194 +}
3195 +
3196 +/**
3197 + * Runtime type information about a class. Can be retrieved for any class type
3198 + * or instance by using the .classinfo property.
3199 + * A pointer to this appears as the first entry in the class's vtbl[].
3200 + */
3201 +class ClassInfo : Object
3202 +{
3203 + byte[] init; /** class static initializer
3204 + * (init.length gives size in bytes of class)
3205 + */
3206 + string name; /// class name
3207 + void*[] vtbl; /// virtual function pointer table
3208 + Interface[] interfaces; /// interfaces this class implements
3209 + ClassInfo base; /// base class
3210 + void* destructor;
3211 + void function(Object) classInvariant;
3212 + uint flags;
3213 + // 1: // is IUnknown or is derived from IUnknown
3214 + // 2: // has no possible pointers into GC memory
3215 + // 4: // has offTi[] member
3216 + // 8: // has constructors
3217 + // 16: // has xgetMembers member
3218 + void* deallocator;
3219 + OffsetTypeInfo[] offTi;
3220 + void function(Object) defaultConstructor; // default Constructor
3221 + const(MemberInfo[]) function(in char[]) xgetMembers;
3222 +
3223 + /**
3224 + * Search all modules for ClassInfo corresponding to classname.
3225 + * Returns: null if not found
3226 + */
3227 + static ClassInfo find(in char[] classname)
3228 + {
3229 + foreach (m; ModuleInfo)
3230 + {
3231 + //writefln("module %s, %d", m.name, m.localClasses.length);
3232 + foreach (c; m.localClasses)
3233 + {
3234 + //writefln("\tclass %s", c.name);
3235 + if (c.name == classname)
3236 + return c;
3237 + }
3238 + }
3239 + return null;
3240 + }
3241 +
3242 + /**
3243 + * Create instance of Object represented by 'this'.
3244 + */
3245 + Object create()
3246 + {
3247 + if (flags & 8 && !defaultConstructor)
3248 + return null;
3249 +
3250 + Object o = _d_allocclass(this);
3251 + // initialize it
3252 + (cast(byte*) o)[0 .. init.length] = init[];
3253 +
3254 + if (flags & 8 && defaultConstructor)
3255 + {
3256 + defaultConstructor(o);
3257 + }
3258 + return o;
3259 + }
3260 +
3261 + /**
3262 + * Search for all members with the name 'name'.
3263 + * If name[] is null, return all members.
3264 + */
3265 + const(MemberInfo[]) getMembers(in char[] name)
3266 + {
3267 + if (flags & 16 && xgetMembers)
3268 + return xgetMembers(name);
3269 + return null;
3270 + }
3271 +}
3272 +
3273 +/**
3274 + * Array of pairs giving the offset and type information for each
3275 + * member in an aggregate.
3276 + */
3277 +struct OffsetTypeInfo
3278 +{
3279 + size_t offset; /// Offset of member from start of object
3280 + TypeInfo ti; /// TypeInfo for this member
3281 +}
3282 +
3283 +/**
3284 + * Runtime type information about a type.
3285 + * Can be retrieved for any type using a
3286 + * <a href="../expression.html#typeidexpression">TypeidExpression</a>.
3287 + */
3288 +class TypeInfo
3289 +{
3290 + override hash_t toHash()
3291 + {
3292 + hash_t hash;
3293 +
3294 + foreach (char c; this.toString())
3295 + hash = hash * 9 + c;
3296 + return hash;
3297 + }
3298 +
3299 + override int opCmp(Object o)
3300 + {
3301 + if (this is o)
3302 + return 0;
3303 + TypeInfo ti = cast(TypeInfo)o;
3304 + if (ti is null)
3305 + return 1;
3306 + return dstrcmp(this.toString(), ti.toString());
3307 + }
3308 +
3309 + override equals_t opEquals(Object o)
3310 + {
3311 + /* TypeInfo instances are singletons, but duplicates can exist
3312 + * across DLL's. Therefore, comparing for a name match is
3313 + * sufficient.
3314 + */
3315 + if (this is o)
3316 + return true;
3317 + TypeInfo ti = cast(TypeInfo)o;
3318 + return ti && this.toString() == ti.toString();
3319 + }
3320 +
3321 + /// Returns a hash of the instance of a type.
3322 + hash_t getHash(in void* p) { return cast(hash_t)p; }
3323 +
3324 + /// Compares two instances for equality.
3325 + equals_t equals(in void* p1, in void* p2) { return p1 == p2; }
3326 +
3327 + /// Compares two instances for &lt;, ==, or &gt;.
3328 + int compare(in void* p1, in void* p2) { return 0; }
3329 +
3330 + /// Returns size of the type.
3331 + size_t tsize() { return 0; }
3332 +
3333 + /// Swaps two instances of the type.
3334 + void swap(void* p1, void* p2)
3335 + {
3336 + size_t n = tsize();
3337 + for (size_t i = 0; i < n; i++)
3338 + {
3339 + byte t = (cast(byte *)p1)[i];
3340 + (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
3341 + (cast(byte*)p2)[i] = t;
3342 + }
3343 + }
3344 +
3345 + /// Get TypeInfo for 'next' type, as defined by what kind of type this is,
3346 + /// null if none.
3347 + TypeInfo next() { return null; }
3348 +
3349 + /// Return default initializer, null if default initialize to 0
3350 + void[] init() { return null; }
3351 +
3352 + /// Get flags for type: 1 means GC should scan for pointers
3353 + uint flags() { return 0; }
3354 +
3355 + /// Get type information on the contents of the type; null if not available
3356 + OffsetTypeInfo[] offTi() { return null; }
3357 + /// Run the destructor on the object and all its sub-objects
3358 + void destroy(void* p) {}
3359 + /// Run the postblit on the object and all its sub-objects
3360 + void postblit(void* p) {}
3361 +}
3362 +
3363 +class TypeInfo_Typedef : TypeInfo
3364 +{
3365 + override string toString() { return name; }
3366 +
3367 + override equals_t opEquals(Object o)
3368 + {
3369 + TypeInfo_Typedef c;
3370 + return this is o ||
3371 + ((c = cast(TypeInfo_Typedef)o) !is null &&
3372 + this.name == c.name &&
3373 + this.base == c.base);
3374 + }
3375 +
3376 + override hash_t getHash(in void* p) { return base.getHash(p); }
3377 + override equals_t equals(in void* p1, in void* p2) { return base.equals(p1, p2); }
3378 + override int compare(in void* p1, in void* p2) { return base.compare(p1, p2); }
3379 + override size_t tsize() { return base.tsize(); }
3380 + override void swap(void* p1, void* p2) { return base.swap(p1, p2); }
3381 +
3382 + override TypeInfo next() { return base.next(); }
3383 + override uint flags() { return base.flags(); }
3384 + override void[] init() { return m_init.length ? m_init : base.init(); }
3385 +
3386 + TypeInfo base;
3387 + string name;
3388 + void[] m_init;
3389 +}
3390 +
3391 +class TypeInfo_Enum : TypeInfo_Typedef
3392 +{
3393 +
3394 +}
3395 +
3396 +class TypeInfo_Pointer : TypeInfo
3397 +{
3398 + override string toString() { return m_next.toString() ~ "*"; }
3399 +
3400 + override equals_t opEquals(Object o)
3401 + {
3402 + TypeInfo_Pointer c;
3403 + return this is o ||
3404 + ((c = cast(TypeInfo_Pointer)o) !is null &&
3405 + this.m_next == c.m_next);
3406 + }
3407 +
3408 + override hash_t getHash(in void* p)
3409 + {
3410 + return cast(hash_t)*cast(void**)p;
3411 + }
3412 +
3413 + override equals_t equals(in void* p1, in void* p2)
3414 + {
3415 + return *cast(void**)p1 == *cast(void**)p2;
3416 + }
3417 +
3418 + override int compare(in void* p1, in void* p2)
3419 + {
3420 + if (*cast(void**)p1 < *cast(void**)p2)
3421 + return -1;
3422 + else if (*cast(void**)p1 > *cast(void**)p2)
3423 + return 1;
3424 + else
3425 + return 0;
3426 + }
3427 +
3428 + override size_t tsize()
3429 + {
3430 + return (void*).sizeof;
3431 + }
3432 +
3433 + override void swap(void* p1, void* p2)
3434 + {
3435 + void* tmp = *cast(void**)p1;
3436 + *cast(void**)p1 = *cast(void**)p2;
3437 + *cast(void**)p2 = tmp;
3438 + }
3439 +
3440 + override TypeInfo next() { return m_next; }
3441 + override uint flags() { return 1; }
3442 +
3443 + TypeInfo m_next;
3444 +}
3445 +
3446 +class TypeInfo_Array : TypeInfo
3447 +{
3448 + override string toString() { return value.toString() ~ "[]"; }
3449 +
3450 + override equals_t opEquals(Object o)
3451 + {
3452 + TypeInfo_Array c;
3453 + return this is o ||
3454 + ((c = cast(TypeInfo_Array)o) !is null &&
3455 + this.value == c.value);
3456 + }
3457 +
3458 + override hash_t getHash(in void* p)
3459 + {
3460 + size_t sz = value.tsize();
3461 + hash_t hash = 0;
3462 + void[] a = *cast(void[]*)p;
3463 + for (size_t i = 0; i < a.length; i++)
3464 + hash += value.getHash(a.ptr + i * sz);
3465 + return hash;
3466 + }
3467 +
3468 + override equals_t equals(in void* p1, in void* p2)
3469 + {
3470 + void[] a1 = *cast(void[]*)p1;
3471 + void[] a2 = *cast(void[]*)p2;
3472 + if (a1.length != a2.length)
3473 + return false;
3474 + size_t sz = value.tsize();
3475 + for (size_t i = 0; i < a1.length; i++)
3476 + {
3477 + if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))
3478 + return false;
3479 + }
3480 + return true;
3481 + }
3482 +
3483 + override int compare(in void* p1, in void* p2)
3484 + {
3485 + void[] a1 = *cast(void[]*)p1;
3486 + void[] a2 = *cast(void[]*)p2;
3487 + size_t sz = value.tsize();
3488 + size_t len = a1.length;
3489 +
3490 + if (a2.length < len)
3491 + len = a2.length;
3492 + for (size_t u = 0; u < len; u++)
3493 + {
3494 + int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
3495 + if (result)
3496 + return result;
3497 + }
3498 + return cast(int)a1.length - cast(int)a2.length;
3499 + }
3500 +
3501 + override size_t tsize()
3502 + {
3503 + return (void[]).sizeof;
3504 + }
3505 +
3506 + override void swap(void* p1, void* p2)
3507 + {
3508 + void[] tmp = *cast(void[]*)p1;
3509 + *cast(void[]*)p1 = *cast(void[]*)p2;
3510 + *cast(void[]*)p2 = tmp;
3511 + }
3512 +
3513 + TypeInfo value;
3514 +
3515 + override TypeInfo next()
3516 + {
3517 + return value;
3518 + }
3519 +
3520 + override uint flags() { return 1; }
3521 +}
3522 +
3523 +class TypeInfo_StaticArray : TypeInfo
3524 +{
3525 + override string toString()
3526 + {
3527 + char[10] tmp = void;
3528 + return cast(string)(value.toString() ~ "[" ~ tmp.intToString(len) ~ "]");
3529 + }
3530 +
3531 + override equals_t opEquals(Object o)
3532 + {
3533 + TypeInfo_StaticArray c;
3534 + return this is o ||
3535 + ((c = cast(TypeInfo_StaticArray)o) !is null &&
3536 + this.len == c.len &&
3537 + this.value == c.value);
3538 + }
3539 +
3540 + override hash_t getHash(in void* p)
3541 + {
3542 + size_t sz = value.tsize();
3543 + hash_t hash = 0;
3544 + for (size_t i = 0; i < len; i++)
3545 + hash += value.getHash(p + i * sz);
3546 + return hash;
3547 + }
3548 +
3549 + override equals_t equals(in void* p1, in void* p2)
3550 + {
3551 + size_t sz = value.tsize();
3552 +
3553 + for (size_t u = 0; u < len; u++)
3554 + {
3555 + if (!value.equals(p1 + u * sz, p2 + u * sz))
3556 + return false;
3557 + }
3558 + return true;
3559 + }
3560 +
3561 + override int compare(in void* p1, in void* p2)
3562 + {
3563 + size_t sz = value.tsize();
3564 +
3565 + for (size_t u = 0; u < len; u++)
3566 + {
3567 + int result = value.compare(p1 + u * sz, p2 + u * sz);
3568 + if (result)
3569 + return result;
3570 + }
3571 + return 0;
3572 + }
3573 +
3574 + override size_t tsize()
3575 + {
3576 + return len * value.tsize();
3577 + }
3578 +
3579 + override void swap(void* p1, void* p2)
3580 + {
3581 + void* tmp;
3582 + size_t sz = value.tsize();
3583 + ubyte[16] buffer;
3584 + void* pbuffer;
3585 +
3586 + if (sz < buffer.sizeof)
3587 + tmp = buffer.ptr;
3588 + else
3589 + tmp = pbuffer = (new void[sz]).ptr;
3590 +
3591 + for (size_t u = 0; u < len; u += sz)
3592 + { size_t o = u * sz;
3593 + memcpy(tmp, p1 + o, sz);
3594 + memcpy(p1 + o, p2 + o, sz);
3595 + memcpy(p2 + o, tmp, sz);
3596 + }
3597 + if (pbuffer)
3598 + delete pbuffer;
3599 + }
3600 +
3601 + override void[] init() { return value.init(); }
3602 + override TypeInfo next() { return value; }
3603 + override uint flags() { return value.flags(); }
3604 +
3605 + override void destroy(void* p)
3606 + {
3607 + auto sz = value.tsize();
3608 + p += sz * len;
3609 + foreach (i; 0 .. len)
3610 + {
3611 + p -= sz;
3612 + value.destroy(p);
3613 + }
3614 + }
3615 +
3616 + override void postblit(void* p)
3617 + {
3618 + auto sz = value.tsize();
3619 + foreach (i; 0 .. len)
3620 + {
3621 + value.postblit(p);
3622 + p += sz;
3623 + }
3624 + }
3625 +
3626 + TypeInfo value;
3627 + size_t len;
3628 +}
3629 +
3630 +class TypeInfo_AssociativeArray : TypeInfo
3631 +{
3632 + override string toString()
3633 + {
3634 + return cast(string)(next.toString() ~ "[" ~ key.toString() ~ "]");
3635 + }
3636 +
3637 + override equals_t opEquals(Object o)
3638 + {
3639 + TypeInfo_AssociativeArray c;
3640 + return this is o ||
3641 + ((c = cast(TypeInfo_AssociativeArray)o) !is null &&
3642 + this.key == c.key &&
3643 + this.value == c.value);
3644 + }
3645 +
3646 + // BUG: need to add the rest of the functions
3647 +
3648 + override size_t tsize()
3649 + {
3650 + return (char[int]).sizeof;
3651 + }
3652 +
3653 + override TypeInfo next() { return value; }
3654 + override uint flags() { return 1; }
3655 +
3656 + TypeInfo value;
3657 + TypeInfo key;
3658 +}
3659 +
3660 +class TypeInfo_Function : TypeInfo
3661 +{
3662 + override string toString()
3663 + {
3664 + return cast(string)(next.toString() ~ "()");
3665 + }
3666 +
3667 + override equals_t opEquals(Object o)
3668 + {
3669 + TypeInfo_Function c;
3670 + return this is o ||
3671 + ((c = cast(TypeInfo_Function)o) !is null &&
3672 + this.next == c.next);
3673 + }
3674 +
3675 + // BUG: need to add the rest of the functions
3676 +
3677 + override size_t tsize()
3678 + {
3679 + return 0; // no size for functions
3680 + }
3681 +
3682 + TypeInfo next;
3683 +}
3684 +
3685 +class TypeInfo_Delegate : TypeInfo
3686 +{
3687 + override string toString()
3688 + {
3689 + return cast(string)(next.toString() ~ " delegate()");
3690 + }
3691 +
3692 + override equals_t opEquals(Object o)
3693 + {
3694 + TypeInfo_Delegate c;
3695 + return this is o ||
3696 + ((c = cast(TypeInfo_Delegate)o) !is null &&
3697 + this.next == c.next);
3698 + }
3699 +
3700 + // BUG: need to add the rest of the functions
3701 +
3702 + override size_t tsize()
3703 + {
3704 + alias int delegate() dg;
3705 + return dg.sizeof;
3706 + }
3707 +
3708 + override uint flags() { return 1; }
3709 +
3710 + TypeInfo next;
3711 +}
3712 +
3713 +class TypeInfo_Class : TypeInfo
3714 +{
3715 + override string toString() { return info.name; }
3716 +
3717 + override equals_t opEquals(Object o)
3718 + {
3719 + TypeInfo_Class c;
3720 + return this is o ||
3721 + ((c = cast(TypeInfo_Class)o) !is null &&
3722 + this.info.name == c.classinfo.name);
3723 + }
3724 +
3725 + override hash_t getHash(in void* p)
3726 + {
3727 + Object o = *cast(Object*)p;
3728 + return o ? o.toHash() : 0;
3729 + }
3730 +
3731 + override equals_t equals(in void* p1, in void* p2)
3732 + {
3733 + Object o1 = *cast(Object*)p1;
3734 + Object o2 = *cast(Object*)p2;
3735 +
3736 + return (o1 is o2) || (o1 && o1.opEquals(o2));
3737 + }
3738 +
3739 + override int compare(in void* p1, in void* p2)
3740 + {
3741 + Object o1 = *cast(Object*)p1;
3742 + Object o2 = *cast(Object*)p2;
3743 + int c = 0;
3744 +
3745 + // Regard null references as always being "less than"
3746 + if (o1 !is o2)
3747 + {
3748 + if (o1)
3749 + {
3750 + if (!o2)
3751 + c = 1;
3752 + else
3753 + c = o1.opCmp(o2);
3754 + }
3755 + else
3756 + c = -1;
3757 + }
3758 + return c;
3759 + }
3760 +
3761 + override size_t tsize()
3762 + {
3763 + return Object.sizeof;
3764 + }
3765 +
3766 + override uint flags() { return 1; }
3767 +
3768 + override OffsetTypeInfo[] offTi()
3769 + {
3770 + return (info.flags & 4) ? info.offTi : null;
3771 + }
3772 +
3773 + ClassInfo info;
3774 +}
3775 +
3776 +class TypeInfo_Interface : TypeInfo
3777 +{
3778 + override string toString() { return info.name; }
3779 +
3780 + override equals_t opEquals(Object o)
3781 + {
3782 + TypeInfo_Interface c;
3783 + return this is o ||
3784 + ((c = cast(TypeInfo_Interface)o) !is null &&
3785 + this.info.name == c.classinfo.name);
3786 + }
3787 +
3788 + override hash_t getHash(in void* p)
3789 + {
3790 + Interface* pi = **cast(Interface ***)*cast(void**)p;
3791 + Object o = cast(Object)(*cast(void**)p - pi.offset);
3792 + assert(o);
3793 + return o.toHash();
3794 + }
3795 +
3796 + override equals_t equals(in void* p1, in void* p2)
3797 + {
3798 + Interface* pi = **cast(Interface ***)*cast(void**)p1;
3799 + Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
3800 + pi = **cast(Interface ***)*cast(void**)p2;
3801 + Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
3802 +
3803 + return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
3804 + }
3805 +
3806 + override int compare(in void* p1, in void* p2)
3807 + {
3808 + Interface* pi = **cast(Interface ***)*cast(void**)p1;
3809 + Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
3810 + pi = **cast(Interface ***)*cast(void**)p2;
3811 + Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
3812 + int c = 0;
3813 +
3814 + // Regard null references as always being "less than"
3815 + if (o1 != o2)
3816 + {
3817 + if (o1)
3818 + {
3819 + if (!o2)
3820 + c = 1;
3821 + else
3822 + c = o1.opCmp(o2);
3823 + }
3824 + else
3825 + c = -1;
3826 + }
3827 + return c;
3828 + }
3829 +
3830 + override size_t tsize()
3831 + {
3832 + return Object.sizeof;
3833 + }
3834 +
3835 + override uint flags() { return 1; }
3836 +
3837 + ClassInfo info;
3838 +}
3839 +
3840 +class TypeInfo_Struct : TypeInfo
3841 +{
3842 + override string toString() { return name; }
3843 +
3844 + override equals_t opEquals(Object o)
3845 + {
3846 + TypeInfo_Struct s;
3847 + return this is o ||
3848 + ((s = cast(TypeInfo_Struct)o) !is null &&
3849 + this.name == s.name &&
3850 + this.init.length == s.init.length);
3851 + }
3852 +
3853 + override hash_t getHash(in void* p)
3854 + {
3855 + assert(p);
3856 + if (xtoHash)
3857 + {
3858 + debug(PRINTF) printf("getHash() using xtoHash\n");
3859 + return (*xtoHash)(p);
3860 + }
3861 + else
3862 + {
3863 + hash_t h;
3864 + debug(PRINTF) printf("getHash() using default hash\n");
3865 + // A sorry hash algorithm.
3866 + // Should use the one for strings.
3867 + // BUG: relies on the GC not moving objects
3868 + auto q = cast(const(ubyte)*)p;
3869 + for (size_t i = 0; i < init.length; i++)
3870 + {
3871 + h = h * 9 + *q;
3872 + q++;
3873 + }
3874 + return h;
3875 + }
3876 + }
3877 +
3878 + override equals_t equals(in void* p1, in void* p2)
3879 + {
3880 + if (p1 == p2)
3881 + return true;
3882 + else if (!p1 || !p2)
3883 + return false;
3884 + else if (xopEquals)
3885 + return (*xopEquals)(p1, p2);
3886 + else
3887 + // BUG: relies on the GC not moving objects
3888 + return memcmp(p1, p2, init.length) == 0;
3889 + }
3890 +
3891 + override int compare(in void* p1, in void* p2)
3892 + {
3893 + // Regard null references as always being "less than"
3894 + if (p1 != p2)
3895 + {
3896 + if (p1)
3897 + {
3898 + if (!p2)
3899 + return true;
3900 + else if (xopCmp)
3901 + return (*xopCmp)(p2, p1);
3902 + else
3903 + // BUG: relies on the GC not moving objects
3904 + return memcmp(p1, p2, init.length);
3905 + }
3906 + else
3907 + return -1;
3908 + }
3909 + return 0;
3910 + }
3911 +
3912 + override size_t tsize()
3913 + {
3914 + return init.length;
3915 + }
3916 +
3917 + override void[] init() { return m_init; }
3918 +
3919 + override uint flags() { return m_flags; }
3920 +
3921 + override void destroy(void* p)
3922 + {
3923 + if (xdtor)
3924 + (*xdtor)(p);
3925 + }
3926 +
3927 + override void postblit(void* p)
3928 + {
3929 + if (xpostblit)
3930 + (*xpostblit)(p);
3931 + }
3932 +
3933 + string name;
3934 + void[] m_init; // initializer; init.ptr == null if 0 initialize
3935 +
3936 + hash_t function(in void*) xtoHash;
3937 + equals_t function(in void*, in void*) xopEquals;
3938 + int function(in void*, in void*) xopCmp;
3939 + char[] function(in void*) xtoString;
3940 +
3941 + uint m_flags;
3942 +
3943 + const(MemberInfo[]) function(in char[]) xgetMembers;
3944 + void function(void*) xdtor;
3945 + void function(void*) xpostblit;
3946 +}
3947 +
3948 +class TypeInfo_Tuple : TypeInfo
3949 +{
3950 + TypeInfo[] elements;
3951 +
3952 + override string toString()
3953 + {
3954 + string s = "(";
3955 + foreach (i, element; elements)
3956 + {
3957 + if (i)
3958 + s ~= ',';
3959 + s ~= element.toString();
3960 + }
3961 + s ~= ")";
3962 + return s;
3963 + }
3964 +
3965 + override equals_t opEquals(Object o)
3966 + {
3967 + if (this is o)
3968 + return true;
3969 +
3970 + auto t = cast(TypeInfo_Tuple)o;
3971 + if (t && elements.length == t.elements.length)
3972 + {
3973 + for (size_t i = 0; i < elements.length; i++)
3974 + {
3975 + if (elements[i] != t.elements[i])
3976 + return false;
3977 + }
3978 + return true;
3979 + }
3980 + return false;
3981 + }
3982 +
3983 + override hash_t getHash(in void* p)
3984 + {
3985 + assert(0);
3986 + }
3987 +
3988 + override equals_t equals(in void* p1, in void* p2)
3989 + {
3990 + assert(0);
3991 + }
3992 +
3993 + override int compare(in void* p1, in void* p2)
3994 + {
3995 + assert(0);
3996 + }
3997 +
3998 + override size_t tsize()
3999 + {
4000 + assert(0);
4001 + }
4002 +
4003 + override void swap(void* p1, void* p2)
4004 + {
4005 + assert(0);
4006 + }
4007 +
4008 + override void destroy(void* p)
4009 + {
4010 + assert(0);
4011 + }
4012 +
4013 + override void postblit(void* p)
4014 + {
4015 + assert(0);
4016 + }
4017 +}
4018 +
4019 +class TypeInfo_Const : TypeInfo
4020 +{
4021 + override string toString()
4022 + {
4023 + return cast(string) ("const(" ~ base.toString() ~ ")");
4024 + }
4025 +
4026 + override equals_t opEquals(Object o) { return base.opEquals(o); }
4027 + override hash_t getHash(in void *p) { return base.getHash(p); }
4028 + override equals_t equals(in void *p1, in void *p2) { return base.equals(p1, p2); }
4029 + override int compare(in void *p1, in void *p2) { return base.compare(p1, p2); }
4030 + override size_t tsize() { return base.tsize(); }
4031 + override void swap(void *p1, void *p2) { return base.swap(p1, p2); }
4032 +
4033 + override TypeInfo next() { return base.next(); }
4034 + override uint flags() { return base.flags(); }
4035 + override void[] init() { return base.init(); }
4036 +
4037 + TypeInfo base;
4038 +}
4039 +
4040 +class TypeInfo_Invariant : TypeInfo_Const
4041 +{
4042 + override string toString()
4043 + {
4044 + return cast(string) ("invariant(" ~ base.toString() ~ ")");
4045 + }
4046 +}
4047 +
4048 +abstract class MemberInfo
4049 +{
4050 + string name();
4051 +}
4052 +
4053 +class MemberInfo_field : MemberInfo
4054 +{
4055 + this(string name, TypeInfo ti, size_t offset)
4056 + {
4057 + m_name = name;
4058 + m_typeinfo = ti;
4059 + m_offset = offset;
4060 + }
4061 +
4062 + override string name() { return m_name; }
4063 + TypeInfo typeInfo() { return m_typeinfo; }
4064 + size_t offset() { return m_offset; }
4065 +
4066 + string m_name;
4067 + TypeInfo m_typeinfo;
4068 + size_t m_offset;
4069 +}
4070 +
4071 +class MemberInfo_function : MemberInfo
4072 +{
4073 + this(string name, TypeInfo ti, void* fp, uint flags)
4074 + {
4075 + m_name = name;
4076 + m_typeinfo = ti;
4077 + m_fp = fp;
4078 + m_flags = flags;
4079 + }
4080 +
4081 + override string name() { return m_name; }
4082 + TypeInfo typeInfo() { return m_typeinfo; }
4083 + void* fp() { return m_fp; }
4084 + uint flags() { return m_flags; }
4085 +
4086 + string m_name;
4087 + TypeInfo m_typeinfo;
4088 + void* m_fp;
4089 + uint m_flags;
4090 +}
4091 +
4092 +
4093 +///////////////////////////////////////////////////////////////////////////////
4094 +// Throwable
4095 +///////////////////////////////////////////////////////////////////////////////
4096 +
4097 +
4098 +class Throwable : Object
4099 +{
4100 + interface TraceInfo
4101 + {
4102 + int opApply(int delegate(inout char[]));
4103 + }
4104 +
4105 + string msg;
4106 + string file;
4107 + size_t line;
4108 + TraceInfo info;
4109 + Throwable next;
4110 +
4111 + this(string msg, Throwable next = null)
4112 + {
4113 + this.msg = msg;
4114 + this.next = next;
4115 + this.info = traceContext();
4116 + }
4117 +
4118 + this(string msg, string file, size_t line, Throwable next = null)
4119 + {
4120 + this(msg, next);
4121 + this.file = file;
4122 + this.line = line;
4123 + this.info = traceContext();
4124 + }
4125 +
4126 + override string toString()
4127 + {
4128 + char[10] tmp = void;
4129 + char[] buf;
4130 +
4131 + for (Throwable e = this; e !is null; e = e.next)
4132 + {
4133 + if (e.file)
4134 + {
4135 + buf ~= e.classinfo.name ~ "@" ~ e.file ~ "(" ~ tmp.intToString(e.line) ~ "): " ~ e.msg;
4136 + }
4137 + else
4138 + {
4139 + buf ~= e.classinfo.name ~ ": " ~ e.msg;
4140 + }
4141 + if (e.info)
4142 + {
4143 + buf ~= "\n----------------";
4144 + foreach (t; e.info)
4145 + buf ~= "\n" ~ t;
4146 + }
4147 + if (e.next)
4148 + buf ~= "\n";
4149 + }
4150 + return cast(string) buf;
4151 + }
4152 +}
4153 +
4154 +
4155 +alias Throwable.TraceInfo function(void* ptr = null) TraceHandler;
4156 +private TraceHandler traceHandler = null;
4157 +
4158 +
4159 +/**
4160 + * Overrides the default trace hander with a user-supplied version.
4161 + *
4162 + * Params:
4163 + * h = The new trace handler. Set to null to use the default handler.
4164 + */
4165 +extern (C) void rt_setTraceHandler(TraceHandler h)
4166 +{
4167 + traceHandler = h;
4168 +}
4169 +
4170 +
4171 +/**
4172 + * This function will be called when an exception is constructed. The
4173 + * user-supplied trace handler will be called if one has been supplied,
4174 + * otherwise no trace will be generated.
4175 + *
4176 + * Params:
4177 + * ptr = A pointer to the location from which to generate the trace, or null
4178 + * if the trace should be generated from within the trace handler
4179 + * itself.
4180 + *
4181 + * Returns:
4182 + * An object describing the current calling context or null if no handler is
4183 + * supplied.
4184 + */
4185 +Throwable.TraceInfo traceContext(void* ptr = null)
4186 +{
4187 + if (traceHandler is null)
4188 + return null;
4189 + return traceHandler(ptr);
4190 +}
4191 +
4192 +
4193 +class Exception : Throwable
4194 +{
4195 + this(string msg, Throwable next = null)
4196 + {
4197 + super(msg, next);
4198 + }
4199 +
4200 + this(string msg, string file, size_t line, Throwable next = null)
4201 + {
4202 + super(msg, file, line, next);
4203 + }
4204 +}
4205 +
4206 +
4207 +class Error : Throwable
4208 +{
4209 + this(string msg, Throwable next = null)
4210 + {
4211 + super(msg, next);
4212 + }
4213 +
4214 + this(string msg, string file, size_t line, Throwable next = null)
4215 + {
4216 + super(msg, file, line, next);
4217 + }
4218 +}
4219 +
4220 +
4221 +///////////////////////////////////////////////////////////////////////////////
4222 +// ModuleInfo
4223 +///////////////////////////////////////////////////////////////////////////////
4224 +
4225 +
4226 +enum
4227 +{
4228 + MIctorstart = 1, // we've started constructing it
4229 + MIctordone = 2, // finished construction
4230 + MIstandalone = 4, // module ctor does not depend on other module
4231 + // ctors being done first
4232 + MIhasictor = 8, // has ictor member
4233 +}
4234 +
4235 +
4236 +class ModuleInfo
4237 +{
4238 + string name;
4239 + ModuleInfo[] importedModules;
4240 + ClassInfo[] localClasses;
4241 + uint flags;
4242 +
4243 + void function() ctor; // module static constructor (order dependent)
4244 + void function() dtor; // module static destructor
4245 + void function() unitTest; // module unit tests
4246 +
4247 + void* xgetMembers; // module getMembers() function
4248 +
4249 + void function() ictor; // module static constructor (order independent)
4250 +
4251 + static int opApply(int delegate(inout ModuleInfo) dg)
4252 + {
4253 + int ret = 0;
4254 +
4255 + foreach (m; _moduleinfo_array)
4256 + {
4257 + ret = dg(m);
4258 + if (ret)
4259 + break;
4260 + }
4261 + return ret;
4262 + }
4263 +}
4264 +
4265 +
4266 +// Windows: this gets initialized by minit.asm
4267 +// linux: this gets initialized in _moduleCtor()
4268 +extern (C) ModuleInfo[] _moduleinfo_array;
4269 +
4270 +
4271 +version (linux)
4272 +{
4273 + // This linked list is created by a compiler generated function inserted
4274 + // into the .ctor list by the compiler.
4275 + struct ModuleReference
4276 + {
4277 + ModuleReference* next;
4278 + ModuleInfo mod;
4279 + }
4280 +
4281 + extern (C) ModuleReference* _Dmodule_ref; // start of linked list
4282 +}
4283 +
4284 +ModuleInfo[] _moduleinfo_dtors;
4285 +uint _moduleinfo_dtors_i;
4286 +
4287 +// Register termination function pointers
4288 +extern (C) int _fatexit(void*);
4289 +
4290 +/**
4291 + * Initialize the modules.
4292 + */
4293 +
4294 +extern (C) void _moduleCtor()
4295 +{
4296 + debug(PRINTF) printf("_moduleCtor()\n");
4297 + version (linux)
4298 + {
4299 + int len = 0;
4300 + ModuleReference *mr;
4301 +
4302 + for (mr = _Dmodule_ref; mr; mr = mr.next)
4303 + len++;
4304 + _moduleinfo_array = new ModuleInfo[len];
4305 + len = 0;
4306 + for (mr = _Dmodule_ref; mr; mr = mr.next)
4307 + { _moduleinfo_array[len] = mr.mod;
4308 + len++;
4309 + }
4310 + }
4311 +
4312 + version (Windows)
4313 + {
4314 + // Ensure module destructors also get called on program termination
4315 + //_fatexit(&_STD_moduleDtor);
4316 + }
4317 +
4318 + _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length];
4319 + debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void*)_moduleinfo_dtors);
4320 + _moduleIndependentCtors();
4321 + _moduleCtor2(_moduleinfo_array, 0);
4322 +}
4323 +
4324 +extern (C) void _moduleIndependentCtors()
4325 +{
4326 + debug(PRINTF) printf("_moduleIndependentCtors()\n");
4327 + foreach (m; _moduleinfo_array)
4328 + {
4329 + if (m && m.flags & MIhasictor && m.ictor)
4330 + {
4331 + (*m.ictor)();
4332 + }
4333 + }
4334 +}
4335 +
4336 +void _moduleCtor2(ModuleInfo[] mi, int skip)
4337 +{
4338 + debug(PRINTF) printf("_moduleCtor2(): %d modules\n", mi.length);
4339 + for (uint i = 0; i < mi.length; i++)
4340 + {
4341 + ModuleInfo m = mi[i];
4342 +
4343 + debug(PRINTF) printf("\tmodule[%d] = '%p'\n", i, m);
4344 + if (!m)
4345 + continue;
4346 + debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name);
4347 + if (m.flags & MIctordone)
4348 + continue;
4349 + debug(PRINTF) printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m);
4350 +
4351 + if (m.ctor || m.dtor)
4352 + {
4353 + if (m.flags & MIctorstart)
4354 + { if (skip || m.flags & MIstandalone)
4355 + continue;
4356 + throw new Exception("Cyclic dependency in module " ~ m.name);
4357 + }
4358 +
4359 + m.flags |= MIctorstart;
4360 + _moduleCtor2(m.importedModules, 0);
4361 + if (m.ctor)
4362 + (*m.ctor)();
4363 + m.flags &= ~MIctorstart;
4364 + m.flags |= MIctordone;
4365 +
4366 + // Now that construction is done, register the destructor
4367 + //printf("\tadding module dtor x%x\n", m);
4368 + assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length);
4369 + _moduleinfo_dtors[_moduleinfo_dtors_i++] = m;
4370 + }
4371 + else
4372 + {
4373 + m.flags |= MIctordone;
4374 + _moduleCtor2(m.importedModules, 1);
4375 + }
4376 + }
4377 +}
4378 +
4379 +/**
4380 + * Destruct the modules.
4381 + */
4382 +
4383 +// Starting the name with "_STD" means under linux a pointer to the
4384 +// function gets put in the .dtors segment.
4385 +
4386 +extern (C) void _moduleDtor()
4387 +{
4388 + debug(PRINTF) printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i);
4389 +
4390 + for (uint i = _moduleinfo_dtors_i; i-- != 0;)
4391 + {
4392 + ModuleInfo m = _moduleinfo_dtors[i];
4393 +
4394 + debug(PRINTF) printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m);
4395 + if (m.dtor)
4396 + {
4397 + (*m.dtor)();
4398 + }
4399 + }
4400 + debug(PRINTF) printf("_moduleDtor() done\n");
4401 +}
4402 +
4403 +///////////////////////////////////////////////////////////////////////////////
4404 +// Monitor
4405 +///////////////////////////////////////////////////////////////////////////////
4406 +
4407 +alias Object.Monitor IMonitor;
4408 +alias void delegate(Object) DEvent;
4409 +
4410 +// NOTE: The dtor callback feature is only supported for monitors that are not
4411 +// supplied by the user. The assumption is that any object with a user-
4412 +// supplied monitor may have special storage or lifetime requirements and
4413 +// that as a result, storing references to local objects within Monitor
4414 +// may not be safe or desirable. Thus, devt is only valid if impl is
4415 +// null.
4416 +struct Monitor
4417 +{
4418 + IMonitor impl;
4419 + /* internal */
4420 + DEvent[] devt;
4421 + /* stuff */
4422 +}
4423 +
4424 +Monitor* getMonitor(Object h)
4425 +{
4426 + return cast(Monitor*) (cast(void**) h)[1];
4427 +}
4428 +
4429 +void setMonitor(Object h, Monitor* m)
4430 +{
4431 + (cast(void**) h)[1] = m;
4432 +}
4433 +
4434 +extern (C) void _d_monitor_create(Object);
4435 +extern (C) void _d_monitor_destroy(Object);
4436 +extern (C) void _d_monitor_lock(Object);
4437 +extern (C) int _d_monitor_unlock(Object);
4438 +
4439 +extern (C) void _d_monitordelete(Object h, bool det)
4440 +{
4441 + Monitor* m = getMonitor(h);
4442 +
4443 + if (m !is null)
4444 + {
4445 + IMonitor i = m.impl;
4446 + if (i is null)
4447 + {
4448 + _d_monitor_devt(m, h);
4449 + _d_monitor_destroy(h);
4450 + setMonitor(h, null);
4451 + return;
4452 + }
4453 + if (det && (cast(void*) i) !is (cast(void*) h))
4454 + delete i;
4455 + setMonitor(h, null);
4456 + }
4457 +}
4458 +
4459 +extern (C) void _d_monitorenter(Object h)
4460 +{
4461 + Monitor* m = getMonitor(h);
4462 +
4463 + if (m is null)
4464 + {
4465 + _d_monitor_create(h);
4466 + m = getMonitor(h);
4467 + }
4468 +
4469 + IMonitor i = m.impl;
4470 +
4471 + if (i is null)
4472 + {
4473 + _d_monitor_lock(h);
4474 + return;
4475 + }
4476 + i.lock();
4477 +}
4478 +
4479 +extern (C) void _d_monitorexit(Object h)
4480 +{
4481 + Monitor* m = getMonitor(h);
4482 + IMonitor i = m.impl;
4483 +
4484 + if (i is null)
4485 + {
4486 + _d_monitor_unlock(h);
4487 + return;
4488 + }
4489 + i.unlock();
4490 +}
4491 +
4492 +extern (C) void _d_monitor_devt(Monitor* m, Object h)
4493 +{
4494 + if (m.devt.length)
4495 + {
4496 + DEvent[] devt;
4497 +
4498 + synchronized (h)
4499 + {
4500 + devt = m.devt;
4501 + m.devt = null;
4502 + }
4503 + foreach (v; devt)
4504 + {
4505 + if (v)
4506 + v(h);
4507 + }
4508 + free(devt.ptr);
4509 + }
4510 +}
4511 +
4512 +extern (C) void rt_attachDisposeEvent(Object h, DEvent e)
4513 +{
4514 + synchronized (h)
4515 + {
4516 + Monitor* m = getMonitor(h);
4517 + assert(m.impl is null);
4518 +
4519 + foreach (inout v; m.devt)
4520 + {
4521 + if (v is null || v == e)
4522 + {
4523 + v = e;
4524 + return;
4525 + }
4526 + }
4527 +
4528 + auto len = m.devt.length + 4; // grow by 4 elements
4529 + auto pos = m.devt.length; // insert position
4530 + auto p = realloc(m.devt.ptr, DEvent.sizeof * len);
4531 + if (!p)
4532 + onOutOfMemoryError();
4533 + m.devt = (cast(DEvent*)p)[0 .. len];
4534 + m.devt[pos+1 .. len] = null;
4535 + m.devt[pos] = e;
4536 + }
4537 +}
4538 +
4539 +extern (C) void rt_detachDisposeEvent(Object h, DEvent e)
4540 +{
4541 + synchronized (h)
4542 + {
4543 + Monitor* m = getMonitor(h);
4544 + assert(m.impl is null);
4545 +
4546 + foreach (p, v; m.devt)
4547 + {
4548 + if (v == e)
4549 + {
4550 + memmove(&m.devt[p],
4551 + &m.devt[p+1],
4552 + (m.devt.length - p - 1) * DEvent.sizeof);
4553 + m.devt[$ - 1] = null;
4554 + return;
4555 + }
4556 + }
4557 + }
4558 +}
4559 Index: src/compiler/ldc/mars.h
4560 ===================================================================
4561 --- src/compiler/ldc/mars.h (revision 0)
4562 +++ src/compiler/ldc/mars.h (revision 0)
4563 @@ -0,0 +1,105 @@
4564 +
4565 +/*
4566 + * Placed into the Public Domain
4567 + * written by Walter Bright, Digital Mars
4568 + * www.digitalmars.com
4569 + */
4570 +
4571 +/*
4572 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
4573 + */
4574 +
4575 +#include <stddef.h>
4576 +
4577 +#if __cplusplus
4578 +extern "C" {
4579 +#endif
4580 +
4581 +struct ClassInfo;
4582 +struct Vtbl;
4583 +
4584 +typedef struct Vtbl
4585 +{
4586 + size_t len;
4587 + void **vptr;
4588 +} Vtbl;
4589 +
4590 +typedef struct Interface
4591 +{
4592 + struct ClassInfo *classinfo;
4593 + struct Vtbl vtbl;
4594 + int offset;
4595 +} Interface;
4596 +
4597 +typedef struct Object
4598 +{
4599 + void **vptr;
4600 + void *monitor;
4601 +} Object;
4602 +
4603 +typedef struct ClassInfo
4604 +{
4605 + Object object;
4606 +
4607 + size_t initlen;
4608 + void *init;
4609 +
4610 + size_t namelen;
4611 + char *name;
4612 +
4613 + Vtbl vtbl;
4614 +
4615 + size_t interfacelen;
4616 + Interface *interfaces;
4617 +
4618 + struct ClassInfo *baseClass;
4619 +
4620 + void *destructor;
4621 + void *invariant;
4622 +
4623 + int flags;
4624 +} ClassInfo;
4625 +
4626 +typedef struct Exception
4627 +{
4628 + Object object;
4629 +
4630 + size_t msglen;
4631 + char* msg;
4632 +
4633 + size_t filelen;
4634 + char* file;
4635 +
4636 + size_t line;
4637 +
4638 + struct Interface *info;
4639 + struct Exception *next;
4640 +} Exception;
4641 +
4642 +typedef struct Array
4643 +{
4644 + size_t length;
4645 + void *ptr;
4646 +} Array;
4647 +
4648 +typedef struct Delegate
4649 +{
4650 + void *thisptr;
4651 + void (*funcptr)();
4652 +} Delegate;
4653 +
4654 +void _d_monitorenter(Object *h);
4655 +void _d_monitorexit(Object *h);
4656 +
4657 +int _d_isbaseof(ClassInfo *b, ClassInfo *c);
4658 +Object *_d_dynamic_cast(Object *o, ClassInfo *ci);
4659 +
4660 +Object * _d_allocclass(ClassInfo *ci);
4661 +void _d_delclass(Object **p);
4662 +
4663 +void _d_OutOfMemory();
4664 +
4665 +#if __cplusplus
4666 +}
4667 +#endif
4668 +
4669 Index: src/compiler/ldc/aApplyR.d
4670 ===================================================================
4671 --- src/compiler/ldc/aApplyR.d (revision 0)
4672 +++ src/compiler/ldc/aApplyR.d (revision 0)
4673 @@ -0,0 +1,975 @@
4674 +
4675 +/**
4676 + * Part of the D programming language runtime library.
4677 + */
4678 +
4679 +/*
4680 + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
4681 + * Written by Walter Bright
4682 + *
4683 + * This software is provided 'as-is', without any express or implied
4684 + * warranty. In no event will the authors be held liable for any damages
4685 + * arising from the use of this software.
4686 + *
4687 + * Permission is granted to anyone to use this software for any purpose,
4688 + * including commercial applications, and to alter it and redistribute it
4689 + * freely, in both source and binary form, subject to the following
4690 + * restrictions:
4691 + *
4692 + * o The origin of this software must not be misrepresented; you must not
4693 + * claim that you wrote the original software. If you use this software
4694 + * in a product, an acknowledgment in the product documentation would be
4695 + * appreciated but is not required.
4696 + * o Altered source versions must be plainly marked as such, and must not
4697 + * be misrepresented as being the original software.
4698 + * o This notice may not be removed or altered from any source
4699 + * distribution.
4700 + */
4701 +
4702 +/*
4703 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
4704 + */
4705 +
4706 +/* This code handles decoding UTF strings for foreach_reverse loops.
4707 + * There are 6 combinations of conversions between char, wchar,
4708 + * and dchar, and 2 of each of those.
4709 + */
4710 +
4711 +private import util.utf;
4712 +
4713 +/**********************************************/
4714 +/* 1 argument versions */
4715 +
4716 +// dg is D, but _aApplyRcd() is C
4717 +extern (D) typedef int delegate(void *) dg_t;
4718 +
4719 +extern (C) int _aApplyRcd1(in char[] aa, dg_t dg)
4720 +{ int result;
4721 +
4722 + debug(apply) printf("_aApplyRcd1(), len = %d\n", aa.length);
4723 + for (size_t i = aa.length; i != 0; )
4724 + { dchar d;
4725 +
4726 + i--;
4727 + d = aa[i];
4728 + if (d & 0x80)
4729 + { char c = cast(char)d;
4730 + uint j;
4731 + uint m = 0x3F;
4732 + d = 0;
4733 + while ((c & 0xC0) != 0xC0)
4734 + { if (i == 0)
4735 + onUnicodeError("Invalid UTF-8 sequence", 0);
4736 + i--;
4737 + d |= (c & 0x3F) << j;
4738 + j += 6;
4739 + m >>= 1;
4740 + c = aa[i];
4741 + }
4742 + d |= (c & m) << j;
4743 + }
4744 + result = dg(cast(void *)&d);
4745 + if (result)
4746 + break;
4747 + }
4748 + return result;
4749 +}
4750 +
4751 +unittest
4752 +{
4753 + debug(apply) printf("_aApplyRcd1.unittest\n");
4754 +
4755 + char[] s = "hello"c;
4756 + int i;
4757 +
4758 + foreach_reverse(dchar d; s)
4759 + {
4760 + switch (i)
4761 + {
4762 + case 0: assert(d == 'o'); break;
4763 + case 1: assert(d == 'l'); break;
4764 + case 2: assert(d == 'l'); break;
4765 + case 3: assert(d == 'e'); break;
4766 + case 4: assert(d == 'h'); break;
4767 + default: assert(0);
4768 + }
4769 + i++;
4770 + }
4771 + assert(i == 5);
4772 +
4773 + s = "a\u1234\U00100456b";
4774 + i = 0;
4775 + foreach_reverse(dchar d; s)
4776 + {
4777 + //printf("i = %d, d = %x\n", i, d);
4778 + switch (i)
4779 + {
4780 + case 0: assert(d == 'b'); break;
4781 + case 1: assert(d == '\U00100456'); break;
4782 + case 2: assert(d == '\u1234'); break;
4783 + case 3: assert(d == 'a'); break;
4784 + default: assert(0);
4785 + }
4786 + i++;
4787 + }
4788 + assert(i == 4);
4789 +}
4790 +
4791 +/*****************************/
4792 +
4793 +extern (C) int _aApplyRwd1(in wchar[] aa, dg_t dg)
4794 +{ int result;
4795 +
4796 + debug(apply) printf("_aApplyRwd1(), len = %d\n", aa.length);
4797 + for (size_t i = aa.length; i != 0; )
4798 + { dchar d;
4799 +
4800 + i--;
4801 + d = aa[i];
4802 + if (d >= 0xDC00 && d <= 0xDFFF)
4803 + { if (i == 0)
4804 + onUnicodeError("Invalid UTF-16 sequence", 0);
4805 + i--;
4806 + d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
4807 + }
4808 + result = dg(cast(void *)&d);
4809 + if (result)
4810 + break;
4811 + }
4812 + return result;
4813 +}
4814 +
4815 +unittest
4816 +{
4817 + debug(apply) printf("_aApplyRwd1.unittest\n");
4818 +
4819 + wchar[] s = "hello"w;
4820 + int i;
4821 +
4822 + foreach_reverse(dchar d; s)
4823 + {
4824 + switch (i)
4825 + {
4826 + case 0: assert(d == 'o'); break;
4827 + case 1: assert(d == 'l'); break;
4828 + case 2: assert(d == 'l'); break;
4829 + case 3: assert(d == 'e'); break;
4830 + case 4: assert(d == 'h'); break;
4831 + default: assert(0);
4832 + }
4833 + i++;
4834 + }
4835 + assert(i == 5);
4836 +
4837 + s = "a\u1234\U00100456b";
4838 + i = 0;
4839 + foreach_reverse(dchar d; s)
4840 + {
4841 + //printf("i = %d, d = %x\n", i, d);
4842 + switch (i)
4843 + {
4844 + case 0: assert(d == 'b'); break;
4845 + case 1: assert(d == '\U00100456'); break;
4846 + case 2: assert(d == '\u1234'); break;
4847 + case 3: assert(d == 'a'); break;
4848 + default: assert(0);
4849 + }
4850 + i++;
4851 + }
4852 + assert(i == 4);
4853 +}
4854 +
4855 +/*****************************/
4856 +
4857 +extern (C) int _aApplyRcw1(in char[] aa, dg_t dg)
4858 +{ int result;
4859 +
4860 + debug(apply) printf("_aApplyRcw1(), len = %d\n", aa.length);
4861 + for (size_t i = aa.length; i != 0; )
4862 + { dchar d;
4863 + wchar w;
4864 +
4865 + i--;
4866 + w = aa[i];
4867 + if (w & 0x80)
4868 + { char c = cast(char)w;
4869 + uint j;
4870 + uint m = 0x3F;
4871 + d = 0;
4872 + while ((c & 0xC0) != 0xC0)
4873 + { if (i == 0)
4874 + onUnicodeError("Invalid UTF-8 sequence", 0);
4875 + i--;
4876 + d |= (c & 0x3F) << j;
4877 + j += 6;
4878 + m >>= 1;
4879 + c = aa[i];
4880 + }
4881 + d |= (c & m) << j;
4882 +
4883 + if (d <= 0xFFFF)
4884 + w = cast(wchar) d;
4885 + else
4886 + {
4887 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
4888 + result = dg(cast(void *)&w);
4889 + if (result)
4890 + break;
4891 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
4892 + }
4893 + }
4894 + result = dg(cast(void *)&w);
4895 + if (result)
4896 + break;
4897 + }
4898 + return result;
4899 +}
4900 +
4901 +unittest
4902 +{
4903 + debug(apply) printf("_aApplyRcw1.unittest\n");
4904 +
4905 + char[] s = "hello"c;
4906 + int i;
4907 +
4908 + foreach_reverse(wchar d; s)
4909 + {
4910 + switch (i)
4911 + {
4912 + case 0: assert(d == 'o'); break;
4913 + case 1: assert(d == 'l'); break;
4914 + case 2: assert(d == 'l'); break;
4915 + case 3: assert(d == 'e'); break;
4916 + case 4: assert(d == 'h'); break;
4917 + default: assert(0);
4918 + }
4919 + i++;
4920 + }
4921 + assert(i == 5);
4922 +
4923 + s = "a\u1234\U00100456b";
4924 + i = 0;
4925 + foreach_reverse(wchar d; s)
4926 + {
4927 + //printf("i = %d, d = %x\n", i, d);
4928 + switch (i)
4929 + {
4930 + case 0: assert(d == 'b'); break;
4931 + case 1: assert(d == 0xDBC1); break;
4932 + case 2: assert(d == 0xDC56); break;
4933 + case 3: assert(d == 0x1234); break;
4934 + case 4: assert(d == 'a'); break;
4935 + default: assert(0);
4936 + }
4937 + i++;
4938 + }
4939 + assert(i == 5);
4940 +}
4941 +
4942 +/*****************************/
4943 +
4944 +extern (C) int _aApplyRwc1(in wchar[] aa, dg_t dg)
4945 +{ int result;
4946 +
4947 + debug(apply) printf("_aApplyRwc1(), len = %d\n", aa.length);
4948 + for (size_t i = aa.length; i != 0; )
4949 + { dchar d;
4950 + char c;
4951 +
4952 + i--;
4953 + d = aa[i];
4954 + if (d >= 0xDC00 && d <= 0xDFFF)
4955 + { if (i == 0)
4956 + onUnicodeError("Invalid UTF-16 sequence", 0);
4957 + i--;
4958 + d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
4959 + }
4960 +
4961 + if (d & ~0x7F)
4962 + {
4963 + char[4] buf;
4964 +
4965 + auto b = toUTF8(buf, d);
4966 + foreach (char c2; b)
4967 + {
4968 + result = dg(cast(void *)&c2);
4969 + if (result)
4970 + return result;
4971 + }
4972 + continue;
4973 + }
4974 + c = cast(char)d;
4975 + result = dg(cast(void *)&c);
4976 + if (result)
4977 + break;
4978 + }
4979 + return result;
4980 +}
4981 +
4982 +unittest
4983 +{
4984 + debug(apply) printf("_aApplyRwc1.unittest\n");
4985 +
4986 + wchar[] s = "hello"w;
4987 + int i;
4988 +
4989 + foreach_reverse(char d; s)
4990 + {
4991 + switch (i)
4992 + {
4993 + case 0: assert(d == 'o'); break;
4994 + case 1: assert(d == 'l'); break;
4995 + case 2: assert(d == 'l'); break;
4996 + case 3: assert(d == 'e'); break;
4997 + case 4: assert(d == 'h'); break;
4998 + default: assert(0);
4999 + }
5000 + i++;
5001 + }
5002 + assert(i == 5);
5003 +
5004 + s = "a\u1234\U00100456b";
5005 + i = 0;
5006 + foreach_reverse(char d; s)
5007 + {
5008 + //printf("i = %d, d = %x\n", i, d);
5009 + switch (i)
5010 + {
5011 + case 0: assert(d == 'b'); break;
5012 + case 1: assert(d == 0xF4); break;
5013 + case 2: assert(d == 0x80); break;
5014 + case 3: assert(d == 0x91); break;
5015 + case 4: assert(d == 0x96); break;
5016 + case 5: assert(d == 0xE1); break;
5017 + case 6: assert(d == 0x88); break;
5018 + case 7: assert(d == 0xB4); break;
5019 + case 8: assert(d == 'a'); break;
5020 + default: assert(0);
5021 + }
5022 + i++;
5023 + }
5024 + assert(i == 9);
5025 +}
5026 +
5027 +/*****************************/
5028 +
5029 +extern (C) int _aApplyRdc1(in dchar[] aa, dg_t dg)
5030 +{ int result;
5031 +
5032 + debug(apply) printf("_aApplyRdc1(), len = %d\n", aa.length);
5033 + for (size_t i = aa.length; i != 0;)
5034 + { dchar d = aa[--i];
5035 + char c;
5036 +
5037 + if (d & ~0x7F)
5038 + {
5039 + char[4] buf;
5040 +
5041 + auto b = toUTF8(buf, d);
5042 + foreach (char c2; b)
5043 + {
5044 + result = dg(cast(void *)&c2);
5045 + if (result)
5046 + return result;
5047 + }
5048 + continue;
5049 + }
5050 + else
5051 + {
5052 + c = cast(char)d;
5053 + }
5054 + result = dg(cast(void *)&c);
5055 + if (result)
5056 + break;
5057 + }
5058 + return result;
5059 +}
5060 +
5061 +unittest
5062 +{
5063 + debug(apply) printf("_aApplyRdc1.unittest\n");
5064 +
5065 + dchar[] s = "hello"d;
5066 + int i;
5067 +
5068 + foreach_reverse(char d; s)
5069 + {
5070 + switch (i)
5071 + {
5072 + case 0: assert(d == 'o'); break;
5073 + case 1: assert(d == 'l'); break;
5074 + case 2: assert(d == 'l'); break;
5075 + case 3: assert(d == 'e'); break;
5076 + case 4: assert(d == 'h'); break;
5077 + default: assert(0);
5078 + }
5079 + i++;
5080 + }
5081 + assert(i == 5);
5082 +
5083 + s = "a\u1234\U00100456b";
5084 + i = 0;
5085 + foreach_reverse(char d; s)
5086 + {
5087 + //printf("i = %d, d = %x\n", i, d);
5088 + switch (i)
5089 + {
5090 + case 0: assert(d == 'b'); break;
5091 + case 1: assert(d == 0xF4); break;
5092 + case 2: assert(d == 0x80); break;
5093 + case 3: assert(d == 0x91); break;
5094 + case 4: assert(d == 0x96); break;
5095 + case 5: assert(d == 0xE1); break;
5096 + case 6: assert(d == 0x88); break;
5097 + case 7: assert(d == 0xB4); break;
5098 + case 8: assert(d == 'a'); break;
5099 + default: assert(0);
5100 + }
5101 + i++;
5102 + }
5103 + assert(i == 9);
5104 +}
5105 +
5106 +/*****************************/
5107 +
5108 +extern (C) int _aApplyRdw1(in dchar[] aa, dg_t dg)
5109 +{ int result;
5110 +
5111 + debug(apply) printf("_aApplyRdw1(), len = %d\n", aa.length);
5112 + for (size_t i = aa.length; i != 0; )
5113 + { dchar d = aa[--i];
5114 + wchar w;
5115 +
5116 + if (d <= 0xFFFF)
5117 + w = cast(wchar) d;
5118 + else
5119 + {
5120 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
5121 + result = dg(cast(void *)&w);
5122 + if (result)
5123 + break;
5124 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
5125 + }
5126 + result = dg(cast(void *)&w);
5127 + if (result)
5128 + break;
5129 + }
5130 + return result;
5131 +}
5132 +
5133 +unittest
5134 +{
5135 + debug(apply) printf("_aApplyRdw1.unittest\n");
5136 +
5137 + dchar[] s = "hello"d;
5138 + int i;
5139 +
5140 + foreach_reverse(wchar d; s)
5141 + {
5142 + switch (i)
5143 + {
5144 + case 0: assert(d == 'o'); break;
5145 + case 1: assert(d == 'l'); break;
5146 + case 2: assert(d == 'l'); break;
5147 + case 3: assert(d == 'e'); break;
5148 + case 4: assert(d == 'h'); break;
5149 + default: assert(0);
5150 + }
5151 + i++;
5152 + }
5153 + assert(i == 5);
5154 +
5155 + s = "a\u1234\U00100456b";
5156 + i = 0;
5157 + foreach_reverse(wchar d; s)
5158 + {
5159 + //printf("i = %d, d = %x\n", i, d);
5160 + switch (i)
5161 + {
5162 + case 0: assert(d == 'b'); break;
5163 + case 1: assert(d == 0xDBC1); break;
5164 + case 2: assert(d == 0xDC56); break;
5165 + case 3: assert(d == 0x1234); break;
5166 + case 4: assert(d == 'a'); break;
5167 + default: assert(0);
5168 + }
5169 + i++;
5170 + }
5171 + assert(i == 5);
5172 +}
5173 +
5174 +
5175 +/****************************************************************************/
5176 +/* 2 argument versions */
5177 +
5178 +// dg is D, but _aApplyRcd2() is C
5179 +extern (D) typedef int delegate(void *, void *) dg2_t;
5180 +
5181 +extern (C) int _aApplyRcd2(in char[] aa, dg2_t dg)
5182 +{ int result;
5183 + size_t i;
5184 + size_t len = aa.length;
5185 +
5186 + debug(apply) printf("_aApplyRcd2(), len = %d\n", len);
5187 + for (i = len; i != 0; )
5188 + { dchar d;
5189 +
5190 + i--;
5191 + d = aa[i];
5192 + if (d & 0x80)
5193 + { char c = cast(char)d;
5194 + uint j;
5195 + uint m = 0x3F;
5196 + d = 0;
5197 + while ((c & 0xC0) != 0xC0)
5198 + { if (i == 0)
5199 + onUnicodeError("Invalid UTF-8 sequence", 0);
5200 + i--;
5201 + d |= (c & 0x3F) << j;
5202 + j += 6;
5203 + m >>= 1;
5204 + c = aa[i];
5205 + }
5206 + d |= (c & m) << j;
5207 + }
5208 + result = dg(&i, cast(void *)&d);
5209 + if (result)
5210 + break;
5211 + }
5212 + return result;
5213 +}
5214 +
5215 +unittest
5216 +{
5217 + debug(apply) printf("_aApplyRcd2.unittest\n");
5218 +
5219 + char[] s = "hello"c;
5220 + int i;
5221 +
5222 + foreach_reverse(k, dchar d; s)
5223 + {
5224 + assert(k == 4 - i);
5225 + switch (i)
5226 + {
5227 + case 0: assert(d == 'o'); break;
5228 + case 1: assert(d == 'l'); break;
5229 + case 2: assert(d == 'l'); break;
5230 + case 3: assert(d == 'e'); break;
5231 + case 4: assert(d == 'h'); break;
5232 + default: assert(0);
5233 + }
5234 + i++;
5235 + }
5236 + assert(i == 5);
5237 +
5238 + s = "a\u1234\U00100456b";
5239 + i = 0;
5240 + foreach_reverse(k, dchar d; s)
5241 + {
5242 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5243 + switch (i)
5244 + {
5245 + case 0: assert(d == 'b'); assert(k == 8); break;
5246 + case 1: assert(d == '\U00100456'); assert(k == 4); break;
5247 + case 2: assert(d == '\u1234'); assert(k == 1); break;
5248 + case 3: assert(d == 'a'); assert(k == 0); break;
5249 + default: assert(0);
5250 + }
5251 + i++;
5252 + }
5253 + assert(i == 4);
5254 +}
5255 +
5256 +/*****************************/
5257 +
5258 +extern (C) int _aApplyRwd2(in wchar[] aa, dg2_t dg)
5259 +{ int result;
5260 +
5261 + debug(apply) printf("_aApplyRwd2(), len = %d\n", aa.length);
5262 + for (size_t i = aa.length; i != 0; )
5263 + { dchar d;
5264 +
5265 + i--;
5266 + d = aa[i];
5267 + if (d >= 0xDC00 && d <= 0xDFFF)
5268 + { if (i == 0)
5269 + onUnicodeError("Invalid UTF-16 sequence", 0);
5270 + i--;
5271 + d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
5272 + }
5273 + result = dg(&i, cast(void *)&d);
5274 + if (result)
5275 + break;
5276 + }
5277 + return result;
5278 +}
5279 +
5280 +unittest
5281 +{
5282 + debug(apply) printf("_aApplyRwd2.unittest\n");
5283 +
5284 + wchar[] s = "hello"w;
5285 + int i;
5286 +
5287 + foreach_reverse(k, dchar d; s)
5288 + {
5289 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5290 + assert(k == 4 - i);
5291 + switch (i)
5292 + {
5293 + case 0: assert(d == 'o'); break;
5294 + case 1: assert(d == 'l'); break;
5295 + case 2: assert(d == 'l'); break;
5296 + case 3: assert(d == 'e'); break;
5297 + case 4: assert(d == 'h'); break;
5298 + default: assert(0);
5299 + }
5300 + i++;
5301 + }
5302 + assert(i == 5);
5303 +
5304 + s = "a\u1234\U00100456b";
5305 + i = 0;
5306 + foreach_reverse(k, dchar d; s)
5307 + {
5308 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5309 + switch (i)
5310 + {
5311 + case 0: assert(k == 4); assert(d == 'b'); break;
5312 + case 1: assert(k == 2); assert(d == '\U00100456'); break;
5313 + case 2: assert(k == 1); assert(d == '\u1234'); break;
5314 + case 3: assert(k == 0); assert(d == 'a'); break;
5315 + default: assert(0);
5316 + }
5317 + i++;
5318 + }
5319 + assert(i == 4);
5320 +}
5321 +
5322 +/*****************************/
5323 +
5324 +extern (C) int _aApplyRcw2(in char[] aa, dg2_t dg)
5325 +{ int result;
5326 +
5327 + debug(apply) printf("_aApplyRcw2(), len = %d\n", aa.length);
5328 + for (size_t i = aa.length; i != 0; )
5329 + { dchar d;
5330 + wchar w;
5331 +
5332 + i--;
5333 + w = aa[i];
5334 + if (w & 0x80)
5335 + { char c = cast(char)w;
5336 + uint j;
5337 + uint m = 0x3F;
5338 + d = 0;
5339 + while ((c & 0xC0) != 0xC0)
5340 + { if (i == 0)
5341 + onUnicodeError("Invalid UTF-8 sequence", 0);
5342 + i--;
5343 + d |= (c & 0x3F) << j;
5344 + j += 6;
5345 + m >>= 1;
5346 + c = aa[i];
5347 + }
5348 + d |= (c & m) << j;
5349 +
5350 + if (d <= 0xFFFF)
5351 + w = cast(wchar) d;
5352 + else
5353 + {
5354 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
5355 + result = dg(&i, cast(void *)&w);
5356 + if (result)
5357 + break;
5358 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
5359 + }
5360 + }
5361 + result = dg(&i, cast(void *)&w);
5362 + if (result)
5363 + break;
5364 + }
5365 + return result;
5366 +}
5367 +
5368 +unittest
5369 +{
5370 + debug(apply) printf("_aApplyRcw2.unittest\n");
5371 +
5372 + char[] s = "hello"c;
5373 + int i;
5374 +
5375 + foreach_reverse(k, wchar d; s)
5376 + {
5377 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5378 + assert(k == 4 - i);
5379 + switch (i)
5380 + {
5381 + case 0: assert(d == 'o'); break;
5382 + case 1: assert(d == 'l'); break;
5383 + case 2: assert(d == 'l'); break;
5384 + case 3: assert(d == 'e'); break;
5385 + case 4: assert(d == 'h'); break;
5386 + default: assert(0);
5387 + }
5388 + i++;
5389 + }
5390 + assert(i == 5);
5391 +
5392 + s = "a\u1234\U00100456b";
5393 + i = 0;
5394 + foreach_reverse(k, wchar d; s)
5395 + {
5396 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5397 + switch (i)
5398 + {
5399 + case 0: assert(k == 8); assert(d == 'b'); break;
5400 + case 1: assert(k == 4); assert(d == 0xDBC1); break;
5401 + case 2: assert(k == 4); assert(d == 0xDC56); break;
5402 + case 3: assert(k == 1); assert(d == 0x1234); break;
5403 + case 4: assert(k == 0); assert(d == 'a'); break;
5404 + default: assert(0);
5405 + }
5406 + i++;
5407 + }
5408 + assert(i == 5);
5409 +}
5410 +
5411 +/*****************************/
5412 +
5413 +extern (C) int _aApplyRwc2(in wchar[] aa, dg2_t dg)
5414 +{ int result;
5415 +
5416 + debug(apply) printf("_aApplyRwc2(), len = %d\n", aa.length);
5417 + for (size_t i = aa.length; i != 0; )
5418 + { dchar d;
5419 + char c;
5420 +
5421 + i--;
5422 + d = aa[i];
5423 + if (d >= 0xDC00 && d <= 0xDFFF)
5424 + { if (i == 0)
5425 + onUnicodeError("Invalid UTF-16 sequence", 0);
5426 + i--;
5427 + d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
5428 + }
5429 +
5430 + if (d & ~0x7F)
5431 + {
5432 + char[4] buf;
5433 +
5434 + auto b = toUTF8(buf, d);
5435 + foreach (char c2; b)
5436 + {
5437 + result = dg(&i, cast(void *)&c2);
5438 + if (result)
5439 + return result;
5440 + }
5441 + continue;
5442 + }
5443 + c = cast(char)d;
5444 + result = dg(&i, cast(void *)&c);
5445 + if (result)
5446 + break;
5447 + }
5448 + return result;
5449 +}
5450 +
5451 +unittest
5452 +{
5453 + debug(apply) printf("_aApplyRwc2.unittest\n");
5454 +
5455 + wchar[] s = "hello"w;
5456 + int i;
5457 +
5458 + foreach_reverse(k, char d; s)
5459 + {
5460 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5461 + assert(k == 4 - i);
5462 + switch (i)
5463 + {
5464 + case 0: assert(d == 'o'); break;
5465 + case 1: assert(d == 'l'); break;
5466 + case 2: assert(d == 'l'); break;
5467 + case 3: assert(d == 'e'); break;
5468 + case 4: assert(d == 'h'); break;
5469 + default: assert(0);
5470 + }
5471 + i++;
5472 + }
5473 + assert(i == 5);
5474 +
5475 + s = "a\u1234\U00100456b";
5476 + i = 0;
5477 + foreach_reverse(k, char d; s)
5478 + {
5479 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5480 + switch (i)
5481 + {
5482 + case 0: assert(k == 4); assert(d == 'b'); break;
5483 + case 1: assert(k == 2); assert(d == 0xF4); break;
5484 + case 2: assert(k == 2); assert(d == 0x80); break;
5485 + case 3: assert(k == 2); assert(d == 0x91); break;
5486 + case 4: assert(k == 2); assert(d == 0x96); break;
5487 + case 5: assert(k == 1); assert(d == 0xE1); break;
5488 + case 6: assert(k == 1); assert(d == 0x88); break;
5489 + case 7: assert(k == 1); assert(d == 0xB4); break;
5490 + case 8: assert(k == 0); assert(d == 'a'); break;
5491 + default: assert(0);
5492 + }
5493 + i++;
5494 + }
5495 + assert(i == 9);
5496 +}
5497 +
5498 +/*****************************/
5499 +
5500 +extern (C) int _aApplyRdc2(in dchar[] aa, dg2_t dg)
5501 +{ int result;
5502 +
5503 + debug(apply) printf("_aApplyRdc2(), len = %d\n", aa.length);
5504 + for (size_t i = aa.length; i != 0; )
5505 + { dchar d = aa[--i];
5506 + char c;
5507 +
5508 + if (d & ~0x7F)
5509 + {
5510 + char[4] buf;
5511 +
5512 + auto b = toUTF8(buf, d);
5513 + foreach (char c2; b)
5514 + {
5515 + result = dg(&i, cast(void *)&c2);
5516 + if (result)
5517 + return result;
5518 + }
5519 + continue;
5520 + }
5521 + else
5522 + { c = cast(char)d;
5523 + }
5524 + result = dg(&i, cast(void *)&c);
5525 + if (result)
5526 + break;
5527 + }
5528 + return result;
5529 +}
5530 +
5531 +unittest
5532 +{
5533 + debug(apply) printf("_aApplyRdc2.unittest\n");
5534 +
5535 + dchar[] s = "hello"d;
5536 + int i;
5537 +
5538 + foreach_reverse(k, char d; s)
5539 + {
5540 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5541 + assert(k == 4 - i);
5542 + switch (i)
5543 + {
5544 + case 0: assert(d == 'o'); break;
5545 + case 1: assert(d == 'l'); break;
5546 + case 2: assert(d == 'l'); break;
5547 + case 3: assert(d == 'e'); break;
5548 + case 4: assert(d == 'h'); break;
5549 + default: assert(0);
5550 + }
5551 + i++;
5552 + }
5553 + assert(i == 5);
5554 +
5555 + s = "a\u1234\U00100456b";
5556 + i = 0;
5557 + foreach_reverse(k, char d; s)
5558 + {
5559 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5560 + switch (i)
5561 + {
5562 + case 0: assert(k == 3); assert(d == 'b'); break;
5563 + case 1: assert(k == 2); assert(d == 0xF4); break;
5564 + case 2: assert(k == 2); assert(d == 0x80); break;
5565 + case 3: assert(k == 2); assert(d == 0x91); break;
5566 + case 4: assert(k == 2); assert(d == 0x96); break;
5567 + case 5: assert(k == 1); assert(d == 0xE1); break;
5568 + case 6: assert(k == 1); assert(d == 0x88); break;
5569 + case 7: assert(k == 1); assert(d == 0xB4); break;
5570 + case 8: assert(k == 0); assert(d == 'a'); break;
5571 + default: assert(0);
5572 + }
5573 + i++;
5574 + }
5575 + assert(i == 9);
5576 +}
5577 +
5578 +/*****************************/
5579 +
5580 +extern (C) int _aApplyRdw2(in dchar[] aa, dg2_t dg)
5581 +{ int result;
5582 +
5583 + debug(apply) printf("_aApplyRdw2(), len = %d\n", aa.length);
5584 + for (size_t i = aa.length; i != 0; )
5585 + { dchar d = aa[--i];
5586 + wchar w;
5587 +
5588 + if (d <= 0xFFFF)
5589 + w = cast(wchar) d;
5590 + else
5591 + {
5592 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
5593 + result = dg(&i, cast(void *)&w);
5594 + if (result)
5595 + break;
5596 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
5597 + }
5598 + result = dg(&i, cast(void *)&w);
5599 + if (result)
5600 + break;
5601 + }
5602 + return result;
5603 +}
5604 +
5605 +unittest
5606 +{
5607 + debug(apply) printf("_aApplyRdw2.unittest\n");
5608 +
5609 + dchar[] s = "hello"d;
5610 + int i;
5611 +
5612 + foreach_reverse(k, wchar d; s)
5613 + {
5614 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5615 + assert(k == 4 - i);
5616 + switch (i)
5617 + {
5618 + case 0: assert(d == 'o'); break;
5619 + case 1: assert(d == 'l'); break;
5620 + case 2: assert(d == 'l'); break;
5621 + case 3: assert(d == 'e'); break;
5622 + case 4: assert(d == 'h'); break;
5623 + default: assert(0);
5624 + }
5625 + i++;
5626 + }
5627 + assert(i == 5);
5628 +
5629 + s = "a\u1234\U00100456b";
5630 + i = 0;
5631 + foreach_reverse(k, wchar d; s)
5632 + {
5633 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5634 + switch (i)
5635 + {
5636 + case 0: assert(k == 3); assert(d == 'b'); break;
5637 + case 1: assert(k == 2); assert(d == 0xDBC1); break;
5638 + case 2: assert(k == 2); assert(d == 0xDC56); break;
5639 + case 3: assert(k == 1); assert(d == 0x1234); break;
5640 + case 4: assert(k == 0); assert(d == 'a'); break;
5641 + default: assert(0);
5642 + }
5643 + i++;
5644 + }
5645 + assert(i == 5);
5646 +}
5647 +
5648 +
5649 Index: src/compiler/ldc/memory.d
5650 ===================================================================
5651 --- src/compiler/ldc/memory.d (revision 0)
5652 +++ src/compiler/ldc/memory.d (revision 0)
5653 @@ -0,0 +1,323 @@
5654 +/**
5655 + * This module exposes functionality for inspecting and manipulating memory.
5656 + *
5657 + * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com.
5658 + * All rights reserved.
5659 + * License:
5660 + * This software is provided 'as-is', without any express or implied
5661 + * warranty. In no event will the authors be held liable for any damages
5662 + * arising from the use of this software.
5663 + *
5664 + * Permission is granted to anyone to use this software for any purpose,
5665 + * including commercial applications, and to alter it and redistribute it
5666 + * freely, in both source and binary form, subject to the following
5667 + * restrictions:
5668 + *
5669 + * o The origin of this software must not be misrepresented; you must not
5670 + * claim that you wrote the original software. If you use this software
5671 + * in a product, an acknowledgment in the product documentation would be
5672 + * appreciated but is not required.
5673 + * o Altered source versions must be plainly marked as such, and must not
5674 + * be misrepresented as being the original software.
5675 + * o This notice may not be removed or altered from any source
5676 + * distribution.
5677 + * Authors: Walter Bright, Sean Kelly
5678 + */
5679 +module memory;
5680 +
5681 +version = GC_Use_Dynamic_Ranges;
5682 +
5683 +// does Posix suffice?
5684 +version(Posix)
5685 +{
5686 + version = GC_Use_Data_Proc_Maps;
5687 +}
5688 +
5689 +version(GC_Use_Data_Proc_Maps)
5690 +{
5691 + version(Posix) {} else {
5692 + static assert(false, "Proc Maps only supported on Posix systems");
5693 + }
5694 +
5695 + version( D_Version2 )
5696 + {
5697 + private import core.sys.posix.unistd;
5698 + private import core.sys.posix.fcntl;
5699 + private import core.stdc.string;
5700 + }
5701 + else
5702 + {
5703 + private import tango.stdc.posix.unistd;
5704 + private import tango.stdc.posix.fcntl;
5705 + private import tango.stdc.string;
5706 + }
5707 +
5708 + version = GC_Use_Dynamic_Ranges;
5709 +}
5710 +
5711 +private
5712 +{
5713 + version( linux )
5714 + {
5715 + //version = SimpleLibcStackEnd;
5716 +
5717 + version( SimpleLibcStackEnd )
5718 + {
5719 + extern (C) extern void* __libc_stack_end;
5720 + }
5721 + else
5722 + {
5723 + version( D_Version2 )
5724 + import core.sys.posix.dlfcn;
5725 + else
5726 + import tango.stdc.posix.dlfcn;
5727 + }
5728 + }
5729 + version(LDC)
5730 + {
5731 + pragma(intrinsic, "llvm.frameaddress")
5732 + {
5733 + void* llvm_frameaddress(uint level=0);
5734 + }
5735 + }
5736 +}
5737 +
5738 +
5739 +/**
5740 + *
5741 + */
5742 +extern (C) void* rt_stackBottom()
5743 +{
5744 + version( Win32 )
5745 + {
5746 + void* bottom;
5747 + asm
5748 + {
5749 + mov EAX, FS:4;
5750 + mov bottom, EAX;
5751 + }
5752 + return bottom;
5753 + }
5754 + else version( linux )
5755 + {
5756 + version( SimpleLibcStackEnd )
5757 + {
5758 + return __libc_stack_end;
5759 + }
5760 + else
5761 + {
5762 + // See discussion: http://autopackage.org/forums/viewtopic.php?t=22
5763 + static void** libc_stack_end;
5764 +
5765 + if( libc_stack_end == libc_stack_end.init )
5766 + {
5767 + void* handle = dlopen( null, RTLD_NOW );
5768 + libc_stack_end = cast(void**) dlsym( handle, "__libc_stack_end" );
5769 + dlclose( handle );
5770 + }
5771 + return *libc_stack_end;
5772 + }
5773 + }
5774 + else version( darwin )
5775 + {
5776 + // darwin has a fixed stack bottom
5777 + return cast(void*) 0xc0000000;
5778 + }
5779 + else
5780 + {
5781 + static assert( false, "Operating system not supported." );
5782 + }
5783 +}
5784 +
5785 +
5786 +/**
5787 + *
5788 + */
5789 +extern (C) void* rt_stackTop()
5790 +{
5791 + version( D_InlineAsm_X86 )
5792 + {
5793 + asm
5794 + {
5795 + naked;
5796 + mov EAX, ESP;
5797 + ret;
5798 + }
5799 + }
5800 + else
5801 + {
5802 + return llvm_frameaddress();
5803 + }
5804 +}
5805 +
5806 +
5807 +private
5808 +{
5809 + version( Win32 )
5810 + {
5811 + extern (C)
5812 + {
5813 + extern int _data_start__;
5814 + extern int _bss_end__;
5815 +
5816 + alias _data_start__ Data_Start;
5817 + alias _bss_end__ Data_End;
5818 + }
5819 + }
5820 + else version( linux )
5821 + {
5822 + extern (C)
5823 + {
5824 + extern int _data;
5825 + extern int __data_start;
5826 + extern int _end;
5827 + extern int _data_start__;
5828 + extern int _data_end__;
5829 + extern int _bss_start__;
5830 + extern int _bss_end__;
5831 + extern int __fini_array_end;
5832 + }
5833 +
5834 + alias __data_start Data_Start;
5835 + alias _end Data_End;
5836 + }
5837 +
5838 + version( GC_Use_Dynamic_Ranges )
5839 + {
5840 + version( D_Version2 )
5841 + private import core.stdc.stdlib;
5842 + else
5843 + private import tango.stdc.stdlib;
5844 + }
5845 +
5846 + extern (C) void gc_addRange( void* p, size_t sz );
5847 + extern (C) void gc_removeRange( void *p );
5848 +}
5849 +
5850 +
5851 +void initStaticDataGC()
5852 +{
5853 + enum S = (void*).sizeof;
5854 +
5855 + // Can't assume the input addresses are word-aligned
5856 + static void* adjust_up( void* p )
5857 + {
5858 + return p + ((S - (cast(size_t)p & (S-1))) & (S-1)); // cast ok even if 64-bit
5859 + }
5860 +
5861 + static void * adjust_down( void* p )
5862 + {
5863 + return p - (cast(size_t) p & (S-1));
5864 + }
5865 +
5866 + version( Win32 )
5867 + {
5868 + void* start = adjust_up( &Data_Start );
5869 + void* end = adjust_down( &Data_End );
5870 + gc_addRange(start, cast(size_t)end - cast(size_t)start);
5871 + }
5872 + else version( GC_Use_Data_Proc_Maps )
5873 + {
5874 + // TODO: Exclude zero-mapped regions
5875 +
5876 + int fd = open("/proc/self/maps", O_RDONLY);
5877 + int count; // %% need to configure ret for read..
5878 + char buf[2024];
5879 + char* p;
5880 + char* e;
5881 + char* s;
5882 + void* start;
5883 + void* end;
5884 +
5885 + void* dataStart = adjust_up( &Data_Start );
5886 + void* dataEnd = adjust_down( &Data_End );
5887 +
5888 + gc_addRange(dataStart, cast(size_t)dataEnd - cast(size_t)dataStart);
5889 +
5890 + p = buf.ptr;
5891 + if (fd != -1)
5892 + {
5893 + while ( (count = read(fd, p, buf.sizeof - (p - buf.ptr))) > 0 )
5894 + {
5895 + e = p + count;
5896 + p = buf.ptr;
5897 + while (true)
5898 + {
5899 + s = p;
5900 + while (p < e && *p != '\n')
5901 + p++;
5902 + if (p < e)
5903 + {
5904 + // parse the entry in [s, p)
5905 + static if( S == 4 )
5906 + {
5907 + enum Ofs
5908 + {
5909 + Write_Prot = 19,
5910 + Start_Addr = 0,
5911 + End_Addr = 9,
5912 + Addr_Len = 8,
5913 + }
5914 + }
5915 + else static if( S == 8 )
5916 + {
5917 + enum Ofs
5918 + {
5919 + Write_Prot = 35,
5920 + Start_Addr = 0,
5921 + End_Addr = 9,
5922 + Addr_Len = 17,
5923 + }
5924 + }
5925 + else
5926 + {
5927 + static assert( false );
5928 + }
5929 +
5930 + // %% this is wrong for 64-bit:
5931 + // uint strtoul(char *,char **,int);
5932 +
5933 + if( s[Ofs.Write_Prot] == 'w' )
5934 + {
5935 + s[Ofs.Start_Addr + Ofs.Addr_Len] = '\0';
5936 + s[Ofs.End_Addr + Ofs.Addr_Len] = '\0';
5937 + start = cast(void*) strtoul(s + Ofs.Start_Addr, null, 16);
5938 + end = cast(void*) strtoul(s + Ofs.End_Addr, null, 16);
5939 +
5940 + // 1. Exclude anything overlapping [dataStart, dataEnd)
5941 + // 2. Exclude stack
5942 + if ( ( !dataEnd ||
5943 + !( dataStart >= start && dataEnd <= end ) ) &&
5944 + !( &buf[0] >= start && &buf[0] < end ) )
5945 + {
5946 + // we already have static data from this region. anything else
5947 + // is heap (%% check)
5948 + debug (ProcMaps) printf("Adding map range %p 0%p\n", start, end);
5949 + gc_addRange(start, cast(size_t)end - cast(size_t)start);
5950 + }
5951 + }
5952 + p++;
5953 + }
5954 + else
5955 + {
5956 + count = p - s;
5957 + memmove(buf.ptr, s, count);
5958 + p = buf.ptr + count;
5959 + break;
5960 + }
5961 + }
5962 + }
5963 + close(fd);
5964 + }
5965 + }
5966 + else version(linux)
5967 + {
5968 + void* start = adjust_up( &Data_Start );
5969 + void* end = adjust_down( &Data_End );
5970 + gc_addRange(start, cast(size_t)end - cast(size_t)start);
5971 + }
5972 + else
5973 + {
5974 + static assert( false, "Operating system not supported." );
5975 + }
5976 +}
5977 Index: src/compiler/ldc/dmain2.d
5978 ===================================================================
5979 --- src/compiler/ldc/dmain2.d (revision 0)
5980 +++ src/compiler/ldc/dmain2.d (revision 0)
5981 @@ -0,0 +1,378 @@
5982 +/*
5983 + * Placed into the Public Domain.
5984 + * written by Walter Bright
5985 + * www.digitalmars.com
5986 + */
5987 +
5988 +/*
5989 + * Modified by Sean Kelly for use with the D Runtime Project
5990 + */
5991 +
5992 +/*
5993 + * Modified by Tomas Lindquist Olsen for use with the LLVM D Compiler
5994 + */
5995 +
5996 +module rt.dmain2;
5997 +
5998 +private
5999 +{
6000 + import memory;
6001 + import util.console;
6002 + import core.stdc.stddef;
6003 + import core.stdc.stdlib;
6004 + import core.stdc.string;
6005 +}
6006 +
6007 +version (Windows)
6008 +{
6009 + extern (Windows) alias int function() FARPROC;
6010 + extern (Windows) FARPROC GetProcAddress(void*, in char*);
6011 + extern (Windows) void* LoadLibraryA(in char*);
6012 + extern (Windows) int FreeLibrary(void*);
6013 + extern (Windows) void* LocalFree(void*);
6014 + extern (Windows) wchar_t* GetCommandLineW();
6015 + extern (Windows) wchar_t** CommandLineToArgvW(wchar_t*, int*);
6016 + extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int);
6017 + pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
6018 +}
6019 +
6020 +extern (C) void _STI_monitor_staticctor();
6021 +extern (C) void _STD_monitor_staticdtor();
6022 +extern (C) void _STI_critical_init();
6023 +extern (C) void _STD_critical_term();
6024 +extern (C) void gc_init();
6025 +extern (C) void gc_term();
6026 +extern (C) void _minit();
6027 +extern (C) void _moduleCtor();
6028 +extern (C) void _moduleDtor();
6029 +extern (C) void thread_joinAll();
6030 +
6031 +/***********************************
6032 + * These are a temporary means of providing a GC hook for DLL use. They may be
6033 + * replaced with some other similar functionality later.
6034 + */
6035 +extern (C)
6036 +{
6037 + void* gc_getProxy();
6038 + void gc_setProxy(void* p);
6039 + void gc_clrProxy();
6040 +
6041 + alias void* function() gcGetFn;
6042 + alias void function(void*) gcSetFn;
6043 + alias void function() gcClrFn;
6044 +}
6045 +
6046 +extern (C) void* rt_loadLibrary(in char[] name)
6047 +{
6048 + version (Windows)
6049 + {
6050 + char[260] temp = void;
6051 + temp[0 .. name.length] = name[];
6052 + temp[name.length] = cast(char) 0;
6053 + void* ptr = LoadLibraryA(temp.ptr);
6054 + if (ptr is null)
6055 + return ptr;
6056 + gcSetFn gcSet = cast(gcSetFn) GetProcAddress(ptr, "gc_setProxy");
6057 + if (gcSet !is null)
6058 + gcSet(gc_getProxy());
6059 + return ptr;
6060 +
6061 + }
6062 + else version (linux)
6063 + {
6064 + throw new Exception("rt_loadLibrary not yet implemented on linux.");
6065 + }
6066 +}
6067 +
6068 +extern (C) bool rt_unloadLibrary(void* ptr)
6069 +{
6070 + version (Windows)
6071 + {
6072 + gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
6073 + if (gcClr !is null)
6074 + gcClr();
6075 + return FreeLibrary(ptr) != 0;
6076 + }
6077 + else version (linux)
6078 + {
6079 + throw new Exception("rt_unloadLibrary not yet implemented on linux.");
6080 + }
6081 +}
6082 +
6083 +/***********************************
6084 + * These functions must be defined for any D program linked
6085 + * against this library.
6086 + */
6087 +extern (C) void onAssertError(string file, size_t line);
6088 +extern (C) void onAssertErrorMsg(string file, size_t line, string msg);
6089 +extern (C) void onRangeError(string file, size_t line);
6090 +extern (C) void onHiddenFuncError(Object o);
6091 +extern (C) void onSwitchError(string file, size_t line);
6092 +extern (C) bool runModuleUnitTests();
6093 +
6094 +// this function is called from the utf module
6095 +//extern (C) void onUnicodeError(string msg, size_t idx);
6096 +
6097 +/***********************************
6098 + * These are internal callbacks for various language errors.
6099 + */
6100 +extern (C) void _d_assert(string file, uint line)
6101 +{
6102 + onAssertError(file, line);
6103 +}
6104 +
6105 +extern (C) static void _d_assert_msg(string msg, string file, uint line)
6106 +{
6107 + onAssertErrorMsg(file, line, msg);
6108 +}
6109 +
6110 +extern (C) void _d_array_bounds(string file, uint line)
6111 +{
6112 + onRangeError(file, line);
6113 +}
6114 +
6115 +extern (C) void _d_switch_error(string file, uint line)
6116 +{
6117 + onSwitchError(file, line);
6118 +}
6119 +
6120 +extern (C) void _d_hidden_func()
6121 +{
6122 + Object o;
6123 + asm
6124 + {
6125 + mov o, EAX;
6126 + }
6127 + onHiddenFuncError(o);
6128 +}
6129 +
6130 +bool _d_isHalting = false;
6131 +
6132 +extern (C) bool rt_isHalting()
6133 +{
6134 + return _d_isHalting;
6135 +}
6136 +
6137 +extern (C) bool rt_trapExceptions = true;
6138 +
6139 +void _d_criticalInit()
6140 +{
6141 + version (linux)
6142 + {
6143 + _STI_monitor_staticctor();
6144 + _STI_critical_init();
6145 + }
6146 +}
6147 +
6148 +alias void delegate(Throwable) ExceptionHandler;
6149 +
6150 +extern (C) bool rt_init(ExceptionHandler dg = null)
6151 +{
6152 + _d_criticalInit();
6153 +
6154 + try
6155 + {
6156 + gc_init();
6157 + initStaticDataGC();
6158 + version (Windows)
6159 + _minit();
6160 + _moduleCtor();
6161 + return true;
6162 + }
6163 + catch (Throwable e)
6164 + {
6165 + if (dg)
6166 + dg(e);
6167 + }
6168 + catch
6169 + {
6170 +
6171 + }
6172 + _d_criticalTerm();
6173 + return false;
6174 +}
6175 +
6176 +void _d_criticalTerm()
6177 +{
6178 + version (linux)
6179 + {
6180 + _STD_critical_term();
6181 + _STD_monitor_staticdtor();
6182 + }
6183 +}
6184 +
6185 +extern (C) bool rt_term(ExceptionHandler dg = null)
6186 +{
6187 + try
6188 + {
6189 + thread_joinAll();
6190 + _d_isHalting = true;
6191 + _moduleDtor();
6192 + gc_term();
6193 + return true;
6194 + }
6195 + catch (Throwable e)
6196 + {
6197 + if (dg)
6198 + dg(e);
6199 + }
6200 + catch
6201 + {
6202 +
6203 + }
6204 + finally
6205 + {
6206 + _d_criticalTerm();
6207 + }
6208 + return false;
6209 +}
6210 +
6211 +/***********************************
6212 + * The D main() function supplied by the user's program
6213 + */
6214 +int main(char[][] args);
6215 +
6216 +/***********************************
6217 + * Substitutes for the C main() function.
6218 + * It's purpose is to wrap the call to the D main()
6219 + * function and catch any unhandled exceptions.
6220 + */
6221 +
6222 +extern (C) int main(int argc, char **argv)
6223 +{
6224 + char[][] args;
6225 + int result;
6226 +
6227 + version (linux)
6228 + {
6229 + _STI_monitor_staticctor();
6230 + _STI_critical_init();
6231 + }
6232 +
6233 + version (Windows)
6234 + {
6235 + wchar_t* wcbuf = GetCommandLineW();
6236 + size_t wclen = wcslen(wcbuf);
6237 + int wargc = 0;
6238 + wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
6239 + assert(wargc == argc);
6240 +
6241 + char* cargp = null;
6242 + size_t cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
6243 +
6244 + cargp = cast(char*) alloca(cargl);
6245 + args = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
6246 +
6247 + for (size_t i = 0, p = 0; i < wargc; i++)
6248 + {
6249 + int wlen = wcslen(wargs[i]);
6250 + int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
6251 + args[i] = cargp[p .. p+clen];
6252 + p += clen; assert(p <= cargl);
6253 + WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
6254 + }
6255 + LocalFree(wargs);
6256 + wargs = null;
6257 + wargc = 0;
6258 + }
6259 + else version (linux)
6260 + {
6261 + char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
6262 + scope(exit) free(am);
6263 +
6264 + for (size_t i = 0; i < argc; i++)
6265 + {
6266 + auto len = strlen(argv[i]);
6267 + am[i] = argv[i][0 .. len];
6268 + }
6269 + args = am[0 .. argc];
6270 + }
6271 +
6272 + bool trapExceptions = rt_trapExceptions;
6273 +
6274 + void tryExec(scope void delegate() dg)
6275 + {
6276 +
6277 + if (trapExceptions)
6278 + {
6279 + try
6280 + {
6281 + dg();
6282 + }
6283 + catch (Throwable e)
6284 + {
6285 + while (e)
6286 + {
6287 + if (e.file)
6288 + {
6289 + // fprintf(stderr, "%.*s(%u): %.*s\n", e.file, e.line, e.msg);
6290 + console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.msg)("\n");
6291 + }
6292 + else
6293 + {
6294 + // fprintf(stderr, "%.*s\n", e.toString());
6295 + console (e.toString)("\n");
6296 + }
6297 + if (e.info)
6298 + {
6299 + console ("----------------\n");
6300 + foreach (t; e.info)
6301 + console (t)("\n");
6302 + }
6303 + if (e.next)
6304 + console ("\n");
6305 + e = e.next;
6306 + }
6307 + result = EXIT_FAILURE;
6308 + }
6309 + catch (Object o)
6310 + {
6311 + // fprintf(stderr, "%.*s\n", o.toString());
6312 + console (o.toString)("\n");
6313 + result = EXIT_FAILURE;
6314 + }
6315 + }
6316 + else
6317 + {
6318 + dg();
6319 + }
6320 + }
6321 +
6322 + // NOTE: The lifetime of a process is much like the lifetime of an object:
6323 + // it is initialized, then used, then destroyed. If initialization
6324 + // fails, the successive two steps are never reached. However, if
6325 + // initialization succeeds, then cleanup will occur even if the use
6326 + // step fails in some way. Here, the use phase consists of running
6327 + // the user's main function. If main terminates with an exception,
6328 + // the exception is handled and then cleanup begins. An exception
6329 + // thrown during cleanup, however, will abort the cleanup process.
6330 +
6331 + void runMain()
6332 + {
6333 + result = main(args);
6334 + }
6335 +
6336 + void runAll()
6337 + {
6338 + gc_init();
6339 + initStaticDataGC();
6340 + version (Windows)
6341 + _minit();
6342 + _moduleCtor();
6343 + if (runModuleUnitTests())
6344 + tryExec(&runMain);
6345 + thread_joinAll();
6346 + _d_isHalting = true;
6347 + _moduleDtor();
6348 + gc_term();
6349 + }
6350 +
6351 + tryExec(&runAll);
6352 +
6353 + version (linux)
6354 + {
6355 + _STD_critical_term();
6356 + _STD_monitor_staticdtor();
6357 + }
6358 + return result;
6359 +}
6360 Index: src/compiler/ldc/typeinfo/ti_void.d
6361 ===================================================================
6362 --- src/compiler/ldc/typeinfo/ti_void.d (revision 0)
6363 +++ src/compiler/ldc/typeinfo/ti_void.d (revision 0)
6364 @@ -0,0 +1,43 @@
6365 +
6366 +// void
6367 +
6368 +module rt.typeinfo.ti_void;
6369 +
6370 +class TypeInfo_v : TypeInfo
6371 +{
6372 + override string toString() { return "void"; }
6373 +
6374 + override hash_t getHash(in void* p)
6375 + {
6376 + assert(0);
6377 + }
6378 +
6379 + override equals_t equals(in void* p1, in void* p2)
6380 + {
6381 + return *cast(byte *)p1 == *cast(byte *)p2;
6382 + }
6383 +
6384 + override int compare(in void* p1, in void* p2)
6385 + {
6386 + return *cast(byte *)p1 - *cast(byte *)p2;
6387 + }
6388 +
6389 + override size_t tsize()
6390 + {
6391 + return void.sizeof;
6392 + }
6393 +
6394 + override void swap(void *p1, void *p2)
6395 + {
6396 + byte t;
6397 +
6398 + t = *cast(byte *)p1;
6399 + *cast(byte *)p1 = *cast(byte *)p2;
6400 + *cast(byte *)p2 = t;
6401 + }
6402 +
6403 + override uint flags()
6404 + {
6405 + return 1;
6406 + }
6407 +}
6408 Index: src/compiler/ldc/typeinfo/ti_wchar.d
6409 ===================================================================
6410 --- src/compiler/ldc/typeinfo/ti_wchar.d (revision 0)
6411 +++ src/compiler/ldc/typeinfo/ti_wchar.d (revision 0)
6412 @@ -0,0 +1,43 @@
6413 +
6414 +module rt.typeinfo.ti_wchar;
6415 +
6416 +
6417 +class TypeInfo_u : TypeInfo
6418 +{
6419 + override string toString() { return "wchar"; }
6420 +
6421 + override hash_t getHash(in void* p)
6422 + {
6423 + return *cast(wchar *)p;
6424 + }
6425 +
6426 + override equals_t equals(in void* p1, in void* p2)
6427 + {
6428 + return *cast(wchar *)p1 == *cast(wchar *)p2;
6429 + }
6430 +
6431 + override int compare(in void* p1, in void* p2)
6432 + {
6433 + return *cast(wchar *)p1 - *cast(wchar *)p2;
6434 + }
6435 +
6436 + override size_t tsize()
6437 + {
6438 + return wchar.sizeof;
6439 + }
6440 +
6441 + override void swap(void *p1, void *p2)
6442 + {
6443 + wchar t;
6444 +
6445 + t = *cast(wchar *)p1;
6446 + *cast(wchar *)p1 = *cast(wchar *)p2;
6447 + *cast(wchar *)p2 = t;
6448 + }
6449 +
6450 + override void[] init()
6451 + { static wchar c;
6452 +
6453 + return (cast(wchar *)&c)[0 .. 1];
6454 + }
6455 +}
6456 Index: src/compiler/ldc/typeinfo/ti_ptr.d
6457 ===================================================================
6458 --- src/compiler/ldc/typeinfo/ti_ptr.d (revision 0)
6459 +++ src/compiler/ldc/typeinfo/ti_ptr.d (revision 0)
6460 @@ -0,0 +1,46 @@
6461 +
6462 +// pointer
6463 +
6464 +module rt.typeinfo.ti_ptr;
6465 +
6466 +class TypeInfo_P : TypeInfo
6467 +{
6468 + override hash_t getHash(in void* p)
6469 + {
6470 + return cast(uint)*cast(void* *)p;
6471 + }
6472 +
6473 + override equals_t equals(in void* p1, in void* p2)
6474 + {
6475 + return *cast(void* *)p1 == *cast(void* *)p2;
6476 + }
6477 +
6478 + override int compare(in void* p1, in void* p2)
6479 + {
6480 + auto c = *cast(void* *)p1 - *cast(void* *)p2;
6481 + if (c < 0)
6482 + return -1;
6483 + else if (c > 0)
6484 + return 1;
6485 + return 0;
6486 + }
6487 +
6488 + override size_t tsize()
6489 + {
6490 + return (void*).sizeof;
6491 + }
6492 +
6493 + override void swap(void *p1, void *p2)
6494 + {
6495 + void* t;
6496 +
6497 + t = *cast(void* *)p1;
6498 + *cast(void* *)p1 = *cast(void* *)p2;
6499 + *cast(void* *)p2 = t;
6500 + }
6501 +
6502 + override uint flags()
6503 + {
6504 + return 1;
6505 + }
6506 +}
6507 Index: src/compiler/ldc/typeinfo/ti_Afloat.d
6508 ===================================================================
6509 --- src/compiler/ldc/typeinfo/ti_Afloat.d (revision 0)
6510 +++ src/compiler/ldc/typeinfo/ti_Afloat.d (revision 0)
6511 @@ -0,0 +1,114 @@
6512 +/*
6513 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
6514 + * Written by Walter Bright
6515 + *
6516 + * This software is provided 'as-is', without any express or implied
6517 + * warranty. In no event will the authors be held liable for any damages
6518 + * arising from the use of this software.
6519 + *
6520 + * Permission is granted to anyone to use this software for any purpose,
6521 + * including commercial applications, and to alter it and redistribute it
6522 + * freely, in both source and binary form, subject to the following
6523 + * restrictions:
6524 + *
6525 + * o The origin of this software must not be misrepresented; you must not
6526 + * claim that you wrote the original software. If you use this software
6527 + * in a product, an acknowledgment in the product documentation would be
6528 + * appreciated but is not required.
6529 + * o Altered source versions must be plainly marked as such, and must not
6530 + * be misrepresented as being the original software.
6531 + * o This notice may not be removed or altered from any source
6532 + * distribution.
6533 + */
6534 +
6535 +module rt.typeinfo.ti_Afloat;
6536 +
6537 +private import typeinfo.ti_float;
6538 +
6539 +// float[]
6540 +
6541 +class TypeInfo_Af : TypeInfo
6542 +{
6543 + override string toString() { return "float[]"; }
6544 +
6545 + override hash_t getHash(in void* p)
6546 + { float[] s = *cast(float[]*)p;
6547 + size_t len = s.length;
6548 + auto str = s.ptr;
6549 + hash_t hash = 0;
6550 +
6551 + while (len)
6552 + {
6553 + hash *= 9;
6554 + hash += *cast(uint *)str;
6555 + str++;
6556 + len--;
6557 + }
6558 +
6559 + return hash;
6560 + }
6561 +
6562 + override equals_t equals(in void* p1, in void* p2)
6563 + {
6564 + float[] s1 = *cast(float[]*)p1;
6565 + float[] s2 = *cast(float[]*)p2;
6566 + size_t len = s1.length;
6567 +
6568 + if (len != s2.length)
6569 + return 0;
6570 + for (size_t u = 0; u < len; u++)
6571 + {
6572 + if (!TypeInfo_f._equals(s1[u], s2[u]))
6573 + return false;
6574 + }
6575 + return true;
6576 + }
6577 +
6578 + override int compare(in void* p1, in void* p2)
6579 + {
6580 + float[] s1 = *cast(float[]*)p1;
6581 + float[] s2 = *cast(float[]*)p2;
6582 + size_t len = s1.length;
6583 +
6584 + if (s2.length < len)
6585 + len = s2.length;
6586 + for (size_t u = 0; u < len; u++)
6587 + {
6588 + int c = TypeInfo_f._compare(s1[u], s2[u]);
6589 + if (c)
6590 + return c;
6591 + }
6592 + if (s1.length < s2.length)
6593 + return -1;
6594 + else if (s1.length > s2.length)
6595 + return 1;
6596 + return 0;
6597 + }
6598 +
6599 + override size_t tsize()
6600 + {
6601 + return (float[]).sizeof;
6602 + }
6603 +
6604 + override uint flags()
6605 + {
6606 + return 1;
6607 + }
6608 +
6609 + override TypeInfo next()
6610 + {
6611 + return typeid(float);
6612 + }
6613 +}
6614 +
6615 +// ifloat[]
6616 +
6617 +class TypeInfo_Ao : TypeInfo_Af
6618 +{
6619 + override string toString() { return "ifloat[]"; }
6620 +
6621 + override TypeInfo next()
6622 + {
6623 + return typeid(ifloat);
6624 + }
6625 +}
6626 Index: src/compiler/ldc/typeinfo/ti_double.d
6627 ===================================================================
6628 --- src/compiler/ldc/typeinfo/ti_double.d (revision 0)
6629 +++ src/compiler/ldc/typeinfo/ti_double.d (revision 0)
6630 @@ -0,0 +1,64 @@
6631 +
6632 +// double
6633 +
6634 +module rt.typeinfo.ti_double;
6635 +
6636 +class TypeInfo_d : TypeInfo
6637 +{
6638 + override string toString() { return "double"; }
6639 +
6640 + override hash_t getHash(in void* p)
6641 + {
6642 + return (cast(uint *)p)[0] + (cast(uint *)p)[1];
6643 + }
6644 +
6645 + static equals_t _equals(double f1, double f2)
6646 + {
6647 + return f1 == f2 ||
6648 + (f1 !<>= f1 && f2 !<>= f2);
6649 + }
6650 +
6651 + static int _compare(double d1, double d2)
6652 + {
6653 + if (d1 !<>= d2) // if either are NaN
6654 + {
6655 + if (d1 !<>= d1)
6656 + { if (d2 !<>= d2)
6657 + return 0;
6658 + return -1;
6659 + }
6660 + return 1;
6661 + }
6662 + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
6663 + }
6664 +
6665 + override equals_t equals(in void* p1, in void* p2)
6666 + {
6667 + return _equals(*cast(double *)p1, *cast(double *)p2);
6668 + }
6669 +
6670 + override int compare(in void* p1, in void* p2)
6671 + {
6672 + return _compare(*cast(double *)p1, *cast(double *)p2);
6673 + }
6674 +
6675 + override size_t tsize()
6676 + {
6677 + return double.sizeof;
6678 + }
6679 +
6680 + override void swap(void *p1, void *p2)
6681 + {
6682 + double t;
6683 +
6684 + t = *cast(double *)p1;
6685 + *cast(double *)p1 = *cast(double *)p2;
6686 + *cast(double *)p2 = t;
6687 + }
6688 +
6689 + override void[] init()
6690 + { static double r;
6691 +
6692 + return (cast(double *)&r)[0 .. 1];
6693 + }
6694 +}
6695 Index: src/compiler/ldc/typeinfo/ti_delegate.d
6696 ===================================================================
6697 --- src/compiler/ldc/typeinfo/ti_delegate.d (revision 0)
6698 +++ src/compiler/ldc/typeinfo/ti_delegate.d (revision 0)
6699 @@ -0,0 +1,39 @@
6700 +
6701 +// delegate
6702 +
6703 +module rt.typeinfo.ti_delegate;
6704 +
6705 +alias void delegate(int) dg;
6706 +
6707 +class TypeInfo_D : TypeInfo
6708 +{
6709 + override hash_t getHash(in void* p)
6710 + { long l = *cast(long *)p;
6711 +
6712 + return cast(uint)(l + (l >> 32));
6713 + }
6714 +
6715 + override equals_t equals(in void* p1, in void* p2)
6716 + {
6717 + return *cast(dg *)p1 == *cast(dg *)p2;
6718 + }
6719 +
6720 + override size_t tsize()
6721 + {
6722 + return dg.sizeof;
6723 + }
6724 +
6725 + override void swap(void *p1, void *p2)
6726 + {
6727 + dg t;
6728 +
6729 + t = *cast(dg *)p1;
6730 + *cast(dg *)p1 = *cast(dg *)p2;
6731 + *cast(dg *)p2 = t;
6732 + }
6733 +
6734 + override uint flags()
6735 + {
6736 + return 1;
6737 + }
6738 +}
6739 Index: src/compiler/ldc/typeinfo/ti_Adouble.d
6740 ===================================================================
6741 --- src/compiler/ldc/typeinfo/ti_Adouble.d (revision 0)
6742 +++ src/compiler/ldc/typeinfo/ti_Adouble.d (revision 0)
6743 @@ -0,0 +1,115 @@
6744 +/*
6745 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
6746 + * Written by Walter Bright
6747 + *
6748 + * This software is provided 'as-is', without any express or implied
6749 + * warranty. In no event will the authors be held liable for any damages
6750 + * arising from the use of this software.
6751 + *
6752 + * Permission is granted to anyone to use this software for any purpose,
6753 + * including commercial applications, and to alter it and redistribute it
6754 + * freely, in both source and binary form, subject to the following
6755 + * restrictions:
6756 + *
6757 + * o The origin of this software must not be misrepresented; you must not
6758 + * claim that you wrote the original software. If you use this software
6759 + * in a product, an acknowledgment in the product documentation would be
6760 + * appreciated but is not required.
6761 + * o Altered source versions must be plainly marked as such, and must not
6762 + * be misrepresented as being the original software.
6763 + * o This notice may not be removed or altered from any source
6764 + * distribution.
6765 + */
6766 +
6767 +module rt.typeinfo.ti_Adouble;
6768 +
6769 +private import typeinfo.ti_double;
6770 +
6771 +// double[]
6772 +
6773 +class TypeInfo_Ad : TypeInfo
6774 +{
6775 + override string toString() { return "double[]"; }
6776 +
6777 + override hash_t getHash(in void* p)
6778 + { double[] s = *cast(double[]*)p;
6779 + size_t len = s.length;
6780 + auto str = s.ptr;
6781 + hash_t hash = 0;
6782 +
6783 + while (len)
6784 + {
6785 + hash *= 9;
6786 + hash += (cast(uint *)str)[0];
6787 + hash += (cast(uint *)str)[1];
6788 + str++;
6789 + len--;
6790 + }
6791 +
6792 + return hash;
6793 + }
6794 +
6795 + override equals_t equals(in void* p1, in void* p2)
6796 + {
6797 + double[] s1 = *cast(double[]*)p1;
6798 + double[] s2 = *cast(double[]*)p2;
6799 + size_t len = s1.length;
6800 +
6801 + if (len != s2.length)
6802 + return 0;
6803 + for (size_t u = 0; u < len; u++)
6804 + {
6805 + if (!TypeInfo_d._equals(s1[u], s2[u]))
6806 + return false;
6807 + }
6808 + return true;
6809 + }
6810 +
6811 + override int compare(in void* p1, in void* p2)
6812 + {
6813 + double[] s1 = *cast(double[]*)p1;
6814 + double[] s2 = *cast(double[]*)p2;
6815 + size_t len = s1.length;
6816 +
6817 + if (s2.length < len)
6818 + len = s2.length;
6819 + for (size_t u = 0; u < len; u++)
6820 + {
6821 + int c = TypeInfo_d._compare(s1[u], s2[u]);
6822 + if (c)
6823 + return c;
6824 + }
6825 + if (s1.length < s2.length)
6826 + return -1;
6827 + else if (s1.length > s2.length)
6828 + return 1;
6829 + return 0;
6830 + }
6831 +
6832 + override size_t tsize()
6833 + {
6834 + return (double[]).sizeof;
6835 + }
6836 +
6837 + override uint flags()
6838 + {
6839 + return 1;
6840 + }
6841 +
6842 + override TypeInfo next()
6843 + {
6844 + return typeid(double);
6845 + }
6846 +}
6847 +
6848 +// idouble[]
6849 +
6850 +class TypeInfo_Ap : TypeInfo_Ad
6851 +{
6852 + override string toString() { return "idouble[]"; }
6853 +
6854 + override TypeInfo next()
6855 + {
6856 + return typeid(idouble);
6857 + }
6858 +}
6859 Index: src/compiler/ldc/typeinfo/ti_char.d
6860 ===================================================================
6861 --- src/compiler/ldc/typeinfo/ti_char.d (revision 0)
6862 +++ src/compiler/ldc/typeinfo/ti_char.d (revision 0)
6863 @@ -0,0 +1,42 @@
6864 +
6865 +module rt.typeinfo.ti_char;
6866 +
6867 +class TypeInfo_a : TypeInfo
6868 +{
6869 + override string toString() { return "char"; }
6870 +
6871 + override hash_t getHash(in void* p)
6872 + {
6873 + return *cast(char *)p;
6874 + }
6875 +
6876 + override equals_t equals(in void* p1, in void* p2)
6877 + {
6878 + return *cast(char *)p1 == *cast(char *)p2;
6879 + }
6880 +
6881 + override int compare(in void* p1, in void* p2)
6882 + {
6883 + return *cast(char *)p1 - *cast(char *)p2;
6884 + }
6885 +
6886 + override size_t tsize()
6887 + {
6888 + return char.sizeof;
6889 + }
6890 +
6891 + override void swap(void *p1, void *p2)
6892 + {
6893 + char t;
6894 +
6895 + t = *cast(char *)p1;
6896 + *cast(char *)p1 = *cast(char *)p2;
6897 + *cast(char *)p2 = t;
6898 + }
6899 +
6900 + override void[] init()
6901 + { static char c;
6902 +
6903 + return (cast(char *)&c)[0 .. 1];
6904 + }
6905 +}
6906 Index: src/compiler/ldc/typeinfo/ti_Acdouble.d
6907 ===================================================================
6908 --- src/compiler/ldc/typeinfo/ti_Acdouble.d (revision 0)
6909 +++ src/compiler/ldc/typeinfo/ti_Acdouble.d (revision 0)
6910 @@ -0,0 +1,105 @@
6911 +/*
6912 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
6913 + * Written by Walter Bright
6914 + *
6915 + * This software is provided 'as-is', without any express or implied
6916 + * warranty. In no event will the authors be held liable for any damages
6917 + * arising from the use of this software.
6918 + *
6919 + * Permission is granted to anyone to use this software for any purpose,
6920 + * including commercial applications, and to alter it and redistribute it
6921 + * freely, in both source and binary form, subject to the following
6922 + * restrictions:
6923 + *
6924 + * o The origin of this software must not be misrepresented; you must not
6925 + * claim that you wrote the original software. If you use this software
6926 + * in a product, an acknowledgment in the product documentation would be
6927 + * appreciated but is not required.
6928 + * o Altered source versions must be plainly marked as such, and must not
6929 + * be misrepresented as being the original software.
6930 + * o This notice may not be removed or altered from any source
6931 + * distribution.
6932 + */
6933 +
6934 +module rt.typeinfo.ti_Acdouble;
6935 +
6936 +private import typeinfo.ti_cdouble;
6937 +
6938 +// cdouble[]
6939 +
6940 +class TypeInfo_Ar : TypeInfo
6941 +{
6942 + override string toString() { return "cdouble[]"; }
6943 +
6944 + override hash_t getHash(in void* p)
6945 + { cdouble[] s = *cast(cdouble[]*)p;
6946 + size_t len = s.length;
6947 + cdouble *str = s.ptr;
6948 + hash_t hash = 0;
6949 +
6950 + while (len)
6951 + {
6952 + hash *= 9;
6953 + hash += (cast(uint *)str)[0];
6954 + hash += (cast(uint *)str)[1];
6955 + hash += (cast(uint *)str)[2];
6956 + hash += (cast(uint *)str)[3];
6957 + str++;
6958 + len--;
6959 + }
6960 +
6961 + return hash;
6962 + }
6963 +
6964 + override equals_t equals(in void* p1, in void* p2)
6965 + {
6966 + cdouble[] s1 = *cast(cdouble[]*)p1;
6967 + cdouble[] s2 = *cast(cdouble[]*)p2;
6968 + size_t len = s1.length;
6969 +
6970 + if (len != s2.length)
6971 + return false;
6972 + for (size_t u = 0; u < len; u++)
6973 + {
6974 + if (!TypeInfo_r._equals(s1[u], s2[u]))
6975 + return false;
6976 + }
6977 + return true;
6978 + }
6979 +
6980 + override int compare(in void* p1, in void* p2)
6981 + {
6982 + cdouble[] s1 = *cast(cdouble[]*)p1;
6983 + cdouble[] s2 = *cast(cdouble[]*)p2;
6984 + size_t len = s1.length;
6985 +
6986 + if (s2.length < len)
6987 + len = s2.length;
6988 + for (size_t u = 0; u < len; u++)
6989 + {
6990 + int c = TypeInfo_r._compare(s1[u], s2[u]);
6991 + if (c)
6992 + return c;
6993 + }
6994 + if (s1.length < s2.length)
6995 + return -1;
6996 + else if (s1.length > s2.length)
6997 + return 1;
6998 + return 0;
6999 + }
7000 +
7001 + override size_t tsize()
7002 + {
7003 + return (cdouble[]).sizeof;
7004 + }
7005 +
7006 + override uint flags()
7007 + {
7008 + return 1;
7009 + }
7010 +
7011 + override TypeInfo next()
7012 + {
7013 + return typeid(cdouble);
7014 + }
7015 +}
7016 Index: src/compiler/ldc/typeinfo/ti_uint.d
7017 ===================================================================
7018 --- src/compiler/ldc/typeinfo/ti_uint.d (revision 0)
7019 +++ src/compiler/ldc/typeinfo/ti_uint.d (revision 0)
7020 @@ -0,0 +1,42 @@
7021 +
7022 +// uint
7023 +
7024 +module rt.typeinfo.ti_uint;
7025 +
7026 +class TypeInfo_k : TypeInfo
7027 +{
7028 + override string toString() { return "uint"; }
7029 +
7030 + override hash_t getHash(in void* p)
7031 + {
7032 + return *cast(uint *)p;
7033 + }
7034 +
7035 + override equals_t equals(in void* p1, in void* p2)
7036 + {
7037 + return *cast(uint *)p1 == *cast(uint *)p2;
7038 + }
7039 +
7040 + override int compare(in void* p1, in void* p2)
7041 + {
7042 + if (*cast(uint*) p1 < *cast(uint*) p2)
7043 + return -1;
7044 + else if (*cast(uint*) p1 > *cast(uint*) p2)
7045 + return 1;
7046 + return 0;
7047 + }
7048 +
7049 + override size_t tsize()
7050 + {
7051 + return uint.sizeof;
7052 + }
7053 +
7054 + override void swap(void *p1, void *p2)
7055 + {
7056 + int t;
7057 +
7058 + t = *cast(uint *)p1;
7059 + *cast(uint *)p1 = *cast(uint *)p2;
7060 + *cast(uint *)p2 = t;
7061 + }
7062 +}
7063 Index: src/compiler/ldc/typeinfo/ti_AC.d
7064 ===================================================================
7065 --- src/compiler/ldc/typeinfo/ti_AC.d (revision 0)
7066 +++ src/compiler/ldc/typeinfo/ti_AC.d (revision 0)
7067 @@ -0,0 +1,95 @@
7068 +module rt.typeinfo.ti_AC;
7069 +
7070 +// Object[]
7071 +
7072 +class TypeInfo_AC : TypeInfo
7073 +{
7074 + override hash_t getHash(in void* p)
7075 + { Object[] s = *cast(Object[]*)p;
7076 + hash_t hash = 0;
7077 +
7078 + foreach (Object o; s)
7079 + {
7080 + if (o)
7081 + hash += o.toHash();
7082 + }
7083 + return hash;
7084 + }
7085 +
7086 + override equals_t equals(in void* p1, in void* p2)
7087 + {
7088 + Object[] s1 = *cast(Object[]*)p1;
7089 + Object[] s2 = *cast(Object[]*)p2;
7090 +
7091 + if (s1.length == s2.length)
7092 + {
7093 + for (size_t u = 0; u < s1.length; u++)
7094 + { Object o1 = s1[u];
7095 + Object o2 = s2[u];
7096 +
7097 + // Do not pass null's to Object.opEquals()
7098 + if (o1 is o2 ||
7099 + (!(o1 is null) && !(o2 is null) && o1.opEquals(o2)))
7100 + continue;
7101 + return false;
7102 + }
7103 + return true;
7104 + }
7105 + return false;
7106 + }
7107 +
7108 + override int compare(in void* p1, in void* p2)
7109 + {
7110 + Object[] s1 = *cast(Object[]*)p1;
7111 + Object[] s2 = *cast(Object[]*)p2;
7112 + ptrdiff_t c;
7113 +
7114 + c = cast(ptrdiff_t)s1.length - cast(ptrdiff_t)s2.length;
7115 + if (c == 0)
7116 + {
7117 + for (size_t u = 0; u < s1.length; u++)
7118 + { Object o1 = s1[u];
7119 + Object o2 = s2[u];
7120 +
7121 + if (o1 is o2)
7122 + continue;
7123 +
7124 + // Regard null references as always being "less than"
7125 + if (o1)
7126 + {
7127 + if (!o2)
7128 + { c = 1;
7129 + break;
7130 + }
7131 + c = o1.opCmp(o2);
7132 + if (c)
7133 + break;
7134 + }
7135 + else
7136 + { c = -1;
7137 + break;
7138 + }
7139 + }
7140 + }
7141 + if (c < 0)
7142 + c = -1;
7143 + else if (c > 0)
7144 + c = 1;
7145 + return c;
7146 + }
7147 +
7148 + override size_t tsize()
7149 + {
7150 + return (Object[]).sizeof;
7151 + }
7152 +
7153 + override uint flags()
7154 + {
7155 + return 1;
7156 + }
7157 +
7158 + override TypeInfo next()
7159 + {
7160 + return typeid(Object);
7161 + }
7162 +}
7163 Index: src/compiler/ldc/typeinfo/ti_ulong.d
7164 ===================================================================
7165 --- src/compiler/ldc/typeinfo/ti_ulong.d (revision 0)
7166 +++ src/compiler/ldc/typeinfo/ti_ulong.d (revision 0)
7167 @@ -0,0 +1,42 @@
7168 +
7169 +// ulong
7170 +
7171 +module rt.typeinfo.ti_ulong;
7172 +
7173 +class TypeInfo_m : TypeInfo
7174 +{
7175 + override string toString() { return "ulong"; }
7176 +
7177 + override hash_t getHash(in void* p)
7178 + {
7179 + return *cast(uint *)p + (cast(uint *)p)[1];
7180 + }
7181 +
7182 + override equals_t equals(in void* p1, in void* p2)
7183 + {
7184 + return *cast(ulong *)p1 == *cast(ulong *)p2;
7185 + }
7186 +
7187 + override int compare(in void* p1, in void* p2)
7188 + {
7189 + if (*cast(ulong *)p1 < *cast(ulong *)p2)
7190 + return -1;
7191 + else if (*cast(ulong *)p1 > *cast(ulong *)p2)
7192 + return 1;
7193 + return 0;
7194 + }
7195 +
7196 + override size_t tsize()
7197 + {
7198 + return ulong.sizeof;
7199 + }
7200 +
7201 + override void swap(void *p1, void *p2)
7202 + {
7203 + ulong t;
7204 +
7205 + t = *cast(ulong *)p1;
7206 + *cast(ulong *)p1 = *cast(ulong *)p2;
7207 + *cast(ulong *)p2 = t;
7208 + }
7209 +}
7210 Index: src/compiler/ldc/typeinfo/ti_creal.d
7211 ===================================================================
7212 --- src/compiler/ldc/typeinfo/ti_creal.d (revision 0)
7213 +++ src/compiler/ldc/typeinfo/ti_creal.d (revision 0)
7214 @@ -0,0 +1,67 @@
7215 +
7216 +// creal
7217 +
7218 +module rt.typeinfo.ti_creal;
7219 +
7220 +class TypeInfo_c : TypeInfo
7221 +{
7222 + override string toString() { return "creal"; }
7223 +
7224 + override hash_t getHash(in void* p)
7225 + {
7226 + return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
7227 + (cast(uint *)p)[2] + (cast(uint *)p)[3] +
7228 + (cast(uint *)p)[4];
7229 + }
7230 +
7231 + static equals_t _equals(creal f1, creal f2)
7232 + {
7233 + return f1 == f2;
7234 + }
7235 +
7236 + static int _compare(creal f1, creal f2)
7237 + { int result;
7238 +
7239 + if (f1.re < f2.re)
7240 + result = -1;
7241 + else if (f1.re > f2.re)
7242 + result = 1;
7243 + else if (f1.im < f2.im)
7244 + result = -1;
7245 + else if (f1.im > f2.im)
7246 + result = 1;
7247 + else
7248 + result = 0;
7249 + return result;
7250 + }
7251 +
7252 + override equals_t equals(in void* p1, in void* p2)
7253 + {
7254 + return _equals(*cast(creal *)p1, *cast(creal *)p2);
7255 + }
7256 +
7257 + override int compare(in void* p1, in void* p2)
7258 + {
7259 + return _compare(*cast(creal *)p1, *cast(creal *)p2);
7260 + }
7261 +
7262 + override size_t tsize()
7263 + {
7264 + return creal.sizeof;
7265 + }
7266 +
7267 + override void swap(void *p1, void *p2)
7268 + {
7269 + creal t;
7270 +
7271 + t = *cast(creal *)p1;
7272 + *cast(creal *)p1 = *cast(creal *)p2;
7273 + *cast(creal *)p2 = t;
7274 + }
7275 +
7276 + override void[] init()
7277 + { static creal r;
7278 +
7279 + return (cast(creal *)&r)[0 .. 1];
7280 + }
7281 +}
7282 Index: src/compiler/ldc/typeinfo/ti_ubyte.d
7283 ===================================================================
7284 --- src/compiler/ldc/typeinfo/ti_ubyte.d (revision 0)
7285 +++ src/compiler/ldc/typeinfo/ti_ubyte.d (revision 0)
7286 @@ -0,0 +1,43 @@
7287 +
7288 +// ubyte
7289 +
7290 +module rt.typeinfo.ti_ubyte;
7291 +
7292 +class TypeInfo_h : TypeInfo
7293 +{
7294 + override string toString() { return "ubyte"; }
7295 +
7296 + override hash_t getHash(in void* p)
7297 + {
7298 + return *cast(ubyte *)p;
7299 + }
7300 +
7301 + override equals_t equals(in void* p1, in void* p2)
7302 + {
7303 + return *cast(ubyte *)p1 == *cast(ubyte *)p2;
7304 + }
7305 +
7306 + override int compare(in void* p1, in void* p2)
7307 + {
7308 + return *cast(ubyte *)p1 - *cast(ubyte *)p2;
7309 + }
7310 +
7311 + override size_t tsize()
7312 + {
7313 + return ubyte.sizeof;
7314 + }
7315 +
7316 + override void swap(void *p1, void *p2)
7317 + {
7318 + ubyte t;
7319 +
7320 + t = *cast(ubyte *)p1;
7321 + *cast(ubyte *)p1 = *cast(ubyte *)p2;
7322 + *cast(ubyte *)p2 = t;
7323 + }
7324 +}
7325 +
7326 +class TypeInfo_b : TypeInfo_h
7327 +{
7328 + override string toString() { return "bool"; }
7329 +}
7330 Index: src/compiler/ldc/typeinfo/ti_Aint.d
7331 ===================================================================
7332 --- src/compiler/ldc/typeinfo/ti_Aint.d (revision 0)
7333 +++ src/compiler/ldc/typeinfo/ti_Aint.d (revision 0)
7334 @@ -0,0 +1,129 @@
7335 +
7336 +module rt.typeinfo.ti_Aint;
7337 +
7338 +private import core.stdc.string;
7339 +
7340 +// int[]
7341 +
7342 +class TypeInfo_Ai : TypeInfo
7343 +{
7344 + override string toString() { return "int[]"; }
7345 +
7346 + override hash_t getHash(in void* p)
7347 + { int[] s = *cast(int[]*)p;
7348 + auto len = s.length;
7349 + auto str = s.ptr;
7350 + hash_t hash = 0;
7351 +
7352 + while (len)
7353 + {
7354 + hash *= 9;
7355 + hash += *cast(uint *)str;
7356 + str++;
7357 + len--;
7358 + }
7359 +
7360 + return hash;
7361 + }
7362 +
7363 + override equals_t equals(in void* p1, in void* p2)
7364 + {
7365 + int[] s1 = *cast(int[]*)p1;
7366 + int[] s2 = *cast(int[]*)p2;
7367 +
7368 + return s1.length == s2.length &&
7369 + memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0;
7370 + }
7371 +
7372 + override int compare(in void* p1, in void* p2)
7373 + {
7374 + int[] s1 = *cast(int[]*)p1;
7375 + int[] s2 = *cast(int[]*)p2;
7376 + size_t len = s1.length;
7377 +
7378 + if (s2.length < len)
7379 + len = s2.length;
7380 + for (size_t u = 0; u < len; u++)
7381 + {
7382 + int result = s1[u] - s2[u];
7383 + if (result)
7384 + return result;
7385 + }
7386 + if (s1.length < s2.length)
7387 + return -1;
7388 + else if (s1.length > s2.length)
7389 + return 1;
7390 + return 0;
7391 + }
7392 +
7393 + override size_t tsize()
7394 + {
7395 + return (int[]).sizeof;
7396 + }
7397 +
7398 + override uint flags()
7399 + {
7400 + return 1;
7401 + }
7402 +
7403 + override TypeInfo next()
7404 + {
7405 + return typeid(int);
7406 + }
7407 +}
7408 +
7409 +unittest
7410 +{
7411 + int[][] a = [[5,3,8,7], [2,5,3,8,7]];
7412 + a.sort;
7413 + assert(a == [[2,5,3,8,7], [5,3,8,7]]);
7414 +
7415 + a = [[5,3,8,7], [5,3,8]];
7416 + a.sort;
7417 + assert(a == [[5,3,8], [5,3,8,7]]);
7418 +}
7419 +
7420 +// uint[]
7421 +
7422 +class TypeInfo_Ak : TypeInfo_Ai
7423 +{
7424 + override string toString() { return "uint[]"; }
7425 +
7426 + override int compare(in void* p1, in void* p2)
7427 + {
7428 + uint[] s1 = *cast(uint[]*)p1;
7429 + uint[] s2 = *cast(uint[]*)p2;
7430 + size_t len = s1.length;
7431 +
7432 + if (s2.length < len)
7433 + len = s2.length;
7434 + for (size_t u = 0; u < len; u++)
7435 + {
7436 + int result = s1[u] - s2[u];
7437 + if (result)
7438 + return result;
7439 + }
7440 + if (s1.length < s2.length)
7441 + return -1;
7442 + else if (s1.length > s2.length)
7443 + return 1;
7444 + return 0;
7445 + }
7446 +
7447 + override TypeInfo next()
7448 + {
7449 + return typeid(uint);
7450 + }
7451 +}
7452 +
7453 +// dchar[]
7454 +
7455 +class TypeInfo_Aw : TypeInfo_Ak
7456 +{
7457 + override string toString() { return "dchar[]"; }
7458 +
7459 + override TypeInfo next()
7460 + {
7461 + return typeid(dchar);
7462 + }
7463 +}
7464 Index: src/compiler/ldc/typeinfo/ti_ireal.d
7465 ===================================================================
7466 --- src/compiler/ldc/typeinfo/ti_ireal.d (revision 0)
7467 +++ src/compiler/ldc/typeinfo/ti_ireal.d (revision 0)
7468 @@ -0,0 +1,11 @@
7469 +
7470 +// ireal
7471 +
7472 +module rt.typeinfo.ti_ireal;
7473 +
7474 +private import typeinfo.ti_real;
7475 +
7476 +class TypeInfo_j : TypeInfo_e
7477 +{
7478 + override string toString() { return "ireal"; }
7479 +}
7480 Index: src/compiler/ldc/typeinfo/ti_long.d
7481 ===================================================================
7482 --- src/compiler/ldc/typeinfo/ti_long.d (revision 0)
7483 +++ src/compiler/ldc/typeinfo/ti_long.d (revision 0)
7484 @@ -0,0 +1,42 @@
7485 +
7486 +// long
7487 +
7488 +module rt.typeinfo.ti_long;
7489 +
7490 +class TypeInfo_l : TypeInfo
7491 +{
7492 + override string toString() { return "long"; }
7493 +
7494 + override hash_t getHash(in void* p)
7495 + {
7496 + return *cast(uint *)p + (cast(uint *)p)[1];
7497 + }
7498 +
7499 + override equals_t equals(in void* p1, in void* p2)
7500 + {
7501 + return *cast(long *)p1 == *cast(long *)p2;
7502 + }
7503 +
7504 + override int compare(in void* p1, in void* p2)
7505 + {
7506 + if (*cast(long *)p1 < *cast(long *)p2)
7507 + return -1;
7508 + else if (*cast(long *)p1 > *cast(long *)p2)
7509 + return 1;
7510 + return 0;
7511 + }
7512 +
7513 + override size_t tsize()
7514 + {
7515 + return long.sizeof;
7516 + }
7517 +
7518 + override void swap(void *p1, void *p2)
7519 + {
7520 + long t;
7521 +
7522 + t = *cast(long *)p1;
7523 + *cast(long *)p1 = *cast(long *)p2;
7524 + *cast(long *)p2 = t;
7525 + }
7526 +}
7527 Index: src/compiler/ldc/typeinfo/ti_short.d
7528 ===================================================================
7529 --- src/compiler/ldc/typeinfo/ti_short.d (revision 0)
7530 +++ src/compiler/ldc/typeinfo/ti_short.d (revision 0)
7531 @@ -0,0 +1,38 @@
7532 +
7533 +// short
7534 +
7535 +module rt.typeinfo.ti_short;
7536 +
7537 +class TypeInfo_s : TypeInfo
7538 +{
7539 + override string toString() { return "short"; }
7540 +
7541 + override hash_t getHash(in void* p)
7542 + {
7543 + return *cast(short *)p;
7544 + }
7545 +
7546 + override equals_t equals(in void* p1, in void* p2)
7547 + {
7548 + return *cast(short *)p1 == *cast(short *)p2;
7549 + }
7550 +
7551 + override int compare(in void* p1, in void* p2)
7552 + {
7553 + return *cast(short *)p1 - *cast(short *)p2;
7554 + }
7555 +
7556 + override size_t tsize()
7557 + {
7558 + return short.sizeof;
7559 + }
7560 +
7561 + override void swap(void *p1, void *p2)
7562 + {
7563 + short t;
7564 +
7565 + t = *cast(short *)p1;
7566 + *cast(short *)p1 = *cast(short *)p2;
7567 + *cast(short *)p2 = t;
7568 + }
7569 +}
7570 Index: src/compiler/ldc/typeinfo/ti_Along.d
7571 ===================================================================
7572 --- src/compiler/ldc/typeinfo/ti_Along.d (revision 0)
7573 +++ src/compiler/ldc/typeinfo/ti_Along.d (revision 0)
7574 @@ -0,0 +1,109 @@
7575 +
7576 +module rt.typeinfo.ti_Along;
7577 +
7578 +private import core.stdc.string;
7579 +
7580 +// long[]
7581 +
7582 +class TypeInfo_Al : TypeInfo
7583 +{
7584 + override string toString() { return "long[]"; }
7585 +
7586 + override hash_t getHash(in void* p)
7587 + { long[] s = *cast(long[]*)p;
7588 + size_t len = s.length;
7589 + auto str = s.ptr;
7590 + hash_t hash = 0;
7591 +
7592 + while (len)
7593 + {
7594 + hash *= 9;
7595 + hash += *cast(uint *)str + *(cast(uint *)str + 1);
7596 + str++;
7597 + len--;
7598 + }
7599 +
7600 + return hash;
7601 + }
7602 +
7603 + override equals_t equals(in void* p1, in void* p2)
7604 + {
7605 + long[] s1 = *cast(long[]*)p1;
7606 + long[] s2 = *cast(long[]*)p2;
7607 +
7608 + return s1.length == s2.length &&
7609 + memcmp(cast(void *)s1, cast(void *)s2, s1.length * long.sizeof) == 0;
7610 + }
7611 +
7612 + override int compare(in void* p1, in void* p2)
7613 + {
7614 + long[] s1 = *cast(long[]*)p1;
7615 + long[] s2 = *cast(long[]*)p2;
7616 + size_t len = s1.length;
7617 +
7618 + if (s2.length < len)
7619 + len = s2.length;
7620 + for (size_t u = 0; u < len; u++)
7621 + {
7622 + if (s1[u] < s2[u])
7623 + return -1;
7624 + else if (s1[u] > s2[u])
7625 + return 1;
7626 + }
7627 + if (s1.length < s2.length)
7628 + return -1;
7629 + else if (s1.length > s2.length)
7630 + return 1;
7631 + return 0;
7632 + }
7633 +
7634 + override size_t tsize()
7635 + {
7636 + return (long[]).sizeof;
7637 + }
7638 +
7639 + override uint flags()
7640 + {
7641 + return 1;
7642 + }
7643 +
7644 + override TypeInfo next()
7645 + {
7646 + return typeid(long);
7647 + }
7648 +}
7649 +
7650 +
7651 +// ulong[]
7652 +
7653 +class TypeInfo_Am : TypeInfo_Al
7654 +{
7655 + override string toString() { return "ulong[]"; }
7656 +
7657 + override int compare(in void* p1, in void* p2)
7658 + {
7659 + ulong[] s1 = *cast(ulong[]*)p1;
7660 + ulong[] s2 = *cast(ulong[]*)p2;
7661 + size_t len = s1.length;
7662 +
7663 + if (s2.length < len)
7664 + len = s2.length;
7665 + for (size_t u = 0; u < len; u++)
7666 + {
7667 + if (s1[u] < s2[u])
7668 + return -1;
7669 + else if (s1[u] > s2[u])
7670 + return 1;
7671 + }
7672 + if (s1.length < s2.length)
7673 + return -1;
7674 + else if (s1.length > s2.length)
7675 + return 1;
7676 + return 0;
7677 + }
7678 +
7679 + override TypeInfo next()
7680 + {
7681 + return typeid(ulong);
7682 + }
7683 +}
7684 Index: src/compiler/ldc/typeinfo/ti_byte.d
7685 ===================================================================
7686 --- src/compiler/ldc/typeinfo/ti_byte.d (revision 0)
7687 +++ src/compiler/ldc/typeinfo/ti_byte.d (revision 0)
7688 @@ -0,0 +1,38 @@
7689 +
7690 +// byte
7691 +
7692 +module rt.typeinfo.ti_byte;
7693 +
7694 +class TypeInfo_g : TypeInfo
7695 +{
7696 + override string toString() { return "byte"; }
7697 +
7698 + override hash_t getHash(in void* p)
7699 + {
7700 + return *cast(byte *)p;
7701 + }
7702 +
7703 + override equals_t equals(in void* p1, in void* p2)
7704 + {
7705 + return *cast(byte *)p1 == *cast(byte *)p2;
7706 + }
7707 +
7708 + override int compare(in void* p1, in void* p2)
7709 + {
7710 + return *cast(byte *)p1 - *cast(byte *)p2;
7711 + }
7712 +
7713 + override size_t tsize()
7714 + {
7715 + return byte.sizeof;
7716 + }
7717 +
7718 + override void swap(void *p1, void *p2)
7719 + {
7720 + byte t;
7721 +
7722 + t = *cast(byte *)p1;
7723 + *cast(byte *)p1 = *cast(byte *)p2;
7724 + *cast(byte *)p2 = t;
7725 + }
7726 +}
7727 Index: src/compiler/ldc/typeinfo/ti_float.d
7728 ===================================================================
7729 --- src/compiler/ldc/typeinfo/ti_float.d (revision 0)
7730 +++ src/compiler/ldc/typeinfo/ti_float.d (revision 0)
7731 @@ -0,0 +1,64 @@
7732 +
7733 +// float
7734 +
7735 +module rt.typeinfo.ti_float;
7736 +
7737 +class TypeInfo_f : TypeInfo
7738 +{
7739 + override string toString() { return "float"; }
7740 +
7741 + override hash_t getHash(in void* p)
7742 + {
7743 + return *cast(uint *)p;
7744 + }
7745 +
7746 + static equals_t _equals(float f1, float f2)
7747 + {
7748 + return f1 == f2 ||
7749 + (f1 !<>= f1 && f2 !<>= f2);
7750 + }
7751 +
7752 + static int _compare(float d1, float d2)
7753 + {
7754 + if (d1 !<>= d2) // if either are NaN
7755 + {
7756 + if (d1 !<>= d1)
7757 + { if (d2 !<>= d2)
7758 + return 0;
7759 + return -1;
7760 + }
7761 + return 1;
7762 + }
7763 + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
7764 + }
7765 +
7766 + override equals_t equals(in void* p1, in void* p2)
7767 + {
7768 + return _equals(*cast(float *)p1, *cast(float *)p2);
7769 + }
7770 +
7771 + override int compare(in void* p1, in void* p2)
7772 + {
7773 + return _compare(*cast(float *)p1, *cast(float *)p2);
7774 + }
7775 +
7776 + override size_t tsize()
7777 + {
7778 + return float.sizeof;
7779 + }
7780 +
7781 + override void swap(void *p1, void *p2)
7782 + {
7783 + float t;
7784 +
7785 + t = *cast(float *)p1;
7786 + *cast(float *)p1 = *cast(float *)p2;
7787 + *cast(float *)p2 = t;
7788 + }
7789 +
7790 + override void[] init()
7791 + { static float r;
7792 +
7793 + return (cast(float *)&r)[0 .. 1];
7794 + }
7795 +}
7796 Index: src/compiler/ldc/typeinfo/ti_cfloat.d
7797 ===================================================================
7798 --- src/compiler/ldc/typeinfo/ti_cfloat.d (revision 0)
7799 +++ src/compiler/ldc/typeinfo/ti_cfloat.d (revision 0)
7800 @@ -0,0 +1,65 @@
7801 +
7802 +// cfloat
7803 +
7804 +module rt.typeinfo.ti_cfloat;
7805 +
7806 +class TypeInfo_q : TypeInfo
7807 +{
7808 + override string toString() { return "cfloat"; }
7809 +
7810 + override hash_t getHash(in void* p)
7811 + {
7812 + return (cast(uint *)p)[0] + (cast(uint *)p)[1];
7813 + }
7814 +
7815 + static equals_t _equals(cfloat f1, cfloat f2)
7816 + {
7817 + return f1 == f2;
7818 + }
7819 +
7820 + static int _compare(cfloat f1, cfloat f2)
7821 + { int result;
7822 +
7823 + if (f1.re < f2.re)
7824 + result = -1;
7825 + else if (f1.re > f2.re)
7826 + result = 1;
7827 + else if (f1.im < f2.im)
7828 + result = -1;
7829 + else if (f1.im > f2.im)
7830 + result = 1;
7831 + else
7832 + result = 0;
7833 + return result;
7834 + }
7835 +
7836 + override equals_t equals(in void* p1, in void* p2)
7837 + {
7838 + return _equals(*cast(cfloat *)p1, *cast(cfloat *)p2);
7839 + }
7840 +
7841 + override int compare(in void* p1, in void* p2)
7842 + {
7843 + return _compare(*cast(cfloat *)p1, *cast(cfloat *)p2);
7844 + }
7845 +
7846 + override size_t tsize()
7847 + {
7848 + return cfloat.sizeof;
7849 + }
7850 +
7851 + override void swap(void *p1, void *p2)
7852 + {
7853 + cfloat t;
7854 +
7855 + t = *cast(cfloat *)p1;
7856 + *cast(cfloat *)p1 = *cast(cfloat *)p2;
7857 + *cast(cfloat *)p2 = t;
7858 + }
7859 +
7860 + override void[] init()
7861 + { static cfloat r;
7862 +
7863 + return (cast(cfloat *)&r)[0 .. 1];
7864 + }
7865 +}
7866 Index: src/compiler/ldc/typeinfo/ti_Acfloat.d
7867 ===================================================================
7868 --- src/compiler/ldc/typeinfo/ti_Acfloat.d (revision 0)
7869 +++ src/compiler/ldc/typeinfo/ti_Acfloat.d (revision 0)
7870 @@ -0,0 +1,103 @@
7871 +/*
7872 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
7873 + * Written by Walter Bright
7874 + *
7875 + * This software is provided 'as-is', without any express or implied
7876 + * warranty. In no event will the authors be held liable for any damages
7877 + * arising from the use of this software.
7878 + *
7879 + * Permission is granted to anyone to use this software for any purpose,
7880 + * including commercial applications, and to alter it and redistribute it
7881 + * freely, in both source and binary form, subject to the following
7882 + * restrictions:
7883 + *
7884 + * o The origin of this software must not be misrepresented; you must not
7885 + * claim that you wrote the original software. If you use this software
7886 + * in a product, an acknowledgment in the product documentation would be
7887 + * appreciated but is not required.
7888 + * o Altered source versions must be plainly marked as such, and must not
7889 + * be misrepresented as being the original software.
7890 + * o This notice may not be removed or altered from any source
7891 + * distribution.
7892 + */
7893 +
7894 +module rt.typeinfo.ti_Acfloat;
7895 +
7896 +private import typeinfo.ti_cfloat;
7897 +
7898 +// cfloat[]
7899 +
7900 +class TypeInfo_Aq : TypeInfo
7901 +{
7902 + override string toString() { return "cfloat[]"; }
7903 +
7904 + override hash_t getHash(in void* p)
7905 + { cfloat[] s = *cast(cfloat[]*)p;
7906 + size_t len = s.length;
7907 + cfloat *str = s.ptr;
7908 + hash_t hash = 0;
7909 +
7910 + while (len)
7911 + {
7912 + hash *= 9;
7913 + hash += (cast(uint *)str)[0];
7914 + hash += (cast(uint *)str)[1];
7915 + str++;
7916 + len--;
7917 + }
7918 +
7919 + return hash;
7920 + }
7921 +
7922 + override equals_t equals(in void* p1, in void* p2)
7923 + {
7924 + cfloat[] s1 = *cast(cfloat[]*)p1;
7925 + cfloat[] s2 = *cast(cfloat[]*)p2;
7926 + size_t len = s1.length;
7927 +
7928 + if (len != s2.length)
7929 + return false;
7930 + for (size_t u = 0; u < len; u++)
7931 + {
7932 + if (!TypeInfo_q._equals(s1[u], s2[u]))
7933 + return false;
7934 + }
7935 + return true;
7936 + }
7937 +
7938 + override int compare(in void* p1, in void* p2)
7939 + {
7940 + cfloat[] s1 = *cast(cfloat[]*)p1;
7941 + cfloat[] s2 = *cast(cfloat[]*)p2;
7942 + size_t len = s1.length;
7943 +
7944 + if (s2.length < len)
7945 + len = s2.length;
7946 + for (size_t u = 0; u < len; u++)
7947 + {
7948 + int c = TypeInfo_q._compare(s1[u], s2[u]);
7949 + if (c)
7950 + return c;
7951 + }
7952 + if (s1.length < s2.length)
7953 + return -1;
7954 + else if (s1.length > s2.length)
7955 + return 1;
7956 + return 0;
7957 + }
7958 +
7959 + override size_t tsize()
7960 + {
7961 + return (cfloat[]).sizeof;
7962 + }
7963 +
7964 + override uint flags()
7965 + {
7966 + return 1;
7967 + }
7968 +
7969 + override TypeInfo next()
7970 + {
7971 + return typeid(cfloat);
7972 + }
7973 +}
7974 Index: src/compiler/ldc/typeinfo/ti_cdouble.d
7975 ===================================================================
7976 --- src/compiler/ldc/typeinfo/ti_cdouble.d (revision 0)
7977 +++ src/compiler/ldc/typeinfo/ti_cdouble.d (revision 0)
7978 @@ -0,0 +1,66 @@
7979 +
7980 +// cdouble
7981 +
7982 +module rt.typeinfo.ti_cdouble;
7983 +
7984 +class TypeInfo_r : TypeInfo
7985 +{
7986 + override string toString() { return "cdouble"; }
7987 +
7988 + override hash_t getHash(in void* p)
7989 + {
7990 + return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
7991 + (cast(uint *)p)[2] + (cast(uint *)p)[3];
7992 + }
7993 +
7994 + static equals_t _equals(cdouble f1, cdouble f2)
7995 + {
7996 + return f1 == f2;
7997 + }
7998 +
7999 + static int _compare(cdouble f1, cdouble f2)
8000 + { int result;
8001 +
8002 + if (f1.re < f2.re)
8003 + result = -1;
8004 + else if (f1.re > f2.re)
8005 + result = 1;
8006 + else if (f1.im < f2.im)
8007 + result = -1;
8008 + else if (f1.im > f2.im)
8009 + result = 1;
8010 + else
8011 + result = 0;
8012 + return result;
8013 + }
8014 +
8015 + override equals_t equals(in void* p1, in void* p2)
8016 + {
8017 + return _equals(*cast(cdouble *)p1, *cast(cdouble *)p2);
8018 + }
8019 +
8020 + override int compare(in void* p1, in void* p2)
8021 + {
8022 + return _compare(*cast(cdouble *)p1, *cast(cdouble *)p2);
8023 + }
8024 +
8025 + override size_t tsize()
8026 + {
8027 + return cdouble.sizeof;
8028 + }
8029 +
8030 + override void swap(void *p1, void *p2)
8031 + {
8032 + cdouble t;
8033 +
8034 + t = *cast(cdouble *)p1;
8035 + *cast(cdouble *)p1 = *cast(cdouble *)p2;
8036 + *cast(cdouble *)p2 = t;
8037 + }
8038 +
8039 + override void[] init()
8040 + { static cdouble r;
8041 +
8042 + return (cast(cdouble *)&r)[0 .. 1];
8043 + }
8044 +}
8045 Index: src/compiler/ldc/typeinfo/ti_ifloat.d
8046 ===================================================================
8047 --- src/compiler/ldc/typeinfo/ti_ifloat.d (revision 0)
8048 +++ src/compiler/ldc/typeinfo/ti_ifloat.d (revision 0)
8049 @@ -0,0 +1,11 @@
8050 +
8051 +// ifloat
8052 +
8053 +module rt.typeinfo.ti_ifloat;
8054 +
8055 +private import typeinfo.ti_float;
8056 +
8057 +class TypeInfo_o : TypeInfo_f
8058 +{
8059 + override string toString() { return "ifloat"; }
8060 +}
8061 Index: src/compiler/ldc/typeinfo/ti_dchar.d
8062 ===================================================================
8063 --- src/compiler/ldc/typeinfo/ti_dchar.d (revision 0)
8064 +++ src/compiler/ldc/typeinfo/ti_dchar.d (revision 0)
8065 @@ -0,0 +1,44 @@
8066 +
8067 +// dchar
8068 +
8069 +module rt.typeinfo.ti_dchar;
8070 +
8071 +class TypeInfo_w : TypeInfo
8072 +{
8073 + override string toString() { return "dchar"; }
8074 +
8075 + override hash_t getHash(in void* p)
8076 + {
8077 + return *cast(dchar *)p;
8078 + }
8079 +
8080 + override equals_t equals(in void* p1, in void* p2)
8081 + {
8082 + return *cast(dchar *)p1 == *cast(dchar *)p2;
8083 + }
8084 +
8085 + override int compare(in void* p1, in void* p2)
8086 + {
8087 + return *cast(dchar *)p1 - *cast(dchar *)p2;
8088 + }
8089 +
8090 + override size_t tsize()
8091 + {
8092 + return dchar.sizeof;
8093 + }
8094 +
8095 + override void swap(void *p1, void *p2)
8096 + {
8097 + dchar t;
8098 +
8099 + t = *cast(dchar *)p1;
8100 + *cast(dchar *)p1 = *cast(dchar *)p2;
8101 + *cast(dchar *)p2 = t;
8102 + }
8103 +
8104 + override void[] init()
8105 + { static dchar c;
8106 +
8107 + return (cast(dchar *)&c)[0 .. 1];
8108 + }
8109 +}
8110 Index: src/compiler/ldc/typeinfo/ti_C.d
8111 ===================================================================
8112 --- src/compiler/ldc/typeinfo/ti_C.d (revision 0)
8113 +++ src/compiler/ldc/typeinfo/ti_C.d (revision 0)
8114 @@ -0,0 +1,74 @@
8115 +/*
8116 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
8117 + * Written by Walter Bright
8118 + *
8119 + * This software is provided 'as-is', without any express or implied
8120 + * warranty. In no event will the authors be held liable for any damages
8121 + * arising from the use of this software.
8122 + *
8123 + * Permission is granted to anyone to use this software for any purpose,
8124 + * including commercial applications, and to alter it and redistribute it
8125 + * freely, in both source and binary form, subject to the following
8126 + * restrictions:
8127 + *
8128 + * o The origin of this software must not be misrepresented; you must not
8129 + * claim that you wrote the original software. If you use this software
8130 + * in a product, an acknowledgment in the product documentation would be
8131 + * appreciated but is not required.
8132 + * o Altered source versions must be plainly marked as such, and must not
8133 + * be misrepresented as being the original software.
8134 + * o This notice may not be removed or altered from any source
8135 + * distribution.
8136 + */
8137 +
8138 +module rt.typeinfo.ti_C;
8139 +
8140 +// Object
8141 +
8142 +class TypeInfo_C : TypeInfo
8143 +{
8144 + override hash_t getHash(in void* p)
8145 + {
8146 + Object o = *cast(Object*)p;
8147 + return o ? o.toHash() : 0;
8148 + }
8149 +
8150 + override equals_t equals(in void* p1, in void* p2)
8151 + {
8152 + Object o1 = *cast(Object*)p1;
8153 + Object o2 = *cast(Object*)p2;
8154 +
8155 + return o1 == o2;
8156 + }
8157 +
8158 + override int compare(in void* p1, in void* p2)
8159 + {
8160 + Object o1 = *cast(Object*)p1;
8161 + Object o2 = *cast(Object*)p2;
8162 + int c = 0;
8163 +
8164 + // Regard null references as always being "less than"
8165 + if (!(o1 is o2))
8166 + {
8167 + if (o1)
8168 + { if (!o2)
8169 + c = 1;
8170 + else
8171 + c = o1.opCmp(o2);
8172 + }
8173 + else
8174 + c = -1;
8175 + }
8176 + return c;
8177 + }
8178 +
8179 + override size_t tsize()
8180 + {
8181 + return Object.sizeof;
8182 + }
8183 +
8184 + override uint flags()
8185 + {
8186 + return 1;
8187 + }
8188 +}
8189 Index: src/compiler/ldc/typeinfo/ti_real.d
8190 ===================================================================
8191 --- src/compiler/ldc/typeinfo/ti_real.d (revision 0)
8192 +++ src/compiler/ldc/typeinfo/ti_real.d (revision 0)
8193 @@ -0,0 +1,64 @@
8194 +
8195 +// real
8196 +
8197 +module rt.typeinfo.ti_real;
8198 +
8199 +class TypeInfo_e : TypeInfo
8200 +{
8201 + override string toString() { return "real"; }
8202 +
8203 + override hash_t getHash(in void* p)
8204 + {
8205 + return (cast(uint *)p)[0] + (cast(uint *)p)[1] + (cast(ushort *)p)[4];
8206 + }
8207 +
8208 + static equals_t _equals(real f1, real f2)
8209 + {
8210 + return f1 == f2 ||
8211 + (f1 !<>= f1 && f2 !<>= f2);
8212 + }
8213 +
8214 + static int _compare(real d1, real d2)
8215 + {
8216 + if (d1 !<>= d2) // if either are NaN
8217 + {
8218 + if (d1 !<>= d1)
8219 + { if (d2 !<>= d2)
8220 + return 0;
8221 + return -1;
8222 + }
8223 + return 1;
8224 + }
8225 + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
8226 + }
8227 +
8228 + override equals_t equals(in void* p1, in void* p2)
8229 + {
8230 + return _equals(*cast(real *)p1, *cast(real *)p2);
8231 + }
8232 +
8233 + override int compare(in void* p1, in void* p2)
8234 + {
8235 + return _compare(*cast(real *)p1, *cast(real *)p2);
8236 + }
8237 +
8238 + override size_t tsize()
8239 + {
8240 + return real.sizeof;
8241 + }
8242 +
8243 + override void swap(void *p1, void *p2)
8244 + {
8245 + real t;
8246 +
8247 + t = *cast(real *)p1;
8248 + *cast(real *)p1 = *cast(real *)p2;
8249 + *cast(real *)p2 = t;
8250 + }
8251 +
8252 + override void[] init()
8253 + { static real r;
8254 +
8255 + return (cast(real *)&r)[0 .. 1];
8256 + }
8257 +}
8258 Index: src/compiler/ldc/typeinfo/ti_idouble.d
8259 ===================================================================
8260 --- src/compiler/ldc/typeinfo/ti_idouble.d (revision 0)
8261 +++ src/compiler/ldc/typeinfo/ti_idouble.d (revision 0)
8262 @@ -0,0 +1,11 @@
8263 +
8264 +// idouble
8265 +
8266 +module rt.typeinfo.ti_idouble;
8267 +
8268 +private import typeinfo.ti_double;
8269 +
8270 +class TypeInfo_p : TypeInfo_d
8271 +{
8272 + override string toString() { return "idouble"; }
8273 +}
8274 Index: src/compiler/ldc/typeinfo/ti_Areal.d
8275 ===================================================================
8276 --- src/compiler/ldc/typeinfo/ti_Areal.d (revision 0)
8277 +++ src/compiler/ldc/typeinfo/ti_Areal.d (revision 0)
8278 @@ -0,0 +1,116 @@
8279 +/*
8280 + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
8281 + * Written by Walter Bright
8282 + *
8283 + * This software is provided 'as-is', without any express or implied
8284 + * warranty. In no event will the authors be held liable for any damages
8285 + * arising from the use of this software.
8286 + *
8287 + * Permission is granted to anyone to use this software for any purpose,
8288 + * including commercial applications, and to alter it and redistribute it
8289 + * freely, in both source and binary form, subject to the following
8290 + * restrictions:
8291 + *
8292 + * o The origin of this software must not be misrepresented; you must not
8293 + * claim that you wrote the original software. If you use this software
8294 + * in a product, an acknowledgment in the product documentation would be
8295 + * appreciated but is not required.
8296 + * o Altered source versions must be plainly marked as such, and must not
8297 + * be misrepresented as being the original software.
8298 + * o This notice may not be removed or altered from any source
8299 + * distribution.
8300 + */
8301 +
8302 +module rt.typeinfo.ti_Areal;
8303 +
8304 +private import typeinfo.ti_real;
8305 +
8306 +// real[]
8307 +
8308 +class TypeInfo_Ae : TypeInfo
8309 +{
8310 + override string toString() { return "real[]"; }
8311 +
8312 + override hash_t getHash(in void* p)
8313 + { real[] s = *cast(real[]*)p;
8314 + size_t len = s.length;
8315 + auto str = s.ptr;
8316 + hash_t hash = 0;
8317 +
8318 + while (len)
8319 + {
8320 + hash *= 9;
8321 + hash += (cast(uint *)str)[0];
8322 + hash += (cast(uint *)str)[1];
8323 + hash += (cast(ushort *)str)[4];
8324 + str++;
8325 + len--;
8326 + }
8327 +
8328 + return hash;
8329 + }
8330 +
8331 + override equals_t equals(in void* p1, in void* p2)
8332 + {
8333 + real[] s1 = *cast(real[]*)p1;
8334 + real[] s2 = *cast(real[]*)p2;
8335 + size_t len = s1.length;
8336 +
8337 + if (len != s2.length)
8338 + return false;
8339 + for (size_t u = 0; u < len; u++)
8340 + {
8341 + if (!TypeInfo_e._equals(s1[u], s2[u]))
8342 + return false;
8343 + }
8344 + return true;
8345 + }
8346 +
8347 + override int compare(in void* p1, in void* p2)
8348 + {
8349 + real[] s1 = *cast(real[]*)p1;
8350 + real[] s2 = *cast(real[]*)p2;
8351 + size_t len = s1.length;
8352 +
8353 + if (s2.length < len)
8354 + len = s2.length;
8355 + for (size_t u = 0; u < len; u++)
8356 + {
8357 + int c = TypeInfo_e._compare(s1[u], s2[u]);
8358 + if (c)
8359 + return c;
8360 + }
8361 + if (s1.length < s2.length)
8362 + return -1;
8363 + else if (s1.length > s2.length)
8364 + return 1;
8365 + return 0;
8366 + }
8367 +
8368 + override size_t tsize()
8369 + {
8370 + return (real[]).sizeof;
8371 + }
8372 +
8373 + override uint flags()
8374 + {
8375 + return 1;
8376 + }
8377 +
8378 + override TypeInfo next()
8379 + {
8380 + return typeid(real);
8381 + }
8382 +}
8383 +
8384 +// ireal[]
8385 +
8386 +class TypeInfo_Aj : TypeInfo_Ae
8387 +{
8388 + override string toString() { return "ireal[]"; }
8389 +
8390 + override TypeInfo next()
8391 + {
8392 + return typeid(ireal);
8393 + }
8394 +}
8395 Index: src/compiler/ldc/typeinfo/ti_ushort.d
8396 ===================================================================
8397 --- src/compiler/ldc/typeinfo/ti_ushort.d (revision 0)
8398 +++ src/compiler/ldc/typeinfo/ti_ushort.d (revision 0)
8399 @@ -0,0 +1,38 @@
8400 +
8401 +// ushort
8402 +
8403 +module rt.typeinfo.ti_ushort;
8404 +
8405 +class TypeInfo_t : TypeInfo
8406 +{
8407 + override string toString() { return "ushort"; }
8408 +
8409 + override hash_t getHash(in void* p)
8410 + {
8411 + return *cast(ushort *)p;
8412 + }
8413 +
8414 + override equals_t equals(in void* p1, in void* p2)
8415 + {
8416 + return *cast(ushort *)p1 == *cast(ushort *)p2;
8417 + }
8418 +
8419 + override int compare(in void* p1, in void* p2)
8420 + {
8421 + return *cast(ushort *)p1 - *cast(ushort *)p2;
8422 + }
8423 +
8424 + override size_t tsize()
8425 + {
8426 + return ushort.sizeof;
8427 + }
8428 +
8429 + override void swap(void *p1, void *p2)
8430 + {
8431 + ushort t;
8432 +
8433 + t = *cast(ushort *)p1;
8434 + *cast(ushort *)p1 = *cast(ushort *)p2;
8435 + *cast(ushort *)p2 = t;
8436 + }
8437 +}
8438 Index: src/compiler/ldc/typeinfo/ti_Ag.d
8439 ===================================================================
8440 --- src/compiler/ldc/typeinfo/ti_Ag.d (revision 0)
8441 +++ src/compiler/ldc/typeinfo/ti_Ag.d (revision 0)
8442 @@ -0,0 +1,204 @@
8443 +
8444 +module rt.typeinfo.ti_Ag;
8445 +
8446 +private import util.string;
8447 +private import core.stdc.string;
8448 +
8449 +// byte[]
8450 +
8451 +class TypeInfo_Ag : TypeInfo
8452 +{
8453 + override string toString() { return "byte[]"; }
8454 +
8455 + override hash_t getHash(in void* p)
8456 + { byte[] s = *cast(byte[]*)p;
8457 + size_t len = s.length;
8458 + byte *str = s.ptr;
8459 + hash_t hash = 0;
8460 +
8461 + while (1)
8462 + {
8463 + switch (len)
8464 + {
8465 + case 0:
8466 + return hash;
8467 +
8468 + case 1:
8469 + hash *= 9;
8470 + hash += *cast(ubyte *)str;
8471 + return hash;
8472 +
8473 + case 2:
8474 + hash *= 9;
8475 + hash += *cast(ushort *)str;
8476 + return hash;
8477 +
8478 + case 3:
8479 + hash *= 9;
8480 + hash += (*cast(ushort *)str << 8) +
8481 + (cast(ubyte *)str)[2];
8482 + return hash;
8483 +
8484 + default:
8485 + hash *= 9;
8486 + hash += *cast(uint *)str;
8487 + str += 4;
8488 + len -= 4;
8489 + break;
8490 + }
8491 + }
8492 +
8493 + return hash;
8494 + }
8495 +
8496 + override equals_t equals(in void* p1, in void* p2)
8497 + {
8498 + byte[] s1 = *cast(byte[]*)p1;
8499 + byte[] s2 = *cast(byte[]*)p2;
8500 +
8501 + return s1.length == s2.length &&
8502 + memcmp(cast(byte *)s1, cast(byte *)s2, s1.length) == 0;
8503 + }
8504 +
8505 + override int compare(in void* p1, in void* p2)
8506 + {
8507 + byte[] s1 = *cast(byte[]*)p1;
8508 + byte[] s2 = *cast(byte[]*)p2;
8509 + size_t len = s1.length;
8510 +
8511 + if (s2.length < len)
8512 + len = s2.length;
8513 + for (size_t u = 0; u < len; u++)
8514 + {
8515 + int result = s1[u] - s2[u];
8516 + if (result)
8517 + return result;
8518 + }
8519 + if (s1.length < s2.length)
8520 + return -1;
8521 + else if (s1.length > s2.length)
8522 + return 1;
8523 + return 0;
8524 + }
8525 +
8526 + override size_t tsize()
8527 + {
8528 + return (byte[]).sizeof;
8529 + }
8530 +
8531 + override uint flags()
8532 + {
8533 + return 1;
8534 + }
8535 +
8536 + override TypeInfo next()
8537 + {
8538 + return typeid(byte);
8539 + }
8540 +}
8541 +
8542 +
8543 +// ubyte[]
8544 +
8545 +class TypeInfo_Ah : TypeInfo_Ag
8546 +{
8547 + override string toString() { return "ubyte[]"; }
8548 +
8549 + override int compare(in void* p1, in void* p2)
8550 + {
8551 + char[] s1 = *cast(char[]*)p1;
8552 + char[] s2 = *cast(char[]*)p2;
8553 +
8554 + return dstrcmp(s1, s2);
8555 + }
8556 +
8557 + override TypeInfo next()
8558 + {
8559 + return typeid(ubyte);
8560 + }
8561 +}
8562 +
8563 +// void[]
8564 +
8565 +class TypeInfo_Av : TypeInfo_Ah
8566 +{
8567 + override string toString() { return "void[]"; }
8568 +
8569 + override TypeInfo next()
8570 + {
8571 + return typeid(void);
8572 + }
8573 +}
8574 +
8575 +// bool[]
8576 +
8577 +class TypeInfo_Ab : TypeInfo_Ah
8578 +{
8579 + override string toString() { return "bool[]"; }
8580 +
8581 + override TypeInfo next()
8582 + {
8583 + return typeid(bool);
8584 + }
8585 +}
8586 +
8587 +// char[]
8588 +
8589 +class TypeInfo_Aa : TypeInfo_Ag
8590 +{
8591 + override string toString() { return "char[]"; }
8592 +
8593 + override hash_t getHash(in void* p)
8594 + { char[] s = *cast(char[]*)p;
8595 + hash_t hash = 0;
8596 +
8597 +version (all)
8598 +{
8599 + foreach (char c; s)
8600 + hash = hash * 11 + c;
8601 +}
8602 +else
8603 +{
8604 + size_t len = s.length;
8605 + char *str = s;
8606 +
8607 + while (1)
8608 + {
8609 + switch (len)
8610 + {
8611 + case 0:
8612 + return hash;
8613 +
8614 + case 1:
8615 + hash *= 9;
8616 + hash += *cast(ubyte *)str;
8617 + return hash;
8618 +
8619 + case 2:
8620 + hash *= 9;
8621 + hash += *cast(ushort *)str;
8622 + return hash;
8623 +
8624 + case 3:
8625 + hash *= 9;
8626 + hash += (*cast(ushort *)str << 8) +
8627 + (cast(ubyte *)str)[2];
8628 + return hash;
8629 +
8630 + default:
8631 + hash *= 9;
8632 + hash += *cast(uint *)str;
8633 + str += 4;
8634 + len -= 4;
8635 + break;
8636 + }
8637 + }
8638 +}
8639 + return hash;
8640 + }
8641 +
8642 + override TypeInfo next()
8643 + {
8644 + return typeid(char);
8645 + }
8646 +}
8647 Index: src/compiler/ldc/typeinfo/ti_Acreal.d
8648 ===================================================================
8649 --- src/compiler/ldc/typeinfo/ti_Acreal.d (revision 0)
8650 +++ src/compiler/ldc/typeinfo/ti_Acreal.d (revision 0)
8651 @@ -0,0 +1,106 @@
8652 +/*
8653 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
8654 + * Written by Walter Bright
8655 + *
8656 + * This software is provided 'as-is', without any express or implied
8657 + * warranty. In no event will the authors be held liable for any damages
8658 + * arising from the use of this software.
8659 + *
8660 + * Permission is granted to anyone to use this software for any purpose,
8661 + * including commercial applications, and to alter it and redistribute it
8662 + * freely, in both source and binary form, subject to the following
8663 + * restrictions:
8664 + *
8665 + * o The origin of this software must not be misrepresented; you must not
8666 + * claim that you wrote the original software. If you use this software
8667 + * in a product, an acknowledgment in the product documentation would be
8668 + * appreciated but is not required.
8669 + * o Altered source versions must be plainly marked as such, and must not
8670 + * be misrepresented as being the original software.
8671 + * o This notice may not be removed or altered from any source
8672 + * distribution.
8673 + */
8674 +
8675 +module rt.typeinfo.ti_Acreal;
8676 +
8677 +private import typeinfo.ti_creal;
8678 +
8679 +// creal[]
8680 +
8681 +class TypeInfo_Ac : TypeInfo
8682 +{
8683 + override string toString() { return "creal[]"; }
8684 +
8685 + override hash_t getHash(in void* p)
8686 + { creal[] s = *cast(creal[]*)p;
8687 + size_t len = s.length;
8688 + creal *str = s.ptr;
8689 + hash_t hash = 0;
8690 +
8691 + while (len)
8692 + {
8693 + hash *= 9;
8694 + hash += (cast(uint *)str)[0];
8695 + hash += (cast(uint *)str)[1];
8696 + hash += (cast(uint *)str)[2];
8697 + hash += (cast(uint *)str)[3];
8698 + hash += (cast(uint *)str)[4];
8699 + str++;
8700 + len--;
8701 + }
8702 +
8703 + return hash;
8704 + }
8705 +
8706 + override equals_t equals(in void* p1, in void* p2)
8707 + {
8708 + creal[] s1 = *cast(creal[]*)p1;
8709 + creal[] s2 = *cast(creal[]*)p2;
8710 + size_t len = s1.length;
8711 +
8712 + if (len != s2.length)
8713 + return 0;
8714 + for (size_t u = 0; u < len; u++)
8715 + {
8716 + if (!TypeInfo_c._equals(s1[u], s2[u]))
8717 + return false;
8718 + }
8719 + return true;
8720 + }
8721 +
8722 + override int compare(in void* p1, in void* p2)
8723 + {
8724 + creal[] s1 = *cast(creal[]*)p1;
8725 + creal[] s2 = *cast(creal[]*)p2;
8726 + size_t len = s1.length;
8727 +
8728 + if (s2.length < len)
8729 + len = s2.length;
8730 + for (size_t u = 0; u < len; u++)
8731 + {
8732 + int c = TypeInfo_c._compare(s1[u], s2[u]);
8733 + if (c)
8734 + return c;
8735 + }
8736 + if (s1.length < s2.length)
8737 + return -1;
8738 + else if (s1.length > s2.length)
8739 + return 1;
8740 + return 0;
8741 + }
8742 +
8743 + override size_t tsize()
8744 + {
8745 + return (creal[]).sizeof;
8746 + }
8747 +
8748 + override uint flags()
8749 + {
8750 + return 1;
8751 + }
8752 +
8753 + override TypeInfo next()
8754 + {
8755 + return typeid(creal);
8756 + }
8757 +}
8758 Index: src/compiler/ldc/typeinfo/ti_int.d
8759 ===================================================================
8760 --- src/compiler/ldc/typeinfo/ti_int.d (revision 0)
8761 +++ src/compiler/ldc/typeinfo/ti_int.d (revision 0)
8762 @@ -0,0 +1,42 @@
8763 +
8764 +// int
8765 +
8766 +module rt.typeinfo.ti_int;
8767 +
8768 +class TypeInfo_i : TypeInfo
8769 +{
8770 + override string toString() { return "int"; }
8771 +
8772 + override hash_t getHash(in void* p)
8773 + {
8774 + return *cast(uint *)p;
8775 + }
8776 +
8777 + override equals_t equals(in void* p1, in void* p2)
8778 + {
8779 + return *cast(uint *)p1 == *cast(uint *)p2;
8780 + }
8781 +
8782 + override int compare(in void* p1, in void* p2)
8783 + {
8784 + if (*cast(int*) p1 < *cast(int*) p2)
8785 + return -1;
8786 + else if (*cast(int*) p1 > *cast(int*) p2)
8787 + return 1;
8788 + return 0;
8789 + }
8790 +
8791 + override size_t tsize()
8792 + {
8793 + return int.sizeof;
8794 + }
8795 +
8796 + override void swap(void *p1, void *p2)
8797 + {
8798 + int t;
8799 +
8800 + t = *cast(int *)p1;
8801 + *cast(int *)p1 = *cast(int *)p2;
8802 + *cast(int *)p2 = t;
8803 + }
8804 +}
8805 Index: src/compiler/ldc/typeinfo/ti_Ashort.d
8806 ===================================================================
8807 --- src/compiler/ldc/typeinfo/ti_Ashort.d (revision 0)
8808 +++ src/compiler/ldc/typeinfo/ti_Ashort.d (revision 0)
8809 @@ -0,0 +1,132 @@
8810 +
8811 +module rt.typeinfo.ti_Ashort;
8812 +
8813 +private import core.stdc.string;
8814 +
8815 +// short[]
8816 +
8817 +class TypeInfo_As : TypeInfo
8818 +{
8819 + override string toString() { return "short[]"; }
8820 +
8821 + override hash_t getHash(in void* p)
8822 + { short[] s = *cast(short[]*)p;
8823 + size_t len = s.length;
8824 + short *str = s.ptr;
8825 + hash_t hash = 0;
8826 +
8827 + while (1)
8828 + {
8829 + switch (len)
8830 + {
8831 + case 0:
8832 + return hash;
8833 +
8834 + case 1:
8835 + hash *= 9;
8836 + hash += *cast(ushort *)str;
8837 + return hash;
8838 +
8839 + default:
8840 + hash *= 9;
8841 + hash += *cast(uint *)str;
8842 + str += 2;
8843 + len -= 2;
8844 + break;
8845 + }
8846 + }
8847 +
8848 + return hash;
8849 + }
8850 +
8851 + override equals_t equals(in void* p1, in void* p2)
8852 + {
8853 + short[] s1 = *cast(short[]*)p1;
8854 + short[] s2 = *cast(short[]*)p2;
8855 +
8856 + return s1.length == s2.length &&
8857 + memcmp(cast(void *)s1, cast(void *)s2, s1.length * short.sizeof) == 0;
8858 + }
8859 +
8860 + override int compare(in void* p1, in void* p2)
8861 + {
8862 + short[] s1 = *cast(short[]*)p1;
8863 + short[] s2 = *cast(short[]*)p2;
8864 + size_t len = s1.length;
8865 +
8866 + if (s2.length < len)
8867 + len = s2.length;
8868 + for (size_t u = 0; u < len; u++)
8869 + {
8870 + int result = s1[u] - s2[u];
8871 + if (result)
8872 + return result;
8873 + }
8874 + if (s1.length < s2.length)
8875 + return -1;
8876 + else if (s1.length > s2.length)
8877 + return 1;
8878 + return 0;
8879 + }
8880 +
8881 + override size_t tsize()
8882 + {
8883 + return (short[]).sizeof;
8884 + }
8885 +
8886 + override uint flags()
8887 + {
8888 + return 1;
8889 + }
8890 +
8891 + override TypeInfo next()
8892 + {
8893 + return typeid(short);
8894 + }
8895 +}
8896 +
8897 +
8898 +// ushort[]
8899 +
8900 +class TypeInfo_At : TypeInfo_As
8901 +{
8902 + override string toString() { return "ushort[]"; }
8903 +
8904 + override int compare(in void* p1, in void* p2)
8905 + {
8906 + ushort[] s1 = *cast(ushort[]*)p1;
8907 + ushort[] s2 = *cast(ushort[]*)p2;
8908 + size_t len = s1.length;
8909 +
8910 + if (s2.length < len)
8911 + len = s2.length;
8912 + for (size_t u = 0; u < len; u++)
8913 + {
8914 + int result = s1[u] - s2[u];
8915 + if (result)
8916 + return result;
8917 + }
8918 + if (s1.length < s2.length)
8919 + return -1;
8920 + else if (s1.length > s2.length)
8921 + return 1;
8922 + return 0;
8923 + }
8924 +
8925 + override TypeInfo next()
8926 + {
8927 + return typeid(ushort);
8928 + }
8929 +}
8930 +
8931 +// wchar[]
8932 +
8933 +class TypeInfo_Au : TypeInfo_At
8934 +{
8935 + override string toString() { return "wchar[]"; }
8936 +
8937 + override TypeInfo next()
8938 + {
8939 + return typeid(wchar);
8940 + }
8941 +}
8942 Index: src/compiler/ldc/ldc/vararg.d
8943 ===================================================================
8944 --- src/compiler/ldc/ldc/vararg.d (revision 0)
8945 +++ src/compiler/ldc/ldc/vararg.d (revision 0)
8946 @@ -0,0 +1,43 @@
8947 +/*
8948 + * This module holds the implementation of special vararg templates for D style var args.
8949 + *
8950 + * Provides the functions tango.core.Vararg expects to be present!
8951 + */
8952 +
8953 +module ldc.Vararg;
8954 +
8955 +// Check for the right compiler
8956 +version(LDC)
8957 +{
8958 + // OK
8959 +}
8960 +else
8961 +{
8962 + static assert(false, "This module is only valid for LDC");
8963 +}
8964 +
8965 +alias void* va_list;
8966 +
8967 +void va_start(T) ( out va_list ap, inout T parmn )
8968 +{
8969 + // not needed !
8970 +}
8971 +
8972 +T va_arg(T)(ref va_list vp)
8973 +{
8974 + T* arg = cast(T*) vp;
8975 + // ldc always aligns to size_t.sizeof in vararg lists
8976 + vp = cast(va_list) ( cast(void*) vp + ( ( T.sizeof + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) ) );
8977 + return *arg;
8978 +}
8979 +
8980 +void va_end( va_list ap )
8981 +{
8982 + // not needed !
8983 +}
8984 +
8985 +void va_copy( out va_list dst, va_list src )
8986 +{
8987 + // seems pretty useless !
8988 + dst = src;
8989 +}
8990 Index: src/compiler/ldc/ldc/bitmanip.d
8991 ===================================================================
8992 --- src/compiler/ldc/ldc/bitmanip.d (revision 0)
8993 +++ src/compiler/ldc/ldc/bitmanip.d (revision 0)
8994 @@ -0,0 +1,81 @@
8995 +/*
8996 + * D phobos intrinsics for LDC
8997 + *
8998 + * From GDC ... public domain!
8999 + */
9000 +module ldc.bitmanip;
9001 +
9002 +// Check for the right compiler
9003 +version(LDC)
9004 +{
9005 + // OK
9006 +}
9007 +else
9008 +{
9009 + static assert(false, "This module is only valid for LDC");
9010 +}
9011 +
9012 +int bsf(uint v)
9013 +{
9014 + uint m = 1;
9015 + uint i;
9016 + for (i = 0; i < 32; i++,m<<=1) {
9017 + if (v&m)
9018 + return i;
9019 + }
9020 + return i; // supposed to be undefined
9021 +}
9022 +
9023 +int bsr(uint v)
9024 +{
9025 + uint m = 0x80000000;
9026 + uint i;
9027 + for (i = 32; i ; i--,m>>>=1) {
9028 + if (v&m)
9029 + return i-1;
9030 + }
9031 + return i; // supposed to be undefined
9032 +}
9033 +
9034 +int bt(uint *p, uint bitnum)
9035 +{
9036 + return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
9037 +}
9038 +
9039 +int btc(uint *p, uint bitnum)
9040 +{
9041 + uint * q = p + (bitnum / (uint.sizeof*8));
9042 + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
9043 + int result = *q & mask;
9044 + *q ^= mask;
9045 + return result ? -1 : 0;
9046 +}
9047 +
9048 +int btr(uint *p, uint bitnum)
9049 +{
9050 + uint * q = p + (bitnum / (uint.sizeof*8));
9051 + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
9052 + int result = *q & mask;
9053 + *q &= ~mask;
9054 + return result ? -1 : 0;
9055 +}
9056 +
9057 +int bts(uint *p, uint bitnum)
9058 +{
9059 + uint * q = p + (bitnum / (uint.sizeof*8));
9060 + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
9061 + int result = *q & mask;
9062 + *q |= mask;
9063 + return result ? -1 : 0;
9064 +}
9065 +
9066 +pragma(intrinsic, "llvm.bswap.i32")
9067 + uint bswap(uint val);
9068 +
9069 +ubyte inp(uint p) { throw new Exception("inp intrinsic not yet implemented"); }
9070 +ushort inpw(uint p) { throw new Exception("inpw intrinsic not yet implemented"); }
9071 +uint inpl(uint p) { throw new Exception("inpl intrinsic not yet implemented"); }
9072 +
9073 +ubyte outp(uint p, ubyte v) { throw new Exception("outp intrinsic not yet implemented"); }
9074 +ushort outpw(uint p, ushort v) { throw new Exception("outpw intrinsic not yet implemented"); }
9075 +uint outpl(uint p, uint v) { throw new Exception("outpl intrinsic not yet implemented"); }
9076 Index: src/compiler/ldc/aaA.d
9077 ===================================================================
9078 --- src/compiler/ldc/aaA.d (revision 0)
9079 +++ src/compiler/ldc/aaA.d (revision 0)
9080 @@ -0,0 +1,837 @@
9081 +//_ aaA.d
9082 +
9083 +/**
9084 + * Part of the D programming language runtime library.
9085 + * Implementation of associative arrays.
9086 + */
9087 +
9088 +/*
9089 + * Copyright (C) 2000-2008 by Digital Mars, www.digitalmars.com
9090 + * Written by Walter Bright
9091 + *
9092 + * This software is provided 'as-is', without any express or implied
9093 + * warranty. In no event will the authors be held liable for any damages
9094 + * arising from the use of this software.
9095 + *
9096 + * Permission is granted to anyone to use this software for any purpose,
9097 + * including commercial applications, and to alter it and redistribute it
9098 + * freely, subject to the following restrictions:
9099 + *
9100 + * o The origin of this software must not be misrepresented; you must not
9101 + * claim that you wrote the original software. If you use this software
9102 + * in a product, an acknowledgment in the product documentation would be
9103 + * appreciated but is not required.
9104 + * o Altered source versions must be plainly marked as such, and must not
9105 + * be misrepresented as being the original software.
9106 + * o This notice may not be removed or altered from any source
9107 + * distribution.
9108 + */
9109 +
9110 +/*
9111 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
9112 + * Modified by Tomas Lindquist Olsen <tomas@famolsen.dk> for use with LDC.
9113 + */
9114 +
9115 +private
9116 +{
9117 + version( D_Version2 )
9118 + {
9119 + import core.stdc.stdarg;
9120 + import core.stdc.string;
9121 + }
9122 + else
9123 + {
9124 + import tango.stdc.stdarg;
9125 + import tango.stdc.string;
9126 + }
9127 +
9128 + enum BlkAttr : uint
9129 + {
9130 + FINALIZE = 0b0000_0001,
9131 + NO_SCAN = 0b0000_0010,
9132 + NO_MOVE = 0b0000_0100,
9133 + ALL_BITS = 0b1111_1111
9134 + }
9135 +
9136 + extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
9137 + extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
9138 + extern (C) void gc_free( void* p );
9139 +}
9140 +
9141 +// Auto-rehash and pre-allocate - Dave Fladebo
9142 +
9143 +static size_t[] prime_list = [
9144 + 97UL, 389UL,
9145 + 1_543UL, 6_151UL,
9146 + 24_593UL, 98_317UL,
9147 + 393_241UL, 1_572_869UL,
9148 + 6_291_469UL, 25_165_843UL,
9149 + 100_663_319UL, 402_653_189UL,
9150 + 1_610_612_741UL, 4_294_967_291UL,
9151 +// 8_589_934_513UL, 17_179_869_143UL
9152 +];
9153 +
9154 +struct aaA
9155 +{
9156 + aaA *left;
9157 + aaA *right;
9158 + hash_t hash;
9159 + /* key */
9160 + /* value */
9161 +}
9162 +
9163 +struct BB
9164 +{
9165 + aaA*[] b;
9166 + size_t nodes; // total number of aaA nodes
9167 + TypeInfo keyti; // TODO: replace this with TypeInfo_AssociativeArray when available in _aaGet()
9168 +}
9169 +
9170 +/* This is the type actually seen by the programmer, although
9171 + * it is completely opaque.
9172 + */
9173 +
9174 +// LDC doesn't pass structs in registers so no need to wrap it ...
9175 +alias BB* AA;
9176 +
9177 +/**********************************
9178 + * Align to next pointer boundary, so that
9179 + * GC won't be faced with misaligned pointers
9180 + * in value.
9181 + */
9182 +
9183 +size_t aligntsize(size_t tsize)
9184 +{
9185 + return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
9186 +}
9187 +
9188 +extern (C):
9189 +
9190 +/*************************************************
9191 + * Invariant for aa.
9192 + */
9193 +
9194 +/+
9195 +void _aaInvAh(aaA*[] aa)
9196 +{
9197 + for (size_t i = 0; i < aa.length; i++)
9198 + {
9199 + if (aa[i])
9200 + _aaInvAh_x(aa[i]);
9201 + }
9202 +}
9203 +
9204 +private int _aaCmpAh_x(aaA *e1, aaA *e2)
9205 +{ int c;
9206 +
9207 + c = e1.hash - e2.hash;
9208 + if (c == 0)
9209 + {
9210 + c = e1.key.length - e2.key.length;
9211 + if (c == 0)
9212 + c = memcmp((char *)e1.key, (char *)e2.key, e1.key.length);
9213 + }
9214 + return c;
9215 +}
9216 +
9217 +private void _aaInvAh_x(aaA *e)
9218 +{
9219 + hash_t key_hash;
9220 + aaA *e1;
9221 + aaA *e2;
9222 +
9223 + key_hash = getHash(e.key);
9224 + assert(key_hash == e.hash);
9225 +
9226 + while (1)
9227 + { int c;
9228 +
9229 + e1 = e.left;
9230 + if (e1)
9231 + {
9232 + _aaInvAh_x(e1); // ordinary recursion
9233 + do
9234 + {
9235 + c = _aaCmpAh_x(e1, e);
9236 + assert(c < 0);
9237 + e1 = e1.right;
9238 + } while (e1 != null);
9239 + }
9240 +
9241 + e2 = e.right;
9242 + if (e2)
9243 + {
9244 + do
9245 + {
9246 + c = _aaCmpAh_x(e, e2);
9247 + assert(c < 0);
9248 + e2 = e2.left;
9249 + } while (e2 != null);
9250 + e = e.right; // tail recursion
9251 + }
9252 + else
9253 + break;
9254 + }
9255 +}
9256 ++/
9257 +
9258 +/****************************************************
9259 + * Determine number of entries in associative array.
9260 + */
9261 +
9262 +size_t _aaLen(AA aa)
9263 +in
9264 +{
9265 + //printf("_aaLen()+\n");
9266 + //_aaInv(aa);
9267 +}
9268 +out (result)
9269 +{
9270 + size_t len = 0;
9271 +
9272 + void _aaLen_x(aaA* ex)
9273 + {
9274 + auto e = ex;
9275 + len++;
9276 +
9277 + while (1)
9278 + {
9279 + if (e.right)
9280 + _aaLen_x(e.right);
9281 + e = e.left;
9282 + if (!e)
9283 + break;
9284 + len++;
9285 + }
9286 + }
9287 +
9288 + if (aa)
9289 + {
9290 + foreach (e; aa.b)
9291 + {
9292 + if (e)
9293 + _aaLen_x(e);
9294 + }
9295 + }
9296 + assert(len == result);
9297 +
9298 + //printf("_aaLen()-\n");
9299 +}
9300 +body
9301 +{
9302 + return aa ? aa.nodes : 0;
9303 +}
9304 +
9305 +
9306 +/*************************************************
9307 + * Get pointer to value in associative array indexed by key.
9308 + * Add entry for key if it is not already there.
9309 + */
9310 +
9311 +void* _aaGet(AA* aa_arg, TypeInfo keyti, size_t valuesize, void* pkey)
9312 +in
9313 +{
9314 + assert(aa_arg);
9315 +}
9316 +out (result)
9317 +{
9318 + assert(result);
9319 + assert(*aa_arg);
9320 + assert((*aa_arg).b.length);
9321 + //assert(_aaInAh(*aa, key));
9322 +}
9323 +body
9324 +{
9325 + //auto pkey = cast(void *)(&valuesize + 1);
9326 + size_t i;
9327 + aaA *e;
9328 + auto keysize = aligntsize(keyti.tsize());
9329 +
9330 + if (!*aa_arg)
9331 + *aa_arg = new BB();
9332 + auto aa = *aa_arg;
9333 + aa.keyti = keyti;
9334 +
9335 + if (!aa.b.length)
9336 + {
9337 + alias aaA *pa;
9338 + auto len = prime_list[0];
9339 +
9340 + aa.b = new pa[len];
9341 + }
9342 +
9343 + auto key_hash = keyti.getHash(pkey);
9344 + //printf("hash = %d\n", key_hash);
9345 + i = key_hash % aa.b.length;
9346 + auto pe = &aa.b[i];
9347 + while ((e = *pe) !is null)
9348 + {
9349 + if (key_hash == e.hash)
9350 + {
9351 + auto c = keyti.compare(pkey, e + 1);
9352 + if (c == 0)
9353 + goto Lret;
9354 + pe = (c < 0) ? &e.left : &e.right;
9355 + }
9356 + else
9357 + pe = (key_hash < e.hash) ? &e.left : &e.right;
9358 + }
9359 +
9360 + // Not found, create new elem
9361 + //printf("create new one\n");
9362 + size_t size = aaA.sizeof + keysize + valuesize;
9363 + e = cast(aaA *) gc_calloc(size);
9364 + memcpy(e + 1, pkey, keysize);
9365 + e.hash = key_hash;
9366 + *pe = e;
9367 +
9368 + auto nodes = ++aa.nodes;
9369 + //printf("length = %d, nodes = %d\n", (*aa).length, nodes);
9370 + if (nodes > aa.b.length * 4)
9371 + {
9372 + _aaRehash(aa_arg,keyti);
9373 + }
9374 +
9375 +Lret:
9376 + return cast(void *)(e + 1) + keysize;
9377 +}
9378 +
9379 +
9380 +/*************************************************
9381 + * Get pointer to value in associative array indexed by key.
9382 + * Returns null if it is not already there.
9383 + */
9384 +
9385 +void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void *pkey)
9386 +{
9387 + //printf("_aaGetRvalue(valuesize = %u)\n", valuesize);
9388 + if (!aa)
9389 + return null;
9390 +
9391 + //auto pkey = cast(void *)(&valuesize + 1);
9392 + auto keysize = aligntsize(keyti.tsize());
9393 + auto len = aa.b.length;
9394 +
9395 + if (len)
9396 + {
9397 + auto key_hash = keyti.getHash(pkey);
9398 + //printf("hash = %d\n", key_hash);
9399 + size_t i = key_hash % len;
9400 + auto e = aa.b[i];
9401 + while (e !is null)
9402 + {
9403 + if (key_hash == e.hash)
9404 + {
9405 + auto c = keyti.compare(pkey, e + 1);
9406 + if (c == 0)
9407 + return cast(void *)(e + 1) + keysize;
9408 + e = (c < 0) ? e.left : e.right;
9409 + }
9410 + else
9411 + e = (key_hash < e.hash) ? e.left : e.right;
9412 + }
9413 + }
9414 + return null; // not found, caller will throw exception
9415 +}
9416 +
9417 +
9418 +/*************************************************
9419 + * Determine if key is in aa.
9420 + * Returns:
9421 + * null not in aa
9422 + * !=null in aa, return pointer to value
9423 + */
9424 +
9425 +void* _aaIn(AA aa, TypeInfo keyti, void *pkey)
9426 +in
9427 +{
9428 +}
9429 +out (result)
9430 +{
9431 + //assert(result == 0 || result == 1);
9432 +}
9433 +body
9434 +{
9435 + if (aa)
9436 + {
9437 + //auto pkey = cast(void *)(&keyti + 1);
9438 +
9439 + //printf("_aaIn(), .length = %d, .ptr = %x\n", aa.length, cast(uint)aa.ptr);
9440 + auto len = aa.b.length;
9441 +
9442 + if (len)
9443 + {
9444 + auto key_hash = keyti.getHash(pkey);
9445 + //printf("hash = %d\n", key_hash);
9446 + size_t i = key_hash % len;
9447 + auto e = aa.b[i];
9448 + while (e !is null)
9449 + {
9450 + if (key_hash == e.hash)
9451 + {
9452 + auto c = keyti.compare(pkey, e + 1);
9453 + if (c == 0)
9454 + return cast(void *)(e + 1) + aligntsize(keyti.tsize());
9455 + e = (c < 0) ? e.left : e.right;
9456 + }
9457 + else
9458 + e = (key_hash < e.hash) ? e.left : e.right;
9459 + }
9460 + }
9461 + }
9462 +
9463 + // Not found
9464 + return null;
9465 +}
9466 +
9467 +/*************************************************
9468 + * Delete key entry in aa[].
9469 + * If key is not in aa[], do nothing.
9470 + */
9471 +
9472 +void _aaDel(AA aa, TypeInfo keyti, void *pkey)
9473 +{
9474 + //auto pkey = cast(void *)(&keyti + 1);
9475 + aaA *e;
9476 +
9477 + if (aa && aa.b.length)
9478 + {
9479 + auto key_hash = keyti.getHash(pkey);
9480 + //printf("hash = %d\n", key_hash);
9481 + size_t i = key_hash % aa.b.length;
9482 + auto pe = &aa.b[i];
9483 + while ((e = *pe) !is null) // null means not found
9484 + {
9485 + if (key_hash == e.hash)
9486 + {
9487 + auto c = keyti.compare(pkey, e + 1);
9488 + if (c == 0)
9489 + {
9490 + if (!e.left && !e.right)
9491 + {
9492 + *pe = null;
9493 + }
9494 + else if (e.left && !e.right)
9495 + {
9496 + *pe = e.left;
9497 + e.left = null;
9498 + }
9499 + else if (!e.left && e.right)
9500 + {
9501 + *pe = e.right;
9502 + e.right = null;
9503 + }
9504 + else
9505 + {
9506 + *pe = e.left;
9507 + e.left = null;
9508 + do
9509 + pe = &(*pe).right;
9510 + while (*pe);
9511 + *pe = e.right;
9512 + e.right = null;
9513 + }
9514 +
9515 + aa.nodes--;
9516 + gc_free(e);
9517 +
9518 + break;
9519 + }
9520 + pe = (c < 0) ? &e.left : &e.right;
9521 + }
9522 + else
9523 + pe = (key_hash < e.hash) ? &e.left : &e.right;
9524 + }
9525 + }
9526 +}
9527 +
9528 +
9529 +/********************************************
9530 + * Produce array of values from aa.
9531 + * The actual type is painted on the return value by the frontend
9532 + * This means the returned length should be the number of elements
9533 + */
9534 +
9535 +void[] _aaValues(AA aa, size_t keysize, size_t valuesize)
9536 +in
9537 +{
9538 + assert(keysize == aligntsize(keysize));
9539 +}
9540 +body
9541 +{
9542 + size_t resi;
9543 + void[] a;
9544 +
9545 + void _aaValues_x(aaA* e)
9546 + {
9547 + do
9548 + {
9549 + memcpy(a.ptr + resi * valuesize,
9550 + cast(byte*)e + aaA.sizeof + keysize,
9551 + valuesize);
9552 + resi++;
9553 + if (e.left)
9554 + { if (!e.right)
9555 + { e = e.left;
9556 + continue;
9557 + }
9558 + _aaValues_x(e.left);
9559 + }
9560 + e = e.right;
9561 + } while (e !is null);
9562 + }
9563 +
9564 + if (aa)
9565 + {
9566 + auto len = _aaLen(aa);
9567 + auto ptr = cast(byte*) gc_malloc(len * valuesize,
9568 + valuesize < (void*).sizeof ? BlkAttr.NO_SCAN : 0);
9569 + a = ptr[0 .. len];
9570 + resi = 0;
9571 + foreach (e; aa.b)
9572 + {
9573 + if (e)
9574 + _aaValues_x(e);
9575 + }
9576 + assert(resi == a.length);
9577 + }
9578 + return a;
9579 +}
9580 +
9581 +
9582 +/********************************************
9583 + * Rehash an array.
9584 + */
9585 +
9586 +void* _aaRehash(AA* paa, TypeInfo keyti)
9587 +in
9588 +{
9589 + //_aaInvAh(paa);
9590 +}
9591 +out (result)
9592 +{
9593 + //_aaInvAh(result);
9594 +}
9595 +body
9596 +{
9597 + BB newb;
9598 +
9599 + void _aaRehash_x(aaA* olde)
9600 + {
9601 + while (1)
9602 + {
9603 + auto left = olde.left;
9604 + auto right = olde.right;
9605 + olde.left = null;
9606 + olde.right = null;
9607 +
9608 + aaA *e;
9609 +
9610 + //printf("rehash %p\n", olde);
9611 + auto key_hash = olde.hash;
9612 + size_t i = key_hash % newb.b.length;
9613 + auto pe = &newb.b[i];
9614 + while ((e = *pe) !is null)
9615 + {
9616 + //printf("\te = %p, e.left = %p, e.right = %p\n", e, e.left, e.right);
9617 + assert(e.left != e);
9618 + assert(e.right != e);
9619 + if (key_hash == e.hash)
9620 + {
9621 + auto c = keyti.compare(olde + 1, e + 1);
9622 + assert(c != 0);
9623 + pe = (c < 0) ? &e.left : &e.right;
9624 + }
9625 + else
9626 + pe = (key_hash < e.hash) ? &e.left : &e.right;
9627 + }
9628 + *pe = olde;
9629 +
9630 + if (right)
9631 + {
9632 + if (!left)
9633 + { olde = right;
9634 + continue;
9635 + }
9636 + _aaRehash_x(right);
9637 + }
9638 + if (!left)
9639 + break;
9640 + olde = left;
9641 + }
9642 + }
9643 +
9644 + //printf("Rehash\n");
9645 + if (*paa)
9646 + {
9647 + auto aa = *paa;
9648 + auto len = _aaLen(aa);
9649 + if (len)
9650 + { size_t i;
9651 +
9652 + for (i = 0; i < prime_list.length - 1; i++)
9653 + {
9654 + if (len <= prime_list[i])
9655 + break;
9656 + }
9657 + len = prime_list[i];
9658 + newb.b = new aaA*[len];
9659 + newb.keyti = keyti;
9660 +
9661 + foreach (e; aa.b)
9662 + {
9663 + if (e)
9664 + _aaRehash_x(e);
9665 + }
9666 +
9667 + newb.nodes = (*aa).nodes;
9668 + }
9669 +
9670 + **paa = newb;
9671 + }
9672 + return *paa;
9673 +}
9674 +
9675 +
9676 +/********************************************
9677 + * Produce array of N byte keys from aa.
9678 + * The actual type is painted on the return value by the frontend
9679 + * This means the returned length should be the number of elements
9680 + */
9681 +
9682 +void[] _aaKeys(AA aa, size_t keysize)
9683 +{
9684 + byte[] res;
9685 + size_t resi;
9686 +
9687 + void _aaKeys_x(aaA* e)
9688 + {
9689 + do
9690 + {
9691 + memcpy(&res[resi * keysize], cast(byte*)(e + 1), keysize);
9692 + resi++;
9693 + if (e.left)
9694 + { if (!e.right)
9695 + { e = e.left;
9696 + continue;
9697 + }
9698 + _aaKeys_x(e.left);
9699 + }
9700 + e = e.right;
9701 + } while (e !is null);
9702 + }
9703 +
9704 + auto len = _aaLen(aa);
9705 + if (!len)
9706 + return null;
9707 + res = (cast(byte*) gc_malloc(len * keysize,
9708 + !(aa.keyti.flags() & 1) ? BlkAttr.NO_SCAN : 0)) [0 .. len * keysize];
9709 + resi = 0;
9710 + foreach (e; aa.b)
9711 + {
9712 + if (e)
9713 + _aaKeys_x(e);
9714 + }
9715 + assert(resi == len);
9716 +
9717 + return res.ptr[0 .. len];
9718 +}
9719 +
9720 +
9721 +/**********************************************
9722 + * 'apply' for associative arrays - to support foreach
9723 + */
9724 +
9725 +// dg is D, but _aaApply() is C
9726 +extern (D) typedef int delegate(void *) dg_t;
9727 +
9728 +int _aaApply(AA aa, size_t keysize, dg_t dg)
9729 +in
9730 +{
9731 + assert(aligntsize(keysize) == keysize);
9732 +}
9733 +body
9734 +{ int result;
9735 +
9736 + //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
9737 +
9738 + int treewalker(aaA* e)
9739 + { int result;
9740 +
9741 + do
9742 + {
9743 + //printf("treewalker(e = %p, dg = x%llx)\n", e, dg);
9744 + result = dg(cast(void *)(e + 1) + keysize);
9745 + if (result)
9746 + break;
9747 + if (e.right)
9748 + { if (!e.left)
9749 + {
9750 + e = e.right;
9751 + continue;
9752 + }
9753 + result = treewalker(e.right);
9754 + if (result)
9755 + break;
9756 + }
9757 + e = e.left;
9758 + } while (e);
9759 +
9760 + return result;
9761 + }
9762 +
9763 + if (aa)
9764 + {
9765 + foreach (e; aa.b)
9766 + {
9767 + if (e)
9768 + {
9769 + result = treewalker(e);
9770 + if (result)
9771 + break;
9772 + }
9773 + }
9774 + }
9775 + return result;
9776 +}
9777 +
9778 +// dg is D, but _aaApply2() is C
9779 +extern (D) typedef int delegate(void *, void *) dg2_t;
9780 +
9781 +int _aaApply2(AA aa, size_t keysize, dg2_t dg)
9782 +in
9783 +{
9784 + assert(aligntsize(keysize) == keysize);
9785 +}
9786 +body
9787 +{ int result;
9788 +
9789 + //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
9790 +
9791 + int treewalker(aaA* e)
9792 + { int result;
9793 +
9794 + do
9795 + {
9796 + //printf("treewalker(e = %p, dg = x%llx)\n", e, dg);
9797 + result = dg(cast(void *)(e + 1), cast(void *)(e + 1) + keysize);
9798 + if (result)
9799 + break;
9800 + if (e.right)
9801 + { if (!e.left)
9802 + {
9803 + e = e.right;
9804 + continue;
9805 + }
9806 + result = treewalker(e.right);
9807 + if (result)
9808 + break;
9809 + }
9810 + e = e.left;
9811 + } while (e);
9812 +
9813 + return result;
9814 + }
9815 +
9816 + if (aa)
9817 + {
9818 + foreach (e; aa.b)
9819 + {
9820 + if (e)
9821 + {
9822 + result = treewalker(e);
9823 + if (result)
9824 + break;
9825 + }
9826 + }
9827 + }
9828 + return result;
9829 +}
9830 +
9831 +
9832 +/***********************************
9833 + * Construct an associative array of type ti from
9834 + * length pairs of key/value pairs.
9835 + */
9836 +
9837 +/+
9838 +
9839 +extern (C)
9840 +BB* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
9841 +{
9842 + auto valuesize = ti.next.tsize(); // value size
9843 + auto keyti = ti.key;
9844 + auto keysize = keyti.tsize(); // key size
9845 + BB* result;
9846 +
9847 + //printf("_d_assocarrayliteralT(keysize = %d, valuesize = %d, length = %d)\n", keysize, valuesize, length);
9848 + //printf("tivalue = %.*s\n", ti.next.classinfo.name);
9849 + if (length == 0 || valuesize == 0 || keysize == 0)
9850 + {
9851 + ;
9852 + }
9853 + else
9854 + {
9855 + va_list q;
9856 + va_start!(size_t)(q, length);
9857 +
9858 + result = new BB();
9859 + size_t i;
9860 +
9861 + for (i = 0; i < prime_list.length - 1; i++)
9862 + {
9863 + if (length <= prime_list[i])
9864 + break;
9865 + }
9866 + auto len = prime_list[i];
9867 + result.b = new aaA*[len];
9868 +
9869 + size_t keystacksize = (keysize + int.sizeof - 1) & ~(int.sizeof - 1);
9870 + size_t valuestacksize = (valuesize + int.sizeof - 1) & ~(int.sizeof - 1);
9871 +
9872 + size_t keytsize = aligntsize(keysize);
9873 +
9874 + for (size_t j = 0; j < length; j++)
9875 + { void* pkey = q;
9876 + q += keystacksize;
9877 + void* pvalue = q;
9878 + q += valuestacksize;
9879 + aaA* e;
9880 +
9881 + auto key_hash = keyti.getHash(pkey);
9882 + //printf("hash = %d\n", key_hash);
9883 + i = key_hash % len;
9884 + auto pe = &result.b[i];
9885 + while (1)
9886 + {
9887 + e = *pe;
9888 + if (!e)
9889 + {
9890 + // Not found, create new elem
9891 + //printf("create new one\n");
9892 + e = cast(aaA *) cast(void*) new void[aaA.sizeof + keytsize + valuesize];
9893 + memcpy(e + 1, pkey, keysize);
9894 + e.hash = key_hash;
9895 + *pe = e;
9896 + result.nodes++;
9897 + break;
9898 + }
9899 + if (key_hash == e.hash)
9900 + {
9901 + auto c = keyti.compare(pkey, e + 1);
9902 + if (c == 0)
9903 + break;
9904 + pe = (c < 0) ? &e.left : &e.right;
9905 + }
9906 + else
9907 + pe = (key_hash < e.hash) ? &e.left : &e.right;
9908 + }
9909 + memcpy(cast(void *)(e + 1) + keytsize, pvalue, valuesize);
9910 + }
9911 +
9912 + va_end(q);
9913 + }
9914 + return result;
9915 +}
9916 +
9917 ++/
9918 Index: src/compiler/ldc/aApply.d
9919 ===================================================================
9920 --- src/compiler/ldc/aApply.d (revision 0)
9921 +++ src/compiler/ldc/aApply.d (revision 0)
9922 @@ -0,0 +1,414 @@
9923 +/**
9924 + * Part of the D programming language runtime library.
9925 + */
9926 +
9927 +/*
9928 + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
9929 + * Written by Walter Bright
9930 + *
9931 + * This software is provided 'as-is', without any express or implied
9932 + * warranty. In no event will the authors be held liable for any damages
9933 + * arising from the use of this software.
9934 + *
9935 + * Permission is granted to anyone to use this software for any purpose,
9936 + * including commercial applications, and to alter it and redistribute it
9937 + * freely, in both source and binary form, subject to the following
9938 + * restrictions:
9939 + *
9940 + * o The origin of this software must not be misrepresented; you must not
9941 + * claim that you wrote the original software. If you use this software
9942 + * in a product, an acknowledgment in the product documentation would be
9943 + * appreciated but is not required.
9944 + * o Altered source versions must be plainly marked as such, and must not
9945 + * be misrepresented as being the original software.
9946 + * o This notice may not be removed or altered from any source
9947 + * distribution.
9948 + */
9949 +
9950 +/*
9951 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
9952 + */
9953 +
9954 +/* This code handles decoding UTF strings for foreach loops.
9955 + * There are 6 combinations of conversions between char, wchar,
9956 + * and dchar, and 2 of each of those.
9957 + */
9958 +
9959 +private import util.utf;
9960 +
9961 +//debug = apply;
9962 +debug(apply)
9963 +{
9964 + extern(C) int printf(char*, ...);
9965 +}
9966 +
9967 +/**********************************************
9968 + */
9969 +
9970 +// dg is D, but _aApplycd() is C
9971 +extern (D) typedef int delegate(void *) dg_t;
9972 +
9973 +extern (C) int _aApplycd1(char[] aa, dg_t dg)
9974 +{ int result;
9975 + size_t i;
9976 + size_t len = aa.length;
9977 +
9978 + debug(apply) printf("_aApplycd1(), len = %d\n", len);
9979 + for (i = 0; i < len; )
9980 + { dchar d;
9981 +
9982 + d = aa[i];
9983 + if (d & 0x80)
9984 + d = decode(aa, i);
9985 + else
9986 + i++;
9987 + result = dg(cast(void *)&d);
9988 + if (result)
9989 + break;
9990 + }
9991 + return result;
9992 +}
9993 +
9994 +extern (C) int _aApplywd1(wchar[] aa, dg_t dg)
9995 +{ int result;
9996 + size_t i;
9997 + size_t len = aa.length;
9998 +
9999 + debug(apply) printf("_aApplywd1(), len = %d\n", len);
10000 + for (i = 0; i < len; )
10001 + { dchar d;
10002 +
10003 + d = aa[i];
10004 + if (d & ~0x7F)
10005 + d = decode(aa, i);
10006 + else
10007 + i++;
10008 + result = dg(cast(void *)&d);
10009 + if (result)
10010 + break;
10011 + }
10012 + return result;
10013 +}
10014 +
10015 +extern (C) int _aApplycw1(char[] aa, dg_t dg)
10016 +{ int result;
10017 + size_t i;
10018 + size_t len = aa.length;
10019 +
10020 + debug(apply) printf("_aApplycw1(), len = %d\n", len);
10021 + for (i = 0; i < len; )
10022 + { dchar d;
10023 + wchar w;
10024 +
10025 + w = aa[i];
10026 + if (w & 0x80)
10027 + { d = decode(aa, i);
10028 + if (d <= 0xFFFF)
10029 + w = cast(wchar) d;
10030 + else
10031 + {
10032 + w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
10033 + result = dg(cast(void *)&w);
10034 + if (result)
10035 + break;
10036 + w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
10037 + }
10038 + }
10039 + else
10040 + i++;
10041 + result = dg(cast(void *)&w);
10042 + if (result)
10043 + break;
10044 + }
10045 + return result;
10046 +}
10047 +
10048 +extern (C) int _aApplywc1(wchar[] aa, dg_t dg)
10049 +{ int result;
10050 + size_t i;
10051 + size_t len = aa.length;
10052 +
10053 + debug(apply) printf("_aApplywc1(), len = %d\n", len);
10054 + for (i = 0; i < len; )
10055 + { dchar d;
10056 + wchar w;
10057 + char c;
10058 +
10059 + w = aa[i];
10060 + if (w & ~0x7F)
10061 + {
10062 + char[4] buf;
10063 +
10064 + d = decode(aa, i);
10065 + auto b = toUTF8(buf, d);
10066 + foreach (char c2; b)
10067 + {
10068 + result = dg(cast(void *)&c2);
10069 + if (result)
10070 + return result;
10071 + }
10072 + continue;
10073 + }
10074 + else
10075 + { c = cast(char)w;
10076 + i++;
10077 + }
10078 + result = dg(cast(void *)&c);
10079 + if (result)
10080 + break;
10081 + }
10082 + return result;
10083 +}
10084 +
10085 +extern (C) int _aApplydc1(dchar[] aa, dg_t dg)
10086 +{ int result;
10087 +
10088 + debug(apply) printf("_aApplydc1(), len = %d\n", aa.length);
10089 + foreach (dchar d; aa)
10090 + {
10091 + char c;
10092 +
10093 + if (d & ~0x7F)
10094 + {
10095 + char[4] buf;
10096 +
10097 + auto b = toUTF8(buf, d);
10098 + foreach (char c2; b)
10099 + {
10100 + result = dg(cast(void *)&c2);
10101 + if (result)
10102 + return result;
10103 + }
10104 + continue;
10105 + }
10106 + else
10107 + {
10108 + c = cast(char)d;
10109 + }
10110 + result = dg(cast(void *)&c);
10111 + if (result)
10112 + break;
10113 + }
10114 + return result;
10115 +}
10116 +
10117 +extern (C) int _aApplydw1(dchar[] aa, dg_t dg)
10118 +{ int result;
10119 +
10120 + debug(apply) printf("_aApplydw1(), len = %d\n", aa.length);
10121 + foreach (dchar d; aa)
10122 + {
10123 + wchar w;
10124 +
10125 + if (d <= 0xFFFF)
10126 + w = cast(wchar) d;
10127 + else
10128 + {
10129 + w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
10130 + result = dg(cast(void *)&w);
10131 + if (result)
10132 + break;
10133 + w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
10134 + }
10135 + result = dg(cast(void *)&w);
10136 + if (result)
10137 + break;
10138 + }
10139 + return result;
10140 +}
10141 +
10142 +
10143 +/****************************************************************************/
10144 +
10145 +// dg is D, but _aApplycd2() is C
10146 +extern (D) typedef int delegate(void *, void *) dg2_t;
10147 +
10148 +extern (C) int _aApplycd2(char[] aa, dg2_t dg)
10149 +{ int result;
10150 + size_t i;
10151 + size_t n;
10152 + size_t len = aa.length;
10153 +
10154 + debug(apply) printf("_aApplycd2(), len = %d\n", len);
10155 + for (i = 0; i < len; i += n)
10156 + { dchar d;
10157 +
10158 + d = aa[i];
10159 + if (d & 0x80)
10160 + {
10161 + n = i;
10162 + d = decode(aa, n);
10163 + n -= i;
10164 + }
10165 + else
10166 + n = 1;
10167 + result = dg(&i, cast(void *)&d);
10168 + if (result)
10169 + break;
10170 + }
10171 + return result;
10172 +}
10173 +
10174 +extern (C) int _aApplywd2(wchar[] aa, dg2_t dg)
10175 +{ int result;
10176 + size_t i;
10177 + size_t n;
10178 + size_t len = aa.length;
10179 +
10180 + debug(apply) printf("_aApplywd2(), len = %d\n", len);
10181 + for (i = 0; i < len; i += n)
10182 + { dchar d;
10183 +
10184 + d = aa[i];
10185 + if (d & ~0x7F)
10186 + {
10187 + n = i;
10188 + d = decode(aa, n);
10189 + n -= i;
10190 + }
10191 + else
10192 + n = 1;
10193 + result = dg(&i, cast(void *)&d);
10194 + if (result)
10195 + break;
10196 + }
10197 + return result;
10198 +}
10199 +
10200 +extern (C) int _aApplycw2(char[] aa, dg2_t dg)
10201 +{ int result;
10202 + size_t i;
10203 + size_t n;
10204 + size_t len = aa.length;
10205 +
10206 + debug(apply) printf("_aApplycw2(), len = %d\n", len);
10207 + for (i = 0; i < len; i += n)
10208 + { dchar d;
10209 + wchar w;
10210 +
10211 + w = aa[i];
10212 + if (w & 0x80)
10213 + { n = i;
10214 + d = decode(aa, n);
10215 + n -= i;
10216 + if (d <= 0xFFFF)
10217 + w = cast(wchar) d;
10218 + else
10219 + {
10220 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
10221 + result = dg(&i, cast(void *)&w);
10222 + if (result)
10223 + break;
10224 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
10225 + }
10226 + }
10227 + else
10228 + n = 1;
10229 + result = dg(&i, cast(void *)&w);
10230 + if (result)
10231 + break;
10232 + }
10233 + return result;
10234 +}
10235 +
10236 +extern (C) int _aApplywc2(wchar[] aa, dg2_t dg)
10237 +{ int result;
10238 + size_t i;
10239 + size_t n;
10240 + size_t len = aa.length;
10241 +
10242 + debug(apply) printf("_aApplywc2(), len = %d\n", len);
10243 + for (i = 0; i < len; i += n)
10244 + { dchar d;
10245 + wchar w;
10246 + char c;
10247 +
10248 + w = aa[i];
10249 + if (w & ~0x7F)
10250 + {
10251 + char[4] buf;
10252 +
10253 + n = i;
10254 + d = decode(aa, n);
10255 + n -= i;
10256 + auto b = toUTF8(buf, d);
10257 + foreach (char c2; b)
10258 + {
10259 + result = dg(&i, cast(void *)&c2);
10260 + if (result)
10261 + return result;
10262 + }
10263 + continue;
10264 + }
10265 + else
10266 + { c = cast(char)w;
10267 + n = 1;
10268 + }
10269 + result = dg(&i, cast(void *)&c);
10270 + if (result)
10271 + break;
10272 + }
10273 + return result;
10274 +}
10275 +
10276 +extern (C) int _aApplydc2(dchar[] aa, dg2_t dg)
10277 +{ int result;
10278 + size_t i;
10279 + size_t len = aa.length;
10280 +
10281 + debug(apply) printf("_aApplydc2(), len = %d\n", len);
10282 + for (i = 0; i < len; i++)
10283 + { dchar d;
10284 + char c;
10285 +
10286 + d = aa[i];
10287 + debug(apply) printf("d = %u\n", d);
10288 + if (d & ~0x7F)
10289 + {
10290 + char[4] buf;
10291 +
10292 + auto b = toUTF8(buf, d);
10293 + foreach (char c2; b)
10294 + {
10295 + debug(apply) printf("c2 = %d\n", c2);
10296 + result = dg(&i, cast(void *)&c2);
10297 + if (result)
10298 + return result;
10299 + }
10300 + continue;
10301 + }
10302 + else
10303 + { c = cast(char)d;
10304 + }
10305 + result = dg(&i, cast(void *)&c);
10306 + if (result)
10307 + break;
10308 + }
10309 + return result;
10310 +}
10311 +
10312 +extern (C) int _aApplydw2(dchar[] aa, dg2_t dg)
10313 +{ int result;
10314 +
10315 + debug(apply) printf("_aApplydw2(), len = %d\n", aa.length);
10316 + foreach (size_t i, dchar d; aa)
10317 + {
10318 + wchar w;
10319 + auto j = i;
10320 +
10321 + if (d <= 0xFFFF)
10322 + w = cast(wchar) d;
10323 + else
10324 + {
10325 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
10326 + result = dg(&j, cast(void *)&w);
10327 + if (result)
10328 + break;
10329 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
10330 + }
10331 + result = dg(&j, cast(void *)&w);
10332 + if (result)
10333 + break;
10334 + }
10335 + return result;
10336 +}
10337 Index: src/compiler/ldc/monitor.c
10338 ===================================================================
10339 --- src/compiler/ldc/monitor.c (revision 0)
10340 +++ src/compiler/ldc/monitor.c (revision 0)
10341 @@ -0,0 +1,212 @@
10342 +// D programming language runtime library
10343 +// Public Domain
10344 +// written by Walter Bright, Digital Mars
10345 +// www.digitalmars.com
10346 +
10347 +// This is written in C because nobody has written a pthreads interface
10348 +// to D yet.
10349 +
10350 +
10351 +#include <stdio.h>
10352 +#include <stdlib.h>
10353 +#include <assert.h>
10354 +
10355 +#if _WIN32
10356 +#elif linux || __APPLE__
10357 +#define USE_PTHREADS 1
10358 +#else
10359 +#endif
10360 +
10361 +#if _WIN32
10362 +#include <windows.h>
10363 +#endif
10364 +
10365 +#if USE_PTHREADS
10366 +#include <pthread.h>
10367 +#endif
10368 +
10369 +#include "mars.h"
10370 +
10371 +// This is what the monitor reference in Object points to
10372 +typedef struct Monitor
10373 +{
10374 + void* impl; // for user-level monitors
10375 + Array devt; // for internal monitors
10376 +
10377 +#if _WIN32
10378 + CRITICAL_SECTION mon;
10379 +#endif
10380 +
10381 +#if USE_PTHREADS
10382 + pthread_mutex_t mon;
10383 +#endif
10384 +} Monitor;
10385 +
10386 +#define MONPTR(h) (&((Monitor *)(h)->monitor)->mon)
10387 +
10388 +static volatile int inited;
10389 +
10390 +/* =============================== Win32 ============================ */
10391 +
10392 +#if _WIN32
10393 +
10394 +static CRITICAL_SECTION _monitor_critsec;
10395 +
10396 +void _STI_monitor_staticctor()
10397 +{
10398 + if (!inited)
10399 + { InitializeCriticalSection(&_monitor_critsec);
10400 + inited = 1;
10401 + }
10402 +}
10403 +
10404 +void _STD_monitor_staticdtor()
10405 +{
10406 + if (inited)
10407 + { inited = 0;
10408 + DeleteCriticalSection(&_monitor_critsec);
10409 + }
10410 +}
10411 +
10412 +void _d_monitor_create(Object *h)
10413 +{
10414 + /*
10415 + * NOTE: Assume this is only called when h->monitor is null prior to the
10416 + * call. However, please note that another thread may call this function
10417 + * at the same time, so we can not assert this here. Instead, try and
10418 + * create a lock, and if one already exists then forget about it.
10419 + */
10420 +
10421 + //printf("+_d_monitor_create(%p)\n", h);
10422 + assert(h);
10423 + Monitor *cs = NULL;
10424 + EnterCriticalSection(&_monitor_critsec);
10425 + if (!h->monitor)
10426 + {
10427 + cs = (Monitor *)calloc(sizeof(Monitor), 1);
10428 + assert(cs);
10429 + InitializeCriticalSection(&cs->mon);
10430 + h->monitor = (void *)cs;
10431 + cs = NULL;
10432 + }
10433 + LeaveCriticalSection(&_monitor_critsec);
10434 + if (cs)
10435 + free(cs);
10436 + //printf("-_d_monitor_create(%p)\n", h);
10437 +}
10438 +
10439 +void _d_monitor_destroy(Object *h)
10440 +{
10441 + //printf("+_d_monitor_destroy(%p)\n", h);
10442 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10443 + DeleteCriticalSection(MONPTR(h));
10444 + free((void *)h->monitor);
10445 + h->monitor = NULL;
10446 + //printf("-_d_monitor_destroy(%p)\n", h);
10447 +}
10448 +
10449 +int _d_monitor_lock(Object *h)
10450 +{
10451 + //printf("+_d_monitor_acquire(%p)\n", h);
10452 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10453 + EnterCriticalSection(MONPTR(h));
10454 + //printf("-_d_monitor_acquire(%p)\n", h);
10455 +}
10456 +
10457 +void _d_monitor_unlock(Object *h)
10458 +{
10459 + //printf("+_d_monitor_release(%p)\n", h);
10460 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10461 + LeaveCriticalSection(MONPTR(h));
10462 + //printf("-_d_monitor_release(%p)\n", h);
10463 +}
10464 +
10465 +#endif
10466 +
10467 +/* =============================== linux ============================ */
10468 +
10469 +#if USE_PTHREADS
10470 +
10471 +#if !linux
10472 +#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
10473 +#endif
10474 +
10475 +// Includes attribute fixes from David Friedman's GDC port
10476 +
10477 +static pthread_mutex_t _monitor_critsec;
10478 +static pthread_mutexattr_t _monitors_attr;
10479 +
10480 +void _STI_monitor_staticctor()
10481 +{
10482 + if (!inited)
10483 + {
10484 + pthread_mutexattr_init(&_monitors_attr);
10485 + pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP);
10486 + pthread_mutex_init(&_monitor_critsec, 0);
10487 + inited = 1;
10488 + }
10489 +}
10490 +
10491 +void _STD_monitor_staticdtor()
10492 +{
10493 + if (inited)
10494 + { inited = 0;
10495 + pthread_mutex_destroy(&_monitor_critsec);
10496 + pthread_mutexattr_destroy(&_monitors_attr);
10497 + }
10498 +}
10499 +
10500 +void _d_monitor_create(Object *h)
10501 +{
10502 + /*
10503 + * NOTE: Assume this is only called when h->monitor is null prior to the
10504 + * call. However, please note that another thread may call this function
10505 + * at the same time, so we can not assert this here. Instead, try and
10506 + * create a lock, and if one already exists then forget about it.
10507 + */
10508 +
10509 + //printf("+_d_monitor_create(%p)\n", h);
10510 + assert(h);
10511 + Monitor *cs = NULL;
10512 + pthread_mutex_lock(&_monitor_critsec);
10513 + if (!h->monitor)
10514 + {
10515 + cs = (Monitor *)calloc(sizeof(Monitor), 1);
10516 + assert(cs);
10517 + pthread_mutex_init(&cs->mon, & _monitors_attr);
10518 + h->monitor = (void *)cs;
10519 + cs = NULL;
10520 + }
10521 + pthread_mutex_unlock(&_monitor_critsec);
10522 + if (cs)
10523 + free(cs);
10524 + //printf("-_d_monitor_create(%p)\n", h);
10525 +}
10526 +
10527 +void _d_monitor_destroy(Object *h)
10528 +{
10529 + //printf("+_d_monitor_destroy(%p)\n", h);
10530 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10531 + pthread_mutex_destroy(MONPTR(h));
10532 + free((void *)h->monitor);
10533 + h->monitor = NULL;
10534 + //printf("-_d_monitor_destroy(%p)\n", h);
10535 +}
10536 +
10537 +int _d_monitor_lock(Object *h)
10538 +{
10539 + //printf("+_d_monitor_acquire(%p)\n", h);
10540 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10541 + pthread_mutex_lock(MONPTR(h));
10542 + //printf("-_d_monitor_acquire(%p)\n", h);
10543 +}
10544 +
10545 +void _d_monitor_unlock(Object *h)
10546 +{
10547 + //printf("+_d_monitor_release(%p)\n", h);
10548 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10549 + pthread_mutex_unlock(MONPTR(h));
10550 + //printf("-_d_monitor_release(%p)\n", h);
10551 +}
10552 +
10553 +#endif
10554 Index: src/compiler/ldc/ldc.mak
10555 ===================================================================
10556 --- src/compiler/ldc/ldc.mak (revision 0)
10557 +++ src/compiler/ldc/ldc.mak (revision 0)
10558 @@ -0,0 +1,166 @@
10559 +# Makefile to build the compiler runtime D library for Linux
10560 +# Designed to work with GNU make
10561 +# Targets:
10562 +# make
10563 +# Same as make all
10564 +# make lib
10565 +# Build the compiler runtime library
10566 +# make doc
10567 +# Generate documentation
10568 +# make clean
10569 +# Delete unneeded files created by build process
10570 +
10571 +LIB_TARGET=libdruntime-rt-ldc.a
10572 +LIB_MASK=libdruntime-rt-ldc*.a
10573 +
10574 +CP=cp -f
10575 +RM=rm -f
10576 +MD=mkdir -p
10577 +
10578 +#CFLAGS=-O $(ADD_CFLAGS)
10579 +CFLAGS=-g $(ADD_CFLAGS)
10580 +
10581 +#DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
10582 +DFLAGS=-g -w $(ADD_DFLAGS)
10583 +
10584 +#TFLAGS=-O -inline -w $(ADD_DFLAGS)
10585 +TFLAGS=-g -w $(ADD_DFLAGS)
10586 +
10587 +DOCFLAGS=-version=DDoc
10588 +
10589 +CC=gcc
10590 +LC=$(AR) -qsv
10591 +DC=ldc2
10592 +
10593 +LIB_DEST=../../../lib
10594 +IMPORT_DEST=../../../import/
10595 +
10596 +.SUFFIXES: .s .S .c .cpp .d .html .o
10597 +
10598 +.s.o:
10599 + $(CC) -c $(CFLAGS) $< -o$@
10600 +
10601 +.S.o:
10602 + $(CC) -c $(CFLAGS) $< -o$@
10603 +
10604 +.c.o:
10605 + $(CC) -c $(CFLAGS) $< -o$@
10606 +
10607 +.cpp.o:
10608 + g++ -c $(CFLAGS) $< -o$@
10609 +
10610 +.d.o:
10611 + $(DC) -c $(DFLAGS) $< -of$@
10612 +
10613 +.d.html:
10614 + $(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
10615 +
10616 +targets : lib doc
10617 +all : lib doc
10618 +lib : ldc.lib
10619 +doc : ldc.doc
10620 +
10621 +######################################################
10622 +
10623 +OBJ_BASE= \
10624 + aaA.o \
10625 + aApply.o \
10626 + aApplyR.o \
10627 + adi.o \
10628 + arrayInit.o \
10629 + cast.o \
10630 + critical.o \
10631 + eh.o \
10632 + dmain2.o \
10633 + invariant.o \
10634 + lifetime.o \
10635 + memory.o \
10636 + monitor.o \
10637 + genobj.o \
10638 + qsort2.o \
10639 + switch.o
10640 +
10641 +OBJ_UTIL= \
10642 + util/console.o \
10643 + util/ctype.o \
10644 + util/string.o \
10645 + util/utf.o \
10646 + ldc/bitmanip.o \
10647 + ldc/vararg.o
10648 +
10649 +OBJ_TI= \
10650 + typeinfo/ti_AC.o \
10651 + typeinfo/ti_Acdouble.o \
10652 + typeinfo/ti_Acfloat.o \
10653 + typeinfo/ti_Acreal.o \
10654 + typeinfo/ti_Adouble.o \
10655 + typeinfo/ti_Afloat.o \
10656 + typeinfo/ti_Ag.o \
10657 + typeinfo/ti_Aint.o \
10658 + typeinfo/ti_Along.o \
10659 + typeinfo/ti_Areal.o \
10660 + typeinfo/ti_Ashort.o \
10661 + typeinfo/ti_byte.o \
10662 + typeinfo/ti_C.o \
10663 + typeinfo/ti_cdouble.o \
10664 + typeinfo/ti_cfloat.o \
10665 + typeinfo/ti_char.o \
10666 + typeinfo/ti_creal.o \
10667 + typeinfo/ti_dchar.o \
10668 + typeinfo/ti_delegate.o \
10669 + typeinfo/ti_double.o \
10670 + typeinfo/ti_float.o \
10671 + typeinfo/ti_idouble.o \
10672 + typeinfo/ti_ifloat.o \
10673 + typeinfo/ti_int.o \
10674 + typeinfo/ti_ireal.o \
10675 + typeinfo/ti_long.o \
10676 + typeinfo/ti_ptr.o \
10677 + typeinfo/ti_real.o \
10678 + typeinfo/ti_short.o \
10679 + typeinfo/ti_ubyte.o \
10680 + typeinfo/ti_uint.o \
10681 + typeinfo/ti_ulong.o \
10682 + typeinfo/ti_ushort.o \
10683 + typeinfo/ti_void.o \
10684 + typeinfo/ti_wchar.o
10685 +
10686 +ALL_OBJS= \
10687 + $(OBJ_BASE) \
10688 + $(OBJ_UTIL) \
10689 + $(OBJ_TI)
10690 +
10691 +######################################################
10692 +
10693 +ALL_DOCS=
10694 +
10695 +######################################################
10696 +
10697 +ldc.lib : $(LIB_TARGET)
10698 +
10699 +$(LIB_TARGET) : $(ALL_OBJS)
10700 + $(RM) $@
10701 + $(LC) $@ $(ALL_OBJS)
10702 +
10703 +ldc.doc : $(ALL_DOCS)
10704 + echo No documentation available.
10705 +
10706 +################### LDC SPECIALS #####################
10707 +
10708 +ldc/bitmanip.o : ldc/bitmanip.d
10709 + $(DC) -c $(DFLAGS) -d -Hf$(IMPORT_DEST)/$*.di ldc/bitmanip.d -of$@
10710 +
10711 +ldc/vararg.o : ldc/vararg.d
10712 + $(DC) -c $(DFLAGS) -d -Hf$(IMPORT_DEST)/$*.di ldc/vararg.d -of$@
10713 +
10714 +######################################################
10715 +
10716 +clean :
10717 + find . -name "*.di" | xargs $(RM)
10718 + $(RM) $(ALL_OBJS)
10719 + $(RM) $(ALL_DOCS)
10720 + $(RM) $(LIB_MASK)
10721 +
10722 +install :
10723 + $(MD) $(LIB_DEST)
10724 + $(CP) $(LIB_MASK) $(LIB_DEST)/.
10725 Index: src/compiler/ldc/critical.c
10726 ===================================================================
10727 --- src/compiler/ldc/critical.c (revision 0)
10728 +++ src/compiler/ldc/critical.c (revision 0)
10729 @@ -0,0 +1,164 @@
10730 +/*
10731 + * Placed into the Public Domain
10732 + * written by Walter Bright, Digital Mars
10733 + * www.digitalmars.com
10734 + */
10735 +
10736 +/* ================================= Win32 ============================ */
10737 +
10738 +#if _WIN32
10739 +
10740 +#include <windows.h>
10741 +
10742 +/******************************************
10743 + * Enter/exit critical section.
10744 + */
10745 +
10746 +/* We don't initialize critical sections unless we actually need them.
10747 + * So keep a linked list of the ones we do use, and in the static destructor
10748 + * code, walk the list and release them.
10749 + */
10750 +
10751 +typedef struct D_CRITICAL_SECTION
10752 +{
10753 + struct D_CRITICAL_SECTION *next;
10754 + CRITICAL_SECTION cs;
10755 +} D_CRITICAL_SECTION;
10756 +
10757 +static D_CRITICAL_SECTION *dcs_list;
10758 +static D_CRITICAL_SECTION critical_section;
10759 +static volatile int inited;
10760 +
10761 +void _d_criticalenter(D_CRITICAL_SECTION *dcs)
10762 +{
10763 + if (!dcs->next)
10764 + {
10765 + EnterCriticalSection(&critical_section.cs);
10766 + if (!dcs->next) // if, in the meantime, another thread didn't set it
10767 + {
10768 + dcs->next = dcs_list;
10769 + dcs_list = dcs;
10770 + InitializeCriticalSection(&dcs->cs);
10771 + }
10772 + LeaveCriticalSection(&critical_section.cs);
10773 + }
10774 + EnterCriticalSection(&dcs->cs);
10775 +}
10776 +
10777 +void _d_criticalexit(D_CRITICAL_SECTION *dcs)
10778 +{
10779 + LeaveCriticalSection(&dcs->cs);
10780 +}
10781 +
10782 +void _STI_critical_init()
10783 +{
10784 + if (!inited)
10785 + { InitializeCriticalSection(&critical_section.cs);
10786 + dcs_list = &critical_section;
10787 + inited = 1;
10788 + }
10789 +}
10790 +
10791 +void _STD_critical_term()
10792 +{
10793 + if (inited)
10794 + { inited = 0;
10795 + while (dcs_list)
10796 + {
10797 + DeleteCriticalSection(&dcs_list->cs);
10798 + dcs_list = dcs_list->next;
10799 + }
10800 + }
10801 +}
10802 +
10803 +#endif
10804 +
10805 +/* ================================= linux ============================ */
10806 +
10807 +#if linux || __APPLE__ || __FreeBSD__
10808 +
10809 +#include <stdio.h>
10810 +#include <stdlib.h>
10811 +#include <pthread.h>
10812 +
10813 +#if !linux
10814 +#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
10815 +#endif
10816 +
10817 +/******************************************
10818 + * Enter/exit critical section.
10819 + */
10820 +
10821 +/* We don't initialize critical sections unless we actually need them.
10822 + * So keep a linked list of the ones we do use, and in the static destructor
10823 + * code, walk the list and release them.
10824 + */
10825 +
10826 +typedef struct D_CRITICAL_SECTION
10827 +{
10828 + struct D_CRITICAL_SECTION *next;
10829 + pthread_mutex_t cs;
10830 +} D_CRITICAL_SECTION;
10831 +
10832 +static D_CRITICAL_SECTION *dcs_list;
10833 +static D_CRITICAL_SECTION critical_section;
10834 +static pthread_mutexattr_t _criticals_attr;
10835 +
10836 +void _STI_critical_init(void);
10837 +void _STD_critical_term(void);
10838 +
10839 +void _d_criticalenter(D_CRITICAL_SECTION *dcs)
10840 +{
10841 + if (!dcs_list)
10842 + { _STI_critical_init();
10843 + atexit(_STD_critical_term);
10844 + }
10845 + //printf("_d_criticalenter(dcs = x%x)\n", dcs);
10846 + if (!dcs->next)
10847 + {
10848 + pthread_mutex_lock(&critical_section.cs);
10849 + if (!dcs->next) // if, in the meantime, another thread didn't set it
10850 + {
10851 + dcs->next = dcs_list;
10852 + dcs_list = dcs;
10853 + pthread_mutex_init(&dcs->cs, &_criticals_attr);
10854 + }
10855 + pthread_mutex_unlock(&critical_section.cs);
10856 + }
10857 + pthread_mutex_lock(&dcs->cs);
10858 +}
10859 +
10860 +void _d_criticalexit(D_CRITICAL_SECTION *dcs)
10861 +{
10862 + //printf("_d_criticalexit(dcs = x%x)\n", dcs);
10863 + pthread_mutex_unlock(&dcs->cs);
10864 +}
10865 +
10866 +void _STI_critical_init()
10867 +{
10868 + if (!dcs_list)
10869 + { //printf("_STI_critical_init()\n");
10870 + pthread_mutexattr_init(&_criticals_attr);
10871 + pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP);
10872 +
10873 + // The global critical section doesn't need to be recursive
10874 + pthread_mutex_init(&critical_section.cs, 0);
10875 + dcs_list = &critical_section;
10876 + }
10877 +}
10878 +
10879 +void _STD_critical_term()
10880 +{
10881 + if (dcs_list)
10882 + { //printf("_STI_critical_term()\n");
10883 + while (dcs_list)
10884 + {
10885 + //printf("\tlooping... %x\n", dcs_list);
10886 + pthread_mutex_destroy(&dcs_list->cs);
10887 + dcs_list = dcs_list->next;
10888 + }
10889 + }
10890 +}
10891 +
10892 +#endif
10893 +
10894 Index: src/compiler/ldc/qsort2.d
10895 ===================================================================
10896 --- src/compiler/ldc/qsort2.d (revision 0)
10897 +++ src/compiler/ldc/qsort2.d (revision 0)
10898 @@ -0,0 +1,67 @@
10899 +
10900 +/*
10901 + * Placed into Public Domain
10902 + * written by Walter Bright
10903 + * www.digitalmars.com
10904 + *
10905 + * This is a public domain version of qsort.d.
10906 + * All it does is call C's qsort(), but runs a little slower since
10907 + * it needs to synchronize a global variable.
10908 + */
10909 +
10910 +/*
10911 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
10912 + */
10913 +
10914 +//debug=qsort;
10915 +
10916 +version( D_Version2 )
10917 +private import stdlib = core.stdc.stdlib;
10918 +else
10919 +private import stdlib = tango.stdc.stdlib;
10920 +
10921 +private TypeInfo tiglobal;
10922 +
10923 +extern (C) int cmp(in void* p1, in void* p2)
10924 +{
10925 + return tiglobal.compare(p1, p2);
10926 +}
10927 +
10928 +extern (C) void[] _adSort(void[] a, TypeInfo ti)
10929 +{
10930 + synchronized
10931 + {
10932 + tiglobal = ti;
10933 + stdlib.qsort(a.ptr, a.length, cast(size_t)ti.tsize(), &cmp);
10934 + }
10935 + return a;
10936 +}
10937 +
10938 +
10939 +
10940 +unittest
10941 +{
10942 + debug(qsort) printf("array.sort.unittest()\n");
10943 +
10944 + int a[] = new int[10];
10945 +
10946 + a[0] = 23;
10947 + a[1] = 1;
10948 + a[2] = 64;
10949 + a[3] = 5;
10950 + a[4] = 6;
10951 + a[5] = 5;
10952 + a[6] = 17;
10953 + a[7] = 3;
10954 + a[8] = 0;
10955 + a[9] = -1;
10956 +
10957 + a.sort;
10958 +
10959 + for (int i = 0; i < a.length - 1; i++)
10960 + {
10961 + //printf("i = %d", i);
10962 + //printf(" %d %d\n", a[i], a[i + 1]);
10963 + assert(a[i] <= a[i + 1]);
10964 + }
10965 +}
10966 Index: src/compiler/ldc/cast.d
10967 ===================================================================
10968 --- src/compiler/ldc/cast.d (revision 0)
10969 +++ src/compiler/ldc/cast.d (revision 0)
10970 @@ -0,0 +1,196 @@
10971 +/*
10972 + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
10973 + * Written by Walter Bright
10974 + *
10975 + * This software is provided 'as-is', without any express or implied
10976 + * warranty. In no event will the authors be held liable for any damages
10977 + * arising from the use of this software.
10978 + *
10979 + * Permission is granted to anyone to use this software for any purpose,
10980 + * including commercial applications, and to alter it and redistribute it
10981 + * freely, in both source and binary form, subject to the following
10982 + * restrictions:
10983 + *
10984 + * o The origin of this software must not be misrepresented; you must not
10985 + * claim that you wrote the original software. If you use this software
10986 + * in a product, an acknowledgment in the product documentation would be
10987 + * appreciated but is not required.
10988 + * o Altered source versions must be plainly marked as such, and must not
10989 + * be misrepresented as being the original software.
10990 + * o This notice may not be removed or altered from any source
10991 + * distribution.
10992 + */
10993 +
10994 +/*
10995 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
10996 + */
10997 +
10998 +extern (C):
10999 +
11000 +//debug = PRINTF;
11001 +debug(PRINTF) int printf(char*, ...);
11002 +
11003 +/******************************************
11004 + * Given a pointer:
11005 + * If it is an Object, return that Object.
11006 + * If it is an interface, return the Object implementing the interface.
11007 + * If it is null, return null.
11008 + * Else, undefined crash
11009 + */
11010 +
11011 +Object _d_toObject(void* p)
11012 +{ Object o;
11013 + debug(PRINTF) printf("toObject(%p)\n", p);
11014 + if (p)
11015 + {
11016 + o = cast(Object)p;
11017 + debug(PRINTF) printf("o = %p\n", o);
11018 + debug(PRINTF) printf("o.vtbl = %p\n", *cast(void**)p);
11019 + ClassInfo oc = o.classinfo;
11020 + debug(PRINTF) printf("oc = %p\n", oc);
11021 + Interface *pi = **cast(Interface ***)p;
11022 + debug(PRINTF) printf("pi = %p\n", pi);
11023 +
11024 + /* Interface.offset lines up with ClassInfo.name.ptr,
11025 + * so we rely on pointers never being less than 64K,
11026 + * and interface vtable offsets never being greater.
11027 + */
11028 + if (pi.offset < 0x10000)
11029 + {
11030 + debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
11031 + o = cast(Object)(p - pi.offset);
11032 + }
11033 + }
11034 + debug(PRINTF) printf("toObject = %p\n", o);
11035 + return o;
11036 +}
11037 +
11038 +
11039 +/*************************************
11040 + * Attempts to cast Object o to class c.
11041 + * Returns o if successful, null if not.
11042 + */
11043 +
11044 +Object _d_interface_cast(void* p, ClassInfo c)
11045 +{ Object o;
11046 +
11047 + debug(PRINTF) printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name.length, c.name.ptr);
11048 + if (p)
11049 + {
11050 + Interface *pi = **cast(Interface ***)p;
11051 +
11052 + debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
11053 + o = cast(Object)(p - pi.offset);
11054 + return _d_dynamic_cast(o, c);
11055 + }
11056 + debug(PRINTF) printf("_d_interface_cast = %p\n", o);
11057 + return o;
11058 +}
11059 +
11060 +Object _d_dynamic_cast(Object o, ClassInfo c)
11061 +{ ClassInfo oc;
11062 + size_t offset = 0;
11063 +
11064 + debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr);
11065 +
11066 + if (o)
11067 + {
11068 + oc = o.classinfo;
11069 + if (_d_isbaseof2(oc, c, offset))
11070 + {
11071 + debug(PRINTF) printf("\toffset = %d\n", offset);
11072 + o = cast(Object)(cast(void*)o + offset);
11073 + }
11074 + else
11075 + o = null;
11076 + }
11077 + //printf("\tresult = %p\n", o);
11078 + debug(PRINTF) printf("_d_dynamic_cast = %p\n", o);
11079 + return o;
11080 +}
11081 +
11082 +int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
11083 +{ int i;
11084 +
11085 + debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset);
11086 +
11087 + if (oc is c)
11088 + return 1;
11089 + do
11090 + {
11091 + debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length);
11092 + if (oc.base is c)
11093 + return 1;
11094 + for (i = 0; i < oc.interfaces.length; i++)
11095 + {
11096 + ClassInfo ic;
11097 +
11098 + ic = oc.interfaces[i].classinfo;
11099 + debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr);
11100 + if (ic is c)
11101 + { offset = cast(size_t)oc.interfaces[i].offset;
11102 + return 1;
11103 + }
11104 + }
11105 + for (i = 0; i < oc.interfaces.length; i++)
11106 + {
11107 + ClassInfo ic;
11108 +
11109 + ic = oc.interfaces[i].classinfo;
11110 + if (_d_isbaseof2(ic, c, offset))
11111 + { offset = cast(size_t)oc.interfaces[i].offset;
11112 + return 1;
11113 + }
11114 + }
11115 + oc = oc.base;
11116 + } while (oc);
11117 + return 0;
11118 +}
11119 +
11120 +int _d_isbaseof(ClassInfo oc, ClassInfo c)
11121 +{ int i;
11122 +
11123 + if (oc is c)
11124 + return 1;
11125 + do
11126 + {
11127 + if (oc.base is c)
11128 + return 1;
11129 + for (i = 0; i < oc.interfaces.length; i++)
11130 + {
11131 + ClassInfo ic;
11132 +
11133 + ic = oc.interfaces[i].classinfo;
11134 + if (ic is c || _d_isbaseof(ic, c))
11135 + return 1;
11136 + }
11137 + oc = oc.base;
11138 + } while (oc);
11139 + return 0;
11140 +}
11141 +
11142 +/*********************************
11143 + * Find the vtbl[] associated with Interface ic.
11144 + */
11145 +
11146 +void *_d_interface_vtbl(ClassInfo ic, Object o)
11147 +{ int i;
11148 + ClassInfo oc;
11149 +
11150 + //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic);
11151 +
11152 + assert(o);
11153 +
11154 + oc = o.classinfo;
11155 + for (i = 0; i < oc.interfaces.length; i++)
11156 + {
11157 + ClassInfo oic;
11158 +
11159 + oic = oc.interfaces[i].classinfo;
11160 + if (oic is ic)
11161 + {
11162 + return cast(void *)oc.interfaces[i].vtbl;
11163 + }
11164 + }
11165 + assert(0);
11166 +}
11167 Index: src/compiler/ldc/util/utf.d
11168 ===================================================================
11169 --- src/compiler/ldc/util/utf.d (revision 0)
11170 +++ src/compiler/ldc/util/utf.d (revision 0)
11171 @@ -0,0 +1,917 @@
11172 +// Written in the D programming language
11173 +
11174 +/*
11175 + * Copyright (C) 2003-2004 by Digital Mars, www.digitalmars.com
11176 + * Written by Walter Bright
11177 + *
11178 + * This software is provided 'as-is', without any express or implied
11179 + * warranty. In no event will the authors be held liable for any damages
11180 + * arising from the use of this software.
11181 + *
11182 + * Permission is granted to anyone to use this software for any purpose,
11183 + * including commercial applications, and to alter it and redistribute it
11184 + * freely, subject to the following restrictions:
11185 + *
11186 + * o The origin of this software must not be misrepresented; you must not
11187 + * claim that you wrote the original software. If you use this software
11188 + * in a product, an acknowledgment in the product documentation would be
11189 + * appreciated but is not required.
11190 + * o Altered source versions must be plainly marked as such, and must not
11191 + * be misrepresented as being the original software.
11192 + * o This notice may not be removed or altered from any source
11193 + * distribution.
11194 + */
11195 +
11196 +/********************************************
11197 + * Encode and decode UTF-8, UTF-16 and UTF-32 strings.
11198 + *
11199 + * For Win32 systems, the C wchar_t type is UTF-16 and corresponds to the D
11200 + * wchar type.
11201 + * For linux systems, the C wchar_t type is UTF-32 and corresponds to
11202 + * the D utf.dchar type.
11203 + *
11204 + * UTF character support is restricted to (\u0000 &lt;= character &lt;= \U0010FFFF).
11205 + *
11206 + * See_Also:
11207 + * $(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia)<br>
11208 + * $(LINK http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8)<br>
11209 + * $(LINK http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335)
11210 + * Macros:
11211 + * WIKI = Phobos/StdUtf
11212 + */
11213 +
11214 +module rt.util.utf;
11215 +
11216 +
11217 +extern (C) void onUnicodeError( string msg, size_t idx );
11218 +
11219 +/*******************************
11220 + * Test if c is a valid UTF-32 character.
11221 + *
11222 + * \uFFFE and \uFFFF are considered valid by this function,
11223 + * as they are permitted for internal use by an application,
11224 + * but they are not allowed for interchange by the Unicode standard.
11225 + *
11226 + * Returns: true if it is, false if not.
11227 + */
11228 +
11229 +bool isValidDchar(dchar c)
11230 +{
11231 + /* Note: FFFE and FFFF are specifically permitted by the
11232 + * Unicode standard for application internal use, but are not
11233 + * allowed for interchange.
11234 + * (thanks to Arcane Jill)
11235 + */
11236 +
11237 + return c < 0xD800 ||
11238 + (c > 0xDFFF && c <= 0x10FFFF /*&& c != 0xFFFE && c != 0xFFFF*/);
11239 +}
11240 +
11241 +unittest
11242 +{
11243 + debug(utf) printf("utf.isValidDchar.unittest\n");
11244 + assert(isValidDchar(cast(dchar)'a') == true);
11245 + assert(isValidDchar(cast(dchar)0x1FFFFF) == false);
11246 +}
11247 +
11248 +
11249 +
11250 +auto UTF8stride =
11251 +[
11252 + cast(ubyte)
11253 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11254 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11255 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11256 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11257 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11258 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11259 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11260 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11261 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11262 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11263 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11264 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11265 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
11266 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
11267 + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
11268 + 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF,
11269 +];
11270 +
11271 +/**
11272 + * stride() returns the length of a UTF-8 sequence starting at index i
11273 + * in string s.
11274 + * Returns:
11275 + * The number of bytes in the UTF-8 sequence or
11276 + * 0xFF meaning s[i] is not the start of of UTF-8 sequence.
11277 + */
11278 +uint stride(in char[] s, size_t i)
11279 +{
11280 + return UTF8stride[s[i]];
11281 +}
11282 +
11283 +/**
11284 + * stride() returns the length of a UTF-16 sequence starting at index i
11285 + * in string s.
11286 + */
11287 +uint stride(in wchar[] s, size_t i)
11288 +{ uint u = s[i];
11289 + return 1 + (u >= 0xD800 && u <= 0xDBFF);
11290 +}
11291 +
11292 +/**
11293 + * stride() returns the length of a UTF-32 sequence starting at index i
11294 + * in string s.
11295 + * Returns: The return value will always be 1.
11296 + */
11297 +uint stride(in dchar[] s, size_t i)
11298 +{
11299 + return 1;
11300 +}
11301 +
11302 +/*******************************************
11303 + * Given an index i into an array of characters s[],
11304 + * and assuming that index i is at the start of a UTF character,
11305 + * determine the number of UCS characters up to that index i.
11306 + */
11307 +
11308 +size_t toUCSindex(in char[] s, size_t i)
11309 +{
11310 + size_t n;
11311 + size_t j;
11312 +
11313 + for (j = 0; j < i; )
11314 + {
11315 + j += stride(s, j);
11316 + n++;
11317 + }
11318 + if (j > i)
11319 + {
11320 + onUnicodeError("invalid UTF-8 sequence", j);
11321 + }
11322 + return n;
11323 +}
11324 +
11325 +/** ditto */
11326 +size_t toUCSindex(in wchar[] s, size_t i)
11327 +{
11328 + size_t n;
11329 + size_t j;
11330 +
11331 + for (j = 0; j < i; )
11332 + {
11333 + j += stride(s, j);
11334 + n++;
11335 + }
11336 + if (j > i)
11337 + {
11338 + onUnicodeError("invalid UTF-16 sequence", j);
11339 + }
11340 + return n;
11341 +}
11342 +
11343 +/** ditto */
11344 +size_t toUCSindex(in dchar[] s, size_t i)
11345 +{
11346 + return i;
11347 +}
11348 +
11349 +/******************************************
11350 + * Given a UCS index n into an array of characters s[], return the UTF index.
11351 + */
11352 +
11353 +size_t toUTFindex(in char[] s, size_t n)
11354 +{
11355 + size_t i;
11356 +
11357 + while (n--)
11358 + {
11359 + uint j = UTF8stride[s[i]];
11360 + if (j == 0xFF)
11361 + onUnicodeError("invalid UTF-8 sequence", i);
11362 + i += j;
11363 + }
11364 + return i;
11365 +}
11366 +
11367 +/** ditto */
11368 +size_t toUTFindex(in wchar[] s, size_t n)
11369 +{
11370 + size_t i;
11371 +
11372 + while (n--)
11373 + { wchar u = s[i];
11374 +
11375 + i += 1 + (u >= 0xD800 && u <= 0xDBFF);
11376 + }
11377 + return i;
11378 +}
11379 +
11380 +/** ditto */
11381 +size_t toUTFindex(in dchar[] s, size_t n)
11382 +{
11383 + return n;
11384 +}
11385 +
11386 +/* =================== Decode ======================= */
11387 +
11388 +/***************
11389 + * Decodes and returns character starting at s[idx]. idx is advanced past the
11390 + * decoded character. If the character is not well formed, a UtfException is
11391 + * thrown and idx remains unchanged.
11392 + */
11393 +dchar decode(in char[] s, inout size_t idx)
11394 + in
11395 + {
11396 + assert(idx >= 0 && idx < s.length);
11397 + }
11398 + out (result)
11399 + {
11400 + assert(isValidDchar(result));
11401 + }
11402 + body
11403 + {
11404 + size_t len = s.length;
11405 + dchar V;
11406 + size_t i = idx;
11407 + char u = s[i];
11408 +
11409 + if (u & 0x80)
11410 + { uint n;
11411 + char u2;
11412 +
11413 + /* The following encodings are valid, except for the 5 and 6 byte
11414 + * combinations:
11415 + * 0xxxxxxx
11416 + * 110xxxxx 10xxxxxx
11417 + * 1110xxxx 10xxxxxx 10xxxxxx
11418 + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
11419 + * 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
11420 + * 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
11421 + */
11422 + for (n = 1; ; n++)
11423 + {
11424 + if (n > 4)
11425 + goto Lerr; // only do the first 4 of 6 encodings
11426 + if (((u << n) & 0x80) == 0)
11427 + {
11428 + if (n == 1)
11429 + goto Lerr;
11430 + break;
11431 + }
11432 + }
11433 +
11434 + // Pick off (7 - n) significant bits of B from first byte of octet
11435 + V = cast(dchar)(u & ((1 << (7 - n)) - 1));
11436 +
11437 + if (i + (n - 1) >= len)
11438 + goto Lerr; // off end of string
11439 +
11440 + /* The following combinations are overlong, and illegal:
11441 + * 1100000x (10xxxxxx)
11442 + * 11100000 100xxxxx (10xxxxxx)
11443 + * 11110000 1000xxxx (10xxxxxx 10xxxxxx)
11444 + * 11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)
11445 + * 11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)
11446 + */
11447 + u2 = s[i + 1];
11448 + if ((u & 0xFE) == 0xC0 ||
11449 + (u == 0xE0 && (u2 & 0xE0) == 0x80) ||
11450 + (u == 0xF0 && (u2 & 0xF0) == 0x80) ||
11451 + (u == 0xF8 && (u2 & 0xF8) == 0x80) ||
11452 + (u == 0xFC && (u2 & 0xFC) == 0x80))
11453 + goto Lerr; // overlong combination
11454 +
11455 + for (uint j = 1; j != n; j++)
11456 + {
11457 + u = s[i + j];
11458 + if ((u & 0xC0) != 0x80)
11459 + goto Lerr; // trailing bytes are 10xxxxxx
11460 + V = (V << 6) | (u & 0x3F);
11461 + }
11462 + if (!isValidDchar(V))
11463 + goto Lerr;
11464 + i += n;
11465 + }
11466 + else
11467 + {
11468 + V = cast(dchar) u;
11469 + i++;
11470 + }
11471 +
11472 + idx = i;
11473 + return V;
11474 +
11475 + Lerr:
11476 + onUnicodeError("invalid UTF-8 sequence", i);
11477 + return V; // dummy return
11478 + }
11479 +
11480 +unittest
11481 +{ size_t i;
11482 + dchar c;
11483 +
11484 + debug(utf) printf("utf.decode.unittest\n");
11485 +
11486 + static s1 = "abcd"c;
11487 + i = 0;
11488 + c = decode(s1, i);
11489 + assert(c == cast(dchar)'a');
11490 + assert(i == 1);
11491 + c = decode(s1, i);
11492 + assert(c == cast(dchar)'b');
11493 + assert(i == 2);
11494 +
11495 + static s2 = "\xC2\xA9"c;
11496 + i = 0;
11497 + c = decode(s2, i);
11498 + assert(c == cast(dchar)'\u00A9');
11499 + assert(i == 2);
11500 +
11501 + static s3 = "\xE2\x89\xA0"c;
11502 + i = 0;
11503 + c = decode(s3, i);
11504 + assert(c == cast(dchar)'\u2260');
11505 + assert(i == 3);
11506 +
11507 + static s4 =
11508 + [ "\xE2\x89"c, // too short
11509 + "\xC0\x8A",
11510 + "\xE0\x80\x8A",
11511 + "\xF0\x80\x80\x8A",
11512 + "\xF8\x80\x80\x80\x8A",
11513 + "\xFC\x80\x80\x80\x80\x8A",
11514 + ];
11515 +
11516 + for (int j = 0; j < s4.length; j++)
11517 + {
11518 + try
11519 + {
11520 + i = 0;
11521 + c = decode(s4[j], i);
11522 + assert(0);
11523 + }
11524 + catch (Object o)
11525 + {
11526 + i = 23;
11527 + }
11528 + assert(i == 23);
11529 + }
11530 +}
11531 +
11532 +/** ditto */
11533 +
11534 +dchar decode(in wchar[] s, inout size_t idx)
11535 + in
11536 + {
11537 + assert(idx >= 0 && idx < s.length);
11538 + }
11539 + out (result)
11540 + {
11541 + assert(isValidDchar(result));
11542 + }
11543 + body
11544 + {
11545 + string msg;
11546 + dchar V;
11547 + size_t i = idx;
11548 + uint u = s[i];
11549 +
11550 + if (u & ~0x7F)
11551 + { if (u >= 0xD800 && u <= 0xDBFF)
11552 + { uint u2;
11553 +
11554 + if (i + 1 == s.length)
11555 + { msg = "surrogate UTF-16 high value past end of string";
11556 + goto Lerr;
11557 + }
11558 + u2 = s[i + 1];
11559 + if (u2 < 0xDC00 || u2 > 0xDFFF)
11560 + { msg = "surrogate UTF-16 low value out of range";
11561 + goto Lerr;
11562 + }
11563 + u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);
11564 + i += 2;
11565 + }
11566 + else if (u >= 0xDC00 && u <= 0xDFFF)
11567 + { msg = "unpaired surrogate UTF-16 value";
11568 + goto Lerr;
11569 + }
11570 + else if (u == 0xFFFE || u == 0xFFFF)
11571 + { msg = "illegal UTF-16 value";
11572 + goto Lerr;
11573 + }
11574 + else
11575 + i++;
11576 + }
11577 + else
11578 + {
11579 + i++;
11580 + }
11581 +
11582 + idx = i;
11583 + return cast(dchar)u;
11584 +
11585 + Lerr:
11586 + onUnicodeError(msg, i);
11587 + return cast(dchar)u; // dummy return
11588 + }
11589 +
11590 +/** ditto */
11591 +
11592 +dchar decode(in dchar[] s, inout size_t idx)
11593 + in
11594 + {
11595 + assert(idx >= 0 && idx < s.length);
11596 + }
11597 + body
11598 + {
11599 + size_t i = idx;
11600 + dchar c = s[i];
11601 +
11602 + if (!isValidDchar(c))
11603 + goto Lerr;
11604 + idx = i + 1;
11605 + return c;
11606 +
11607 + Lerr:
11608 + onUnicodeError("invalid UTF-32 value", i);
11609 + return c; // dummy return
11610 + }
11611 +
11612 +
11613 +/* =================== Encode ======================= */
11614 +
11615 +/*******************************
11616 + * Encodes character c and appends it to array s[].
11617 + */
11618 +void encode(inout char[] s, dchar c)
11619 + in
11620 + {
11621 + assert(isValidDchar(c));
11622 + }
11623 + body
11624 + {
11625 + char[] r = s;
11626 +
11627 + if (c <= 0x7F)
11628 + {
11629 + r ~= cast(char) c;
11630 + }
11631 + else
11632 + {
11633 + char[4] buf;
11634 + uint L;
11635 +
11636 + if (c <= 0x7FF)
11637 + {
11638 + buf[0] = cast(char)(0xC0 | (c >> 6));
11639 + buf[1] = cast(char)(0x80 | (c & 0x3F));
11640 + L = 2;
11641 + }
11642 + else if (c <= 0xFFFF)
11643 + {
11644 + buf[0] = cast(char)(0xE0 | (c >> 12));
11645 + buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
11646 + buf[2] = cast(char)(0x80 | (c & 0x3F));
11647 + L = 3;
11648 + }
11649 + else if (c <= 0x10FFFF)
11650 + {
11651 + buf[0] = cast(char)(0xF0 | (c >> 18));
11652 + buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
11653 + buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
11654 + buf[3] = cast(char)(0x80 | (c & 0x3F));
11655 + L = 4;
11656 + }
11657 + else
11658 + {
11659 + assert(0);
11660 + }
11661 + r ~= buf[0 .. L];
11662 + }
11663 + s = r;
11664 + }
11665 +
11666 +unittest
11667 +{
11668 + debug(utf) printf("utf.encode.unittest\n");
11669 +
11670 + char[] s = "abcd".dup;
11671 + encode(s, cast(dchar)'a');
11672 + assert(s.length == 5);
11673 + assert(s == "abcda");
11674 +
11675 + encode(s, cast(dchar)'\u00A9');
11676 + assert(s.length == 7);
11677 + assert(s == "abcda\xC2\xA9");
11678 + //assert(s == "abcda\u00A9"); // BUG: fix compiler
11679 +
11680 + encode(s, cast(dchar)'\u2260');
11681 + assert(s.length == 10);
11682 + assert(s == "abcda\xC2\xA9\xE2\x89\xA0");
11683 +}
11684 +
11685 +/** ditto */
11686 +
11687 +void encode(inout wchar[] s, dchar c)
11688 + in
11689 + {
11690 + assert(isValidDchar(c));
11691 + }
11692 + body
11693 + {
11694 + wchar[] r = s;
11695 +
11696 + if (c <= 0xFFFF)
11697 + {
11698 + r ~= cast(wchar) c;
11699 + }
11700 + else
11701 + {
11702 + wchar[2] buf;
11703 +
11704 + buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
11705 + buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);
11706 + r ~= buf;
11707 + }
11708 + s = r;
11709 + }
11710 +
11711 +/** ditto */
11712 +void encode(inout dchar[] s, dchar c)
11713 + in
11714 + {
11715 + assert(isValidDchar(c));
11716 + }
11717 + body
11718 + {
11719 + s ~= c;
11720 + }
11721 +
11722 +/**
11723 +Returns the code length of $(D c) in the encoding using $(D C) as a
11724 +code point. The code is returned in character count, not in bytes.
11725 + */
11726 +
11727 +ubyte codeLength(C)(dchar c)
11728 +{
11729 +
11730 + static if (C.sizeof == 1)
11731 + {
11732 + return
11733 + c <= 0x7F ? 1
11734 + : c <= 0x7FF ? 2
11735 + : c <= 0xFFFF ? 3
11736 + : c <= 0x10FFFF ? 4
11737 + : (assert(false), 6);
11738 +}
11739 +
11740 + else static if (C.sizeof == 2)
11741 +{
11742 + return c <= 0xFFFF ? 1 : 2;
11743 + }
11744 + else
11745 + {
11746 + static assert(C.sizeof == 4);
11747 + return 1;
11748 + }
11749 +}
11750 +
11751 +/* =================== Validation ======================= */
11752 +
11753 +/***********************************
11754 +Checks to see if string is well formed or not. $(D S) can be an array
11755 + of $(D char), $(D wchar), or $(D dchar). Throws a $(D UtfException)
11756 + if it is not. Use to check all untrusted input for correctness.
11757 + */
11758 +void validate(S)(in S s)
11759 +{
11760 + auto len = s.length;
11761 + for (size_t i = 0; i < len; )
11762 + {
11763 + decode(s, i);
11764 + }
11765 +}
11766 +
11767 +/* =================== Conversion to UTF8 ======================= */
11768 +
11769 +char[] toUTF8(char[4] buf, dchar c)
11770 + in
11771 + {
11772 + assert(isValidDchar(c));
11773 + }
11774 + body
11775 + {
11776 + if (c <= 0x7F)
11777 + {
11778 + buf[0] = cast(char) c;
11779 + return buf[0 .. 1];
11780 + }
11781 + else if (c <= 0x7FF)
11782 + {
11783 + buf[0] = cast(char)(0xC0 | (c >> 6));
11784 + buf[1] = cast(char)(0x80 | (c & 0x3F));
11785 + return buf[0 .. 2];
11786 + }
11787 + else if (c <= 0xFFFF)
11788 + {
11789 + buf[0] = cast(char)(0xE0 | (c >> 12));
11790 + buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
11791 + buf[2] = cast(char)(0x80 | (c & 0x3F));
11792 + return buf[0 .. 3];
11793 + }
11794 + else if (c <= 0x10FFFF)
11795 + {
11796 + buf[0] = cast(char)(0xF0 | (c >> 18));
11797 + buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
11798 + buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
11799 + buf[3] = cast(char)(0x80 | (c & 0x3F));
11800 + return buf[0 .. 4];
11801 + }
11802 + assert(0);
11803 + }
11804 +
11805 +/*******************
11806 + * Encodes string s into UTF-8 and returns the encoded string.
11807 + */
11808 +string toUTF8(string s)
11809 + in
11810 + {
11811 + validate(s);
11812 + }
11813 + body
11814 + {
11815 + return s;
11816 + }
11817 +
11818 +/** ditto */
11819 +string toUTF8(in wchar[] s)
11820 +{
11821 + char[] r;
11822 + size_t i;
11823 + size_t slen = s.length;
11824 +
11825 + r.length = slen;
11826 +
11827 + for (i = 0; i < slen; i++)
11828 + { wchar c = s[i];
11829 +
11830 + if (c <= 0x7F)
11831 + r[i] = cast(char)c; // fast path for ascii
11832 + else
11833 + {
11834 + r.length = i;
11835 + foreach (dchar c; s[i .. slen])
11836 + {
11837 + encode(r, c);
11838 + }
11839 + break;
11840 + }
11841 + }
11842 + return cast(string)r;
11843 +}
11844 +
11845 +/** ditto */
11846 +string toUTF8(in dchar[] s)
11847 +{
11848 + char[] r;
11849 + size_t i;
11850 + size_t slen = s.length;
11851 +
11852 + r.length = slen;
11853 +
11854 + for (i = 0; i < slen; i++)
11855 + { dchar c = s[i];
11856 +
11857 + if (c <= 0x7F)
11858 + r[i] = cast(char)c; // fast path for ascii
11859 + else
11860 + {
11861 + r.length = i;
11862 + foreach (dchar d; s[i .. slen])
11863 + {
11864 + encode(r, d);
11865 + }
11866 + break;
11867 + }
11868 + }
11869 + return cast(string)r;
11870 +}
11871 +
11872 +/* =================== Conversion to UTF16 ======================= */
11873 +
11874 +wchar[] toUTF16(wchar[2] buf, dchar c)
11875 + in
11876 + {
11877 + assert(isValidDchar(c));
11878 + }
11879 + body
11880 + {
11881 + if (c <= 0xFFFF)
11882 + {
11883 + buf[0] = cast(wchar) c;
11884 + return buf[0 .. 1];
11885 + }
11886 + else
11887 + {
11888 + buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
11889 + buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);
11890 + return buf[0 .. 2];
11891 + }
11892 + }
11893 +
11894 +/****************
11895 + * Encodes string s into UTF-16 and returns the encoded string.
11896 + * toUTF16z() is suitable for calling the 'W' functions in the Win32 API that take
11897 + * an LPWSTR or LPCWSTR argument.
11898 + */
11899 +wstring toUTF16(in char[] s)
11900 +{
11901 + wchar[] r;
11902 + size_t slen = s.length;
11903 +
11904 + r.length = slen;
11905 + r.length = 0;
11906 + for (size_t i = 0; i < slen; )
11907 + {
11908 + dchar c = s[i];
11909 + if (c <= 0x7F)
11910 + {
11911 + i++;
11912 + r ~= cast(wchar)c;
11913 + }
11914 + else
11915 + {
11916 + c = decode(s, i);
11917 + encode(r, c);
11918 + }
11919 + }
11920 + return cast(wstring)r;
11921 +}
11922 +
11923 +alias const(wchar)* wptr;
11924 +/** ditto */
11925 +wptr toUTF16z(in char[] s)
11926 +{
11927 + wchar[] r;
11928 + size_t slen = s.length;
11929 +
11930 + r.length = slen + 1;
11931 + r.length = 0;
11932 + for (size_t i = 0; i < slen; )
11933 + {
11934 + dchar c = s[i];
11935 + if (c <= 0x7F)
11936 + {
11937 + i++;
11938 + r ~= cast(wchar)c;
11939 + }
11940 + else
11941 + {
11942 + c = decode(s, i);
11943 + encode(r, c);
11944 + }
11945 + }
11946 + r ~= "\000";
11947 + return r.ptr;
11948 +}
11949 +
11950 +/** ditto */
11951 +wstring toUTF16(wstring s)
11952 + in
11953 + {
11954 + validate(s);
11955 + }
11956 + body
11957 + {
11958 + return s;
11959 + }
11960 +
11961 +/** ditto */
11962 +wstring toUTF16(in dchar[] s)
11963 +{
11964 + wchar[] r;
11965 + size_t slen = s.length;
11966 +
11967 + r.length = slen;
11968 + r.length = 0;
11969 + for (size_t i = 0; i < slen; i++)
11970 + {
11971 + encode(r, s[i]);
11972 + }
11973 + return cast(wstring)r;
11974 +}
11975 +
11976 +/* =================== Conversion to UTF32 ======================= */
11977 +
11978 +/*****
11979 + * Encodes string s into UTF-32 and returns the encoded string.
11980 + */
11981 +dstring toUTF32(in char[] s)
11982 +{
11983 + dchar[] r;
11984 + size_t slen = s.length;
11985 + size_t j = 0;
11986 +
11987 + r.length = slen; // r[] will never be longer than s[]
11988 + for (size_t i = 0; i < slen; )
11989 + {
11990 + dchar c = s[i];
11991 + if (c >= 0x80)
11992 + c = decode(s, i);
11993 + else
11994 + i++; // c is ascii, no need for decode
11995 + r[j++] = c;
11996 + }
11997 + return cast(dstring)r[0 .. j];
11998 +}
11999 +
12000 +/** ditto */
12001 +dstring toUTF32(in wchar[] s)
12002 +{
12003 + dchar[] r;
12004 + size_t slen = s.length;
12005 + size_t j = 0;
12006 +
12007 + r.length = slen; // r[] will never be longer than s[]
12008 + for (size_t i = 0; i < slen; )
12009 + {
12010 + dchar c = s[i];
12011 + if (c >= 0x80)
12012 + c = decode(s, i);
12013 + else
12014 + i++; // c is ascii, no need for decode
12015 + r[j++] = c;
12016 + }
12017 + return cast(dstring)r[0 .. j];
12018 +}
12019 +
12020 +/** ditto */
12021 +dstring toUTF32(dstring s)
12022 + in
12023 + {
12024 + validate(s);
12025 + }
12026 + body
12027 + {
12028 + return s;
12029 + }
12030 +
12031 +/* ================================ tests ================================== */
12032 +
12033 +unittest
12034 +{
12035 + debug(utf) printf("utf.toUTF.unittest\n");
12036 +
12037 + auto c = "hello"c;
12038 + auto w = toUTF16(c);
12039 + assert(w == "hello");
12040 + auto d = toUTF32(c);
12041 + assert(d == "hello");
12042 +
12043 + c = toUTF8(w);
12044 + assert(c == "hello");
12045 + d = toUTF32(w);
12046 + assert(d == "hello");
12047 +
12048 + c = toUTF8(d);
12049 + assert(c == "hello");
12050 + w = toUTF16(d);
12051 + assert(w == "hello");
12052 +
12053 +
12054 + c = "hel\u1234o";
12055 + w = toUTF16(c);
12056 + assert(w == "hel\u1234o");
12057 + d = toUTF32(c);
12058 + assert(d == "hel\u1234o");
12059 +
12060 + c = toUTF8(w);
12061 + assert(c == "hel\u1234o");
12062 + d = toUTF32(w);
12063 + assert(d == "hel\u1234o");
12064 +
12065 + c = toUTF8(d);
12066 + assert(c == "hel\u1234o");
12067 + w = toUTF16(d);
12068 + assert(w == "hel\u1234o");
12069 +
12070 +
12071 + c = "he\U0010AAAAllo";
12072 + w = toUTF16(c);
12073 + //foreach (wchar c; w) printf("c = x%x\n", c);
12074 + //foreach (wchar c; cast(wstring)"he\U0010AAAAllo") printf("c = x%x\n", c);
12075 + assert(w == "he\U0010AAAAllo");
12076 + d = toUTF32(c);
12077 + assert(d == "he\U0010AAAAllo");
12078 +
12079 + c = toUTF8(w);
12080 + assert(c == "he\U0010AAAAllo");
12081 + d = toUTF32(w);
12082 + assert(d == "he\U0010AAAAllo");
12083 +
12084 + c = toUTF8(d);
12085 + assert(c == "he\U0010AAAAllo");
12086 + w = toUTF16(d);
12087 + assert(w == "he\U0010AAAAllo");
12088 +}
12089 Index: src/compiler/ldc/util/console.d
12090 ===================================================================
12091 --- src/compiler/ldc/util/console.d (revision 0)
12092 +++ src/compiler/ldc/util/console.d (revision 0)
12093 @@ -0,0 +1,49 @@
12094 +/**
12095 + * The console module contains some simple routines for console output.
12096 + *
12097 + * Copyright: Public Domain
12098 + * License: Public Domain
12099 + * Authors: Sean Kelly
12100 + */
12101 +module rt.util.console;
12102 +
12103 +
12104 +private
12105 +{
12106 + version (Windows)
12107 + {
12108 + import core.sys.windows.windows;
12109 + }
12110 + else version( Posix )
12111 + {
12112 + import core.sys.posix.unistd;
12113 + }
12114 + import util.string;
12115 +}
12116 +
12117 +
12118 +struct Console
12119 +{
12120 + Console opCall( in char[] val )
12121 + {
12122 + version( Windows )
12123 + {
12124 + uint count = void;
12125 + WriteFile( GetStdHandle( 0xfffffff5 ), val.ptr, val.length, &count, null );
12126 + }
12127 + else version( Posix )
12128 + {
12129 + write( 2, val.ptr, val.length );
12130 + }
12131 + return *this;
12132 + }
12133 +
12134 +
12135 + Console opCall( uint val )
12136 + {
12137 + char[10] tmp = void;
12138 + return opCall( tmp.intToString( val ) );
12139 + }
12140 +}
12141 +
12142 +Console console;
12143 Index: src/compiler/ldc/util/ctype.d
12144 ===================================================================
12145 --- src/compiler/ldc/util/ctype.d (revision 0)
12146 +++ src/compiler/ldc/util/ctype.d (revision 0)
12147 @@ -0,0 +1,106 @@
12148 +
12149 +/*
12150 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
12151 + * Written by Walter Bright
12152 + *
12153 + * This software is provided 'as-is', without any express or implied
12154 + * warranty. In no event will the authors be held liable for any damages
12155 + * arising from the use of this software.
12156 + *
12157 + * Permission is granted to anyone to use this software for any purpose,
12158 + * including commercial applications, and to alter it and redistribute it
12159 + * freely, in both source and binary form, subject to the following
12160 + * restrictions:
12161 + *
12162 + * o The origin of this software must not be misrepresented; you must not
12163 + * claim that you wrote the original software. If you use this software
12164 + * in a product, an acknowledgment in the product documentation would be
12165 + * appreciated but is not required.
12166 + * o Altered source versions must be plainly marked as such, and must not
12167 + * be misrepresented as being the original software.
12168 + * o This notice may not be removed or altered from any source
12169 + * distribution.
12170 + */
12171 +
12172 +// Simple ASCII char classification functions
12173 +
12174 +module rt.util.ctype;
12175 +
12176 +int isalnum(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG) : 0; }
12177 +int isalpha(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP) : 0; }
12178 +int iscntrl(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_CTL) : 0; }
12179 +int isdigit(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_DIG) : 0; }
12180 +int islower(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_LC) : 0; }
12181 +int ispunct(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_PNC) : 0; }
12182 +int isspace(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_SPC) : 0; }
12183 +int isupper(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_UC) : 0; }
12184 +int isxdigit(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_HEX) : 0; }
12185 +int isgraph(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG|_PNC) : 0; }
12186 +int isprint(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG|_PNC|_BLK) : 0; }
12187 +int isascii(dchar c) { return c <= 0x7F; }
12188 +
12189 +dchar tolower(dchar c)
12190 + out (result)
12191 + {
12192 + assert(!isupper(result));
12193 + }
12194 + body
12195 + {
12196 + return isupper(c) ? c + (cast(dchar)'a' - 'A') : c;
12197 + }
12198 +
12199 +dchar toupper(dchar c)
12200 + out (result)
12201 + {
12202 + assert(!islower(result));
12203 + }
12204 + body
12205 + {
12206 + return islower(c) ? c - (cast(dchar)'a' - 'A') : c;
12207 + }
12208 +
12209 +private:
12210 +
12211 +enum
12212 +{
12213 + _SPC = 8,
12214 + _CTL = 0x20,
12215 + _BLK = 0x40,
12216 + _HEX = 0x80,
12217 + _UC = 1,
12218 + _LC = 2,
12219 + _PNC = 0x10,
12220 + _DIG = 4,
12221 + _ALP = _UC|_LC,
12222 +}
12223 +
12224 +ubyte _ctype[128] =
12225 +[
12226 + _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
12227 + _CTL,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL,_CTL,
12228 + _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
12229 + _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
12230 + _SPC|_BLK,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
12231 + _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
12232 + _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,
12233 + _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,
12234 + _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
12235 + _PNC,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC,
12236 + _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,
12237 + _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,
12238 + _UC,_UC,_UC,_PNC,_PNC,_PNC,_PNC,_PNC,
12239 + _PNC,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC,
12240 + _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC,
12241 + _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC,
12242 + _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL
12243 +];
12244 +
12245 +
12246 +unittest
12247 +{
12248 + assert(isspace(' '));
12249 + assert(!isspace('z'));
12250 + assert(toupper('a') == 'A');
12251 + assert(tolower('Q') == 'q');
12252 + assert(!isxdigit('G'));
12253 +}
12254 Index: src/compiler/ldc/util/string.d
12255 ===================================================================
12256 --- src/compiler/ldc/util/string.d (revision 0)
12257 +++ src/compiler/ldc/util/string.d (revision 0)
12258 @@ -0,0 +1,35 @@
12259 +/**
12260 + * The exception module defines all system-level exceptions and provides a
12261 + * mechanism to alter system-level error handling.
12262 + *
12263 + * Copyright: Copyright (c) 2005-2008, The D Runtime Project
12264 + * License: BSD Style, see LICENSE
12265 + * Authors: Sean Kelly
12266 + */
12267 +module rt.util.string;
12268 +
12269 +private import core.stdc.string;
12270 +
12271 +char[] intToString( char[] buf, uint val )
12272 +{
12273 + assert( buf.length > 9 );
12274 + auto p = buf.ptr + buf.length;
12275 +
12276 + do
12277 + {
12278 + *--p = cast(char)(val % 10 + '0');
12279 + } while( val /= 10 );
12280 +
12281 + return buf[p - buf.ptr .. $];
12282 +}
12283 +
12284 +
12285 +int dstrcmp( in char[] s1, in char[] s2 )
12286 +{
12287 + auto len = s1.length;
12288 + if( s2.length < len )
12289 + len = s2.length;
12290 + if( memcmp( s1.ptr, s2.ptr, len ) == 0 )
12291 + return 0;
12292 + return s1.length > s2.length ? 1 : -1;
12293 +}
12294 Index: src/compiler/ldc/invariant.d
12295 ===================================================================
12296 --- src/compiler/ldc/invariant.d (revision 0)
12297 +++ src/compiler/ldc/invariant.d (revision 0)
12298 @@ -0,0 +1,25 @@
12299 +
12300 +/*
12301 + * Placed into the Public Domain
12302 + * written by Walter Bright
12303 + * www.digitalmars.com
12304 + */
12305 +
12306 +extern(C) void _d_invariant(Object o)
12307 +{ ClassInfo c;
12308 +
12309 + //printf("__d_invariant(%p)\n", o);
12310 +
12311 + // BUG: needs to be filename/line of caller, not library routine
12312 + assert(o !is null); // just do null check, not invariant check
12313 +
12314 + c = o.classinfo;
12315 + do
12316 + {
12317 + if (c.classInvariant)
12318 + {
12319 + (*c.classInvariant)(o);
12320 + }
12321 + c = c.base;
12322 + } while (c);
12323 +}
12324 Index: src/compiler/ldc/eh.d
12325 ===================================================================
12326 --- src/compiler/ldc/eh.d (revision 0)
12327 +++ src/compiler/ldc/eh.d (revision 0)
12328 @@ -0,0 +1,388 @@
12329 +/**
12330 + * This module contains functions and structures required for
12331 + * exception handling.
12332 + */
12333 +module eh;
12334 +
12335 +import util.console;
12336 +import ldc.cstdarg;
12337 +
12338 +// debug = EH_personality;
12339 +
12340 +// current EH implementation works on x86
12341 +// if it has a working unwind runtime
12342 +version(X86) {
12343 + version(linux) version=X86_UNWIND;
12344 + version(darwin) version=X86_UNWIND;
12345 +}
12346 +version(X86_64) {
12347 + version(linux) version=X86_UNWIND;
12348 +}
12349 +
12350 +private extern(C) void abort();
12351 +private extern(C) int printf(in char*, ...);
12352 +private extern(C) int vprintf(in char*, va_list va);
12353 +
12354 +// D runtime functions
12355 +extern(C) {
12356 + int _d_isbaseof(ClassInfo oc, ClassInfo c);
12357 +}
12358 +
12359 +// libunwind headers
12360 +extern(C)
12361 +{
12362 + enum _Unwind_Reason_Code
12363 + {
12364 + NO_REASON = 0,
12365 + FOREIGN_EXCEPTION_CAUGHT = 1,
12366 + FATAL_PHASE2_ERROR = 2,
12367 + FATAL_PHASE1_ERROR = 3,
12368 + NORMAL_STOP = 4,
12369 + END_OF_STACK = 5,
12370 + HANDLER_FOUND = 6,
12371 + INSTALL_CONTEXT = 7,
12372 + CONTINUE_UNWIND = 8
12373 + }
12374 +
12375 + enum _Unwind_Action
12376 + {
12377 + SEARCH_PHASE = 1,
12378 + CLEANUP_PHASE = 2,
12379 + HANDLER_PHASE = 3,
12380 + FORCE_UNWIND = 4
12381 + }
12382 +
12383 + alias void* _Unwind_Context_Ptr;
12384 +
12385 + alias void function(_Unwind_Reason_Code, _Unwind_Exception*) _Unwind_Exception_Cleanup_Fn;
12386 +
12387 + struct _Unwind_Exception
12388 + {
12389 + char[8] exception_class;
12390 + _Unwind_Exception_Cleanup_Fn exception_cleanup;
12391 + int private_1;
12392 + int private_2;
12393 + }
12394 +
12395 +version(X86_UNWIND)
12396 +{
12397 + void _Unwind_Resume(_Unwind_Exception*);
12398 + _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*);
12399 + ulong _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context);
12400 + ulong _Unwind_GetIP(_Unwind_Context_Ptr context);
12401 + ulong _Unwind_SetIP(_Unwind_Context_Ptr context, ulong new_value);
12402 + ulong _Unwind_SetGR(_Unwind_Context_Ptr context, int index, ulong new_value);
12403 + ulong _Unwind_GetRegionStart(_Unwind_Context_Ptr context);
12404 +}
12405 +else
12406 +{
12407 + // runtime calls these directly
12408 + void _Unwind_Resume(_Unwind_Exception*)
12409 + {
12410 + console("_Unwind_Resume is not implemented on this platform.\n");
12411 + }
12412 + _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*)
12413 + {
12414 + console("_Unwind_RaiseException is not implemented on this platform.\n");
12415 + return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
12416 + }
12417 +}
12418 +
12419 +}
12420 +
12421 +// error and exit
12422 +extern(C) private void fatalerror(in char* format, ...)
12423 +{
12424 + va_list args;
12425 + va_start(args, format);
12426 + printf("Fatal error in EH code: ");
12427 + vprintf(format, args);
12428 + printf("\n");
12429 + abort();
12430 +}
12431 +
12432 +
12433 +// helpers for reading certain DWARF data
12434 +private ubyte* get_uleb128(ubyte* addr, ref size_t res)
12435 +{
12436 + res = 0;
12437 + size_t bitsize = 0;
12438 +
12439 + // read as long as high bit is set
12440 + while(*addr & 0x80) {
12441 + res |= (*addr & 0x7f) << bitsize;
12442 + bitsize += 7;
12443 + addr += 1;
12444 + if(bitsize >= size_t.sizeof*8)
12445 + fatalerror("tried to read uleb128 that exceeded size of size_t");
12446 + }
12447 + // read last
12448 + if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize)
12449 + fatalerror("Fatal error in EH code: tried to read uleb128 that exceeded size of size_t");
12450 + res |= (*addr) << bitsize;
12451 +
12452 + return addr + 1;
12453 +}
12454 +
12455 +private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res)
12456 +{
12457 + res = 0;
12458 + size_t bitsize = 0;
12459 +
12460 + // read as long as high bit is set
12461 + while(*addr & 0x80) {
12462 + res |= (*addr & 0x7f) << bitsize;
12463 + bitsize += 7;
12464 + addr += 1;
12465 + if(bitsize >= size_t.sizeof*8)
12466 + fatalerror("tried to read sleb128 that exceeded size of size_t");
12467 + }
12468 + // read last
12469 + if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize)
12470 + fatalerror("tried to read sleb128 that exceeded size of size_t");
12471 + res |= (*addr) << bitsize;
12472 +
12473 + // take care of sign
12474 + if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40))
12475 + res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1);
12476 +
12477 + return addr + 1;
12478 +}
12479 +
12480 +
12481 +// exception struct used by the runtime.
12482 +// _d_throw allocates a new instance and passes the address of its
12483 +// _Unwind_Exception member to the unwind call. The personality
12484 +// routine is then able to get the whole struct by looking at the data
12485 +// surrounding the unwind info.
12486 +struct _d_exception
12487 +{
12488 + Object exception_object;
12489 + _Unwind_Exception unwind_info;
12490 +}
12491 +
12492 +// the 8-byte string identifying the type of exception
12493 +// the first 4 are for vendor, the second 4 for language
12494 +//TODO: This may be the wrong way around
12495 +char[8] _d_exception_class = "LLDCD1\0\0";
12496 +
12497 +
12498 +//
12499 +// x86 unwind specific implementation of personality function
12500 +// and helpers
12501 +//
12502 +version(X86_UNWIND)
12503 +{
12504 +
12505 +// the personality routine gets called by the unwind handler and is responsible for
12506 +// reading the EH tables and deciding what to do
12507 +extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context)
12508 +{
12509 + // check ver: the C++ Itanium ABI only allows ver == 1
12510 + if(ver != 1)
12511 + return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
12512 +
12513 + // check exceptionClass
12514 + //TODO: Treat foreign exceptions with more respect
12515 + if((cast(char*)&exception_class)[0..8] != _d_exception_class)
12516 + return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
12517 +
12518 + // find call site table, action table and classinfo table
12519 + // Note: callsite and action tables do not contain static-length
12520 + // data and will be parsed as needed
12521 + // Note: classinfo_table points past the end of the table
12522 + ubyte* callsite_table;
12523 + ubyte* action_table;
12524 + ClassInfo* classinfo_table;
12525 + _d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table);
12526 +
12527 +
12528 + /*
12529 + find landing pad and action table index belonging to ip by walking
12530 + the callsite_table
12531 + */
12532 + ubyte* callsite_walker = callsite_table;
12533 +
12534 + // get the instruction pointer
12535 + // will be used to find the right entry in the callsite_table
12536 + // -1 because it will point past the last instruction
12537 + ulong ip = _Unwind_GetIP(context) - 1;
12538 +
12539 + // address block_start is relative to
12540 + ulong region_start = _Unwind_GetRegionStart(context);
12541 +
12542 + // table entries
12543 + uint block_start_offset, block_size;
12544 + ulong landing_pad;
12545 + size_t action_offset;
12546 +
12547 + while(true) {
12548 + // if we've gone through the list and found nothing...
12549 + if(callsite_walker >= action_table)
12550 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12551 +
12552 + block_start_offset = *cast(uint*)callsite_walker;
12553 + block_size = *(cast(uint*)callsite_walker + 1);
12554 + landing_pad = *(cast(uint*)callsite_walker + 2);
12555 + if(landing_pad)
12556 + landing_pad += region_start;
12557 + callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset);
12558 +
12559 + debug(EH_personality_verbose) printf("%d %d %d\n", block_start_offset, block_size, landing_pad);
12560 +
12561 + // since the list is sorted, as soon as we're past the ip
12562 + // there's no handler to be found
12563 + if(ip < region_start + block_start_offset)
12564 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12565 +
12566 + // if we've found our block, exit
12567 + if(ip < region_start + block_start_offset + block_size)
12568 + break;
12569 + }
12570 +
12571 + debug(EH_personality) printf("Found correct landing pad and actionOffset %d\n", action_offset);
12572 +
12573 + // now we need the exception's classinfo to find a handler
12574 + // the exception_info is actually a member of a larger _d_exception struct
12575 + // the runtime allocated. get that now
12576 + _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - _d_exception.unwind_info.offsetof);
12577 +
12578 + // if there's no action offset and no landing pad, continue unwinding
12579 + if(!action_offset && !landing_pad)
12580 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12581 +
12582 + // if there's no action offset but a landing pad, this is a cleanup handler
12583 + else if(!action_offset && landing_pad)
12584 + return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context);
12585 +
12586 + /*
12587 + walk action table chain, comparing classinfos using _d_isbaseof
12588 + */
12589 + ubyte* action_walker = action_table + action_offset - 1;
12590 +
12591 + ptrdiff_t ti_offset, next_action_offset;
12592 + while(true) {
12593 + action_walker = get_sleb128(action_walker, ti_offset);
12594 + // it is intentional that we not modify action_walker here
12595 + // next_action_offset is from current action_walker position
12596 + get_sleb128(action_walker, next_action_offset);
12597 +
12598 + // negative are 'filters' which we don't use
12599 + if(!(ti_offset >= 0))
12600 + fatalerror("Filter actions are unsupported");
12601 +
12602 + // zero means cleanup, which we require to be the last action
12603 + if(ti_offset == 0) {
12604 + if(!(next_action_offset == 0))
12605 + fatalerror("Cleanup action must be last in chain");
12606 + return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context);
12607 + }
12608 +
12609 + // get classinfo for action and check if the one in the
12610 + // exception structure is a base
12611 + ClassInfo catch_ci = classinfo_table[-ti_offset];
12612 + debug(EH_personality) printf("Comparing catch %s to exception %s\n", catch_ci.name.ptr, exception_struct.exception_object.classinfo.name.ptr);
12613 + if(_d_isbaseof(exception_struct.exception_object.classinfo, catch_ci))
12614 + return _d_eh_install_catch_context(actions, ti_offset, landing_pad, exception_struct, context);
12615 +
12616 + // we've walked through all actions and found nothing...
12617 + if(next_action_offset == 0)
12618 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12619 + else
12620 + action_walker += next_action_offset;
12621 + }
12622 +
12623 + fatalerror("reached unreachable");
12624 + return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
12625 +}
12626 +
12627 +// These are the register numbers for SetGR that
12628 +// llvm's eh.exception and eh.selector intrinsics
12629 +// will pick up.
12630 +// Found by trial-and-error :/
12631 +version (X86_64)
12632 +{
12633 + private int eh_exception_regno = 3;
12634 + private int eh_selector_regno = 1;
12635 +} else {
12636 + private int eh_exception_regno = 0;
12637 + private int eh_selector_regno = 2;
12638 +}
12639 +
12640 +private _Unwind_Reason_Code _d_eh_install_catch_context(_Unwind_Action actions, ptrdiff_t switchval, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
12641 +{
12642 + debug(EH_personality) printf("Found catch clause!\n");
12643 +
12644 + if(actions & _Unwind_Action.SEARCH_PHASE)
12645 + return _Unwind_Reason_Code.HANDLER_FOUND;
12646 +
12647 + else if(actions & _Unwind_Action.HANDLER_PHASE)
12648 + {
12649 + debug(EH_personality) printf("Setting switch value to: %d!\n", switchval);
12650 + _Unwind_SetGR(context, eh_exception_regno, cast(ulong)cast(void*)(exception_struct.exception_object));
12651 + _Unwind_SetGR(context, eh_selector_regno, switchval);
12652 + _Unwind_SetIP(context, landing_pad);
12653 + return _Unwind_Reason_Code.INSTALL_CONTEXT;
12654 + }
12655 +
12656 + fatalerror("reached unreachable");
12657 + return _Unwind_Reason_Code.FATAL_PHASE2_ERROR;
12658 +}
12659 +
12660 +private _Unwind_Reason_Code _d_eh_install_finally_context(_Unwind_Action actions, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
12661 +{
12662 + // if we're merely in search phase, continue
12663 + if(actions & _Unwind_Action.SEARCH_PHASE)
12664 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12665 +
12666 + debug(EH_personality) printf("Calling cleanup routine...\n");
12667 +
12668 + _Unwind_SetGR(context, eh_exception_regno, cast(ulong)exception_struct);
12669 + _Unwind_SetGR(context, eh_selector_regno, 0);
12670 + _Unwind_SetIP(context, landing_pad);
12671 + return _Unwind_Reason_Code.INSTALL_CONTEXT;
12672 +}
12673 +
12674 +private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci)
12675 +{
12676 + ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context);
12677 +
12678 + //TODO: Do proper DWARF reading here
12679 + if(*data++ != 0xff)
12680 + fatalerror("DWARF header has unexpected format 1");
12681 +
12682 + if(*data++ != 0x00)
12683 + fatalerror("DWARF header has unexpected format 2");
12684 + size_t cioffset;
12685 + data = get_uleb128(data, cioffset);
12686 + ci = cast(ClassInfo*)(data + cioffset);
12687 +
12688 + if(*data++ != 0x03)
12689 + fatalerror("DWARF header has unexpected format 3");
12690 + size_t callsitelength;
12691 + data = get_uleb128(data, callsitelength);
12692 + action = data + callsitelength;
12693 +
12694 + callsite = data;
12695 +}
12696 +
12697 +} // end of x86 Linux specific implementation
12698 +
12699 +
12700 +extern(C) void _d_throw_exception(Object e)
12701 +{
12702 + if (e !is null)
12703 + {
12704 + _d_exception* exc_struct = new _d_exception;
12705 + exc_struct.unwind_info.exception_class[] = _d_exception_class;
12706 + exc_struct.exception_object = e;
12707 + _Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info);
12708 + console("_Unwind_RaiseException failed with reason code: ")(ret)("\n");
12709 + }
12710 + abort();
12711 +}
12712 +
12713 +extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct)
12714 +{
12715 + _Unwind_Resume(&exception_struct.unwind_info);
12716 +}
12717 Index: import/object.di
12718 ===================================================================
12719 --- import/object.di (revision 46)
12720 +++ import/object.di (working copy)
12721 @@ -208,6 +208,13 @@
12722 void function() dtor;
12723 void function() unitTest;
12724
12725 + // DMD actually has them too, but LDC doesn't allow the resulting type mismatch
12726 + version( LDC )
12727 + {
12728 + void* xgetMembers;
12729 + void function() ictor;
12730 + }
12731 +
12732 static int opApply(int delegate(inout ModuleInfo));
12733 }
12734
12735 Index: import/ldc/intrinsics.di
12736 ===================================================================
12737 --- import/ldc/intrinsics.di (revision 0)
12738 +++ import/ldc/intrinsics.di (revision 0)
12739 @@ -0,0 +1,343 @@
12740 +/*
12741 + * This module holds declarations to LLVM intrinsics.
12742 + *
12743 + * See the LLVM language reference for more information:
12744 + *
12745 + * - http://llvm.org/docs/LangRef.html#intrinsics
12746 + *
12747 + */
12748 +
12749 +module ldc.intrinsics;
12750 +
12751 +// Check for the right compiler
12752 +version(LDC)
12753 +{
12754 + // OK
12755 +}
12756 +else
12757 +{
12758 + static assert(false, "This module is only valid for LDC");
12759 +}
12760 +
12761 +//
12762 +// CODE GENERATOR INTRINSICS
12763 +//
12764 +
12765 +
12766 +// The 'llvm.returnaddress' intrinsic attempts to compute a target-specific value indicating the return address of the current function or one of its callers.
12767 +
12768 +pragma(intrinsic, "llvm.returnaddress")
12769 + void* llvm_returnaddress(uint level);
12770 +
12771 +
12772 +// The 'llvm.frameaddress' intrinsic attempts to return the target-specific frame pointer value for the specified stack frame.
12773 +
12774 +pragma(intrinsic, "llvm.frameaddress")
12775 + void* llvm_frameaddress(uint level);
12776 +
12777 +
12778 +// The 'llvm.stacksave' intrinsic is used to remember the current state of the function stack, for use with llvm.stackrestore. This is useful for implementing language features like scoped automatic variable sized arrays in C99.
12779 +
12780 +pragma(intrinsic, "llvm.stacksave")
12781 + void* llvm_stacksave();
12782 +
12783 +
12784 +// The 'llvm.stackrestore' intrinsic is used to restore the state of the function stack to the state it was in when the corresponding llvm.stacksave intrinsic executed. This is useful for implementing language features like scoped automatic variable sized arrays in C99.
12785 +
12786 +pragma(intrinsic, "llvm.stackrestore")
12787 + void llvm_stackrestore(void* ptr);
12788 +
12789 +
12790 +// The 'llvm.prefetch' intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a noop. Prefetches have no effect on the behavior of the program but can change its performance characteristics.
12791 +
12792 +pragma(intrinsic, "llvm.prefetch")
12793 + void llvm_prefetch(void* ptr, uint rw, uint locality);
12794 +
12795 +
12796 +// The 'llvm.pcmarker' intrinsic is a method to export a Program Counter (PC) in a region of code to simulators and other tools. The method is target specific, but it is expected that the marker will use exported symbols to transmit the PC of the marker. The marker makes no guarantees that it will remain with any specific instruction after optimizations. It is possible that the presence of a marker will inhibit optimizations. The intended use is to be inserted after optimizations to allow correlations of simulation runs.
12797 +
12798 +pragma(intrinsic, "llvm.pcmarker")
12799 + void llvm_pcmarker(uint id);
12800 +
12801 +
12802 +// The 'llvm.readcyclecounter' intrinsic provides access to the cycle counter register (or similar low latency, high accuracy clocks) on those targets that support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC. As the backing counters overflow quickly (on the order of 9 seconds on alpha), this should only be used for small timings.
12803 +
12804 +pragma(intrinsic, "llvm.readcyclecounter")
12805 + ulong readcyclecounter();
12806 +
12807 +
12808 +
12809 +
12810 +//
12811 +// STANDARD C LIBRARY INTRINSICS
12812 +//
12813 +
12814 +
12815 +// The 'llvm.memcpy.*' intrinsics copy a block of memory from the source location to the destination location.
12816 +// Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do not return a value, and takes an extra alignment argument.
12817 +
12818 +pragma(intrinsic, "llvm.memcpy.i32")
12819 + void llvm_memcpy_i32(void* dst, void* src, uint len, uint alignment);
12820 +pragma(intrinsic, "llvm.memcpy.i64")
12821 + void llvm_memcpy_i64(void* dst, void* src, ulong len, uint alignment);
12822 +
12823 +
12824 +// The 'llvm.memmove.*' intrinsics move a block of memory from the source location to the destination location. It is similar to the 'llvm.memcpy' intrinsic but allows the two memory locations to overlap.
12825 +// Note that, unlike the standard libc function, the llvm.memmove.* intrinsics do not return a value, and takes an extra alignment argument.
12826 +
12827 +pragma(intrinsic, "llvm.memmove.i32")
12828 + void llvm_memmove_i32(void* dst, void* src, uint len, uint alignment);
12829 +pragma(intrinsic, "llvm.memmove.i64")
12830 + void llvm_memmove_i64(void* dst, void* src, ulong len, int alignment);
12831 +
12832 +
12833 +// The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte value.
12834 +// Note that, unlike the standard libc function, the llvm.memset intrinsic does not return a value, and takes an extra alignment argument.
12835 +
12836 +pragma(intrinsic, "llvm.memset.i32")
12837 + void llvm_memset_i32(void* dst, ubyte val, uint len, uint alignment);
12838 +pragma(intrinsic, "llvm.memset.i64")
12839 + void llvm_memset_i64(void* dst, ubyte val, ulong len, uint alignment);
12840 +
12841 +
12842 +// The 'llvm.sqrt' intrinsics return the sqrt of the specified operand, returning the same value as the libm 'sqrt' functions would. Unlike sqrt in libm, however, llvm.sqrt has undefined behavior for negative numbers other than -0.0 (which allows for better optimization, because there is no need to worry about errno being set). llvm.sqrt(-0.0) is defined to return -0.0 like IEEE sqrt.
12843 +
12844 +pragma(intrinsic, "llvm.sqrt.f32")
12845 + float llvm_sqrt_f32(float val);
12846 +pragma(intrinsic, "llvm.sqrt.f64")
12847 + double llvm_sqrt_f64(double val);
12848 +version(X86)
12849 +{
12850 +pragma(intrinsic, "llvm.sqrt.f80")
12851 + real llvm_sqrt_f80(real val);
12852 +}
12853 +
12854 +version(X86_64)
12855 +{
12856 +pragma(intrinsic, "llvm.sqrt.f80")
12857 + real llvm_sqrt_f80(real val);
12858 +}
12859 +
12860 +
12861 +// The 'llvm.sin.*' intrinsics return the sine of the operand.
12862 +
12863 +pragma(intrinsic, "llvm.sin.f32")
12864 + float llvm_sin_f32(float val);
12865 +pragma(intrinsic, "llvm.sin.f64")
12866 + double llvm_sin_f64(double val);
12867 +version(X86)
12868 +{
12869 +pragma(intrinsic, "llvm.sin.f80")
12870 + real llvm_sin_f80(real val);
12871 +}
12872 +
12873 +version(X86_64)
12874 +{
12875 +pragma(intrinsic, "llvm.sin.f80")
12876 + real llvm_sin_f80(real val);
12877 +}
12878 +
12879 +
12880 +// The 'llvm.cos.*' intrinsics return the cosine of the operand.
12881 +
12882 +pragma(intrinsic, "llvm.cos.f32")
12883 + float llvm_cos_f32(float val);
12884 +pragma(intrinsic, "llvm.cos.f64")
12885 + double llvm_cos_f64(double val);
12886 +version(X86)
12887 +{
12888 +pragma(intrinsic, "llvm.cos.f80")
12889 + real llvm_cos_f80(real val);
12890 +}
12891 +
12892 +version(X86_64)
12893 +{
12894 +pragma(intrinsic, "llvm.cos.f80")
12895 + real llvm_cos_f80(real val);
12896 +}
12897 +
12898 +
12899 +// The 'llvm.powi.*' intrinsics return the first operand raised to the specified (positive or negative) power. The order of evaluation of multiplications is not defined. When a vector of floating point type is used, the second argument remains a scalar integer value.
12900 +
12901 +pragma(intrinsic, "llvm.powi.f32")
12902 + float llvm_powi_f32(float val, int power);
12903 +
12904 +pragma(intrinsic, "llvm.powi.f64")
12905 + double llvm_powi_f64(double val, int power);
12906 +version(X86)
12907 +{
12908 +pragma(intrinsic, "llvm.powi.f80")
12909 + real llvm_powi_f80(real val, int power);
12910 +}
12911 +
12912 +version(X86_64)
12913 +{
12914 +pragma(intrinsic, "llvm.powi.f80")
12915 + real llvm_powi_f80(real val, int power);
12916 +}
12917 +
12918 +// The 'llvm.pow.*' intrinsics return the first operand raised to the specified (positive or negative) power.
12919 +
12920 +pragma(intrinsic, "llvm.pow.f32")
12921 + float llvm_pow_f32(float val, float power);
12922 +
12923 +pragma(intrinsic, "llvm.pow.f64")
12924 + double llvm_pow_f64(double val, double power);
12925 +version(X86)
12926 +{
12927 +pragma(intrinsic, "llvm.pow.f80")
12928 + real llvm_pow_f80(real val, real power);
12929 +}
12930 +
12931 +version(X86_64)
12932 +{
12933 +pragma(intrinsic, "llvm.pow.f80")
12934 + real llvm_pow_f80(real val, real power);
12935 +}
12936 +
12937 +
12938 +//
12939 +// BIT MANIPULATION INTRINSICS
12940 +//
12941 +
12942 +// The 'llvm.bswap' family of intrinsics is used to byte swap integer values with an even number of bytes (positive multiple of 16 bits). These are useful for performing operations on data that is not in the target's native byte order.
12943 +
12944 +pragma(intrinsic, "llvm.bswap.i16.i16")
12945 + ushort llvm_bswap_i16(ushort val);
12946 +
12947 +pragma(intrinsic, "llvm.bswap.i32.i32")
12948 + uint llvm_bswap_i32(uint val);
12949 +
12950 +pragma(intrinsic, "llvm.bswap.i64.i64")
12951 + ulong llvm_bswap_i64(ulong val);
12952 +
12953 +
12954 +// The 'llvm.ctpop' family of intrinsics counts the number of bits set in a value.
12955 +
12956 +pragma(intrinsic, "llvm.ctpop.i8")
12957 + ubyte llvm_ctpop_i8(ubyte src);
12958 +
12959 +pragma(intrinsic, "llvm.ctpop.i16")
12960 + ushort llvm_ctpop_i16(ushort src);
12961 +
12962 +pragma(intrinsic, "llvm.ctpop.i32")
12963 + uint llvm_ctpop_i32(uint src);
12964 +
12965 +pragma(intrinsic, "llvm.ctpop.i64")
12966 + ulong llvm_ctpop_i64(ulong src);
12967 +
12968 +
12969 +// The 'llvm.ctlz' family of intrinsic functions counts the number of leading zeros in a variable.
12970 +
12971 +pragma(intrinsic, "llvm.ctlz.i8")
12972 + ubyte llvm_ctlz_i8(ubyte src);
12973 +
12974 +pragma(intrinsic, "llvm.ctlz.i16")
12975 + ushort llvm_ctlz_i16(ushort src);
12976 +
12977 +pragma(intrinsic, "llvm.ctlz.i32")
12978 + uint llvm_ctlz_i32(uint src);
12979 +
12980 +pragma(intrinsic, "llvm.ctlz.i64")
12981 + ulong llvm_ctlz_i64(ulong src);
12982 +
12983 +
12984 +// The 'llvm.cttz' family of intrinsic functions counts the number of trailing zeros.
12985 +
12986 +pragma(intrinsic, "llvm.cttz.i8")
12987 + ubyte llvm_cttz_i8(ubyte src);
12988 +
12989 +pragma(intrinsic, "llvm.cttz.i16")
12990 + ushort llvm_cttz_i16(ushort src);
12991 +
12992 +pragma(intrinsic, "llvm.cttz.i32")
12993 + uint llvm_cttz_i32(uint src);
12994 +
12995 +pragma(intrinsic, "llvm.cttz.i64")
12996 + ulong llvm_cttz_i64(ulong src);
12997 +
12998 +
12999 +// The 'llvm.part.select' family of intrinsic functions selects a range of bits from an integer value and returns them in the same bit width as the original value.
13000 +
13001 +pragma(intrinsic, "llvm.part.select.i8")
13002 + ubyte llvm_part_select_i(ubyte val, uint loBit, uint hiBit);
13003 +
13004 +pragma(intrinsic, "llvm.part.select.i16")
13005 + ushort llvm_part_select_i(ushort val, uint loBit, uint hiBit);
13006 +
13007 +pragma(intrinsic, "llvm.part.select.i32")
13008 + uint llvm_part_select_i(uint val, uint loBit, uint hiBit);
13009 +
13010 +pragma(intrinsic, "llvm.part.select.i64")
13011 + ulong llvm_part_select_i(ulong val, uint loBit, uint hiBit);
13012 +
13013 +
13014 +// The 'llvm.part.set' family of intrinsic functions replaces a range of bits in an integer value with another integer value. It returns the integer with the replaced bits.
13015 +
13016 +// TODO
13017 +// declare i17 @llvm.part.set.i17.i9 (i17 %val, i9 %repl, i32 %lo, i32 %hi)
13018 +// declare i29 @llvm.part.set.i29.i9 (i29 %val, i9 %repl, i32 %lo, i32 %hi)
13019 +
13020 +
13021 +
13022 +
13023 +//
13024 +// ATOMIC OPERATIONS AND SYNCHRONIZATION INTRINSICS
13025 +//
13026 +
13027 +// The llvm.memory.barrier intrinsic guarantees ordering between specific pairs of memory access types.
13028 +
13029 +pragma(intrinsic, "llvm.memory.barrier")
13030 + void llvm_memory_barrier(bool ll, bool ls, bool sl, bool ss, bool device);
13031 +
13032 +// This loads a value in memory and compares it to a given value. If they are equal, it stores a new value into the memory.
13033 +
13034 +pragma(intrinsic, "llvm.atomic.cmp.swap.i#.p0i#")
13035 + T llvm_atomic_cmp_swap(T)(T* ptr, T cmp, T val);
13036 +
13037 +// This intrinsic loads the value stored in memory at ptr and yields the value from memory. It then stores the value in val in the memory at ptr.
13038 +
13039 +pragma(intrinsic, "llvm.atomic.swap.i#.p0i#")
13040 + T llvm_atomic_swap(T)(T* ptr, T val);
13041 +
13042 +// This intrinsic adds delta to the value stored in memory at ptr. It yields the original value at ptr.
13043 +
13044 +pragma(intrinsic, "llvm.atomic.load.add.i#.p0i#")
13045 + T llvm_atomic_load_add(T)(T* ptr, T val);
13046 +
13047 +// This intrinsic subtracts delta to the value stored in memory at ptr. It yields the original value at ptr.
13048 +
13049 +pragma(intrinsic, "llvm.atomic.load.sub.i#.p0i#")
13050 + T llvm_atomic_load_sub(T)(T* ptr, T val);
13051 +
13052 +// These intrinsics bitwise the operation (and, nand, or, xor) delta to the value stored in memory at ptr. It yields the original value at ptr.
13053 +
13054 +pragma(intrinsic, "llvm.atomic.load.and.i#.p0i#")
13055 + T llvm_atomic_load_and(T)(T* ptr, T val);
13056 +pragma(intrinsic, "llvm.atomic.load.nand.i#.p0i#")
13057 + T llvm_atomic_load_nand(T)(T* ptr, T val);
13058 +pragma(intrinsic, "llvm.atomic.load.or.i#.p0i#")
13059 + T llvm_atomic_load_or(T)(T* ptr, T val);
13060 +pragma(intrinsic, "llvm.atomic.load.xor.i#.p0i#")
13061 + T llvm_atomic_load_xor(T)(T* ptr, T val);
13062 +
13063 +// These intrinsics takes the signed or unsigned minimum or maximum of delta and the value stored in memory at ptr. It yields the original value at ptr.
13064 +
13065 +pragma(intrinsic, "llvm.atomic.load.max.i#.p0i#")
13066 + T llvm_atomic_load_max(T)(T* ptr, T val);
13067 +pragma(intrinsic, "llvm.atomic.load.min.i#.p0i#")
13068 + T llvm_atomic_load_min(T)(T* ptr, T val);
13069 +pragma(intrinsic, "llvm.atomic.load.umax.i#.p0i#")
13070 + T llvm_atomic_load_umax(T)(T* ptr, T val);
13071 +pragma(intrinsic, "llvm.atomic.load.umin.i#.p0i#")
13072 + T llvm_atomic_load_umin(T)(T* ptr, T val);
13073 +
13074 +//
13075 +// GENERAL INTRINSICS
13076 +//
13077 +
13078 +
13079 +// This intrinsics is lowered to the target dependent trap instruction. If the target does not have a trap instruction, this intrinsic will be lowered to the call of the abort() function.
13080 +
13081 +pragma(intrinsic, "llvm.trap")
13082 + void llvm_trap();
13083 Index: import/ldc/cstdarg.di
13084 ===================================================================
13085 --- import/ldc/cstdarg.di (revision 0)
13086 +++ import/ldc/cstdarg.di (revision 0)
13087 @@ -0,0 +1,29 @@
13088 +/*
13089 + * vararg support for extern(C) functions
13090 + */
13091 +
13092 +module ldc.cstdarg;
13093 +
13094 +// Check for the right compiler
13095 +version(LDC)
13096 +{
13097 + // OK
13098 +}
13099 +else
13100 +{
13101 + static assert(false, "This module is only valid for LDC");
13102 +}
13103 +
13104 +alias void* va_list;
13105 +
13106 +pragma(va_start)
13107 + void va_start(T)(va_list ap, ref T);
13108 +
13109 +pragma(va_arg)
13110 + T va_arg(T)(va_list ap);
13111 +
13112 +pragma(va_end)
13113 + void va_end(va_list args);
13114 +
13115 +pragma(va_copy)
13116 + void va_copy(va_list dst, va_list src);
13117 Index: import/core/stdc/stdarg.d
13118 ===================================================================
13119 --- import/core/stdc/stdarg.d (revision 46)
13120 +++ import/core/stdc/stdarg.d (working copy)
13121 @@ -9,8 +9,12 @@
13122 module core.stdc.stdarg;
13123
13124
13125 -version( GNU )
13126 +version( LDC )
13127 {
13128 + public import ldc.cstdarg;
13129 +}
13130 +else version( GNU )
13131 +{
13132 public import std.c.stdarg;
13133 }
13134 else
13135 Index: import/core/bitmanip.di
13136 ===================================================================
13137 --- import/core/bitmanip.di (revision 46)
13138 +++ import/core/bitmanip.di (working copy)
13139 @@ -171,6 +171,10 @@
13140 */
13141 uint outpl( uint port_address, uint value );
13142 }
13143 +else version( LDC )
13144 +{
13145 + public import ldc.bitmanip;
13146 +}
13147 else
13148 {
13149 public import std.intrinsic;