comparison runtime/ldc2.diff @ 768:85e2093edd73

Updated runtime README a bit. Messed up the druntime patch earlier :/
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 12 Nov 2008 06:26:45 +0100
parents eb1ce70ee01c
children 038ea84f2d9d
comparison
equal deleted inserted replaced
767:eb1ce70ee01c 768:85e2093edd73
175 + } 175 + }
176 ++/ 176 ++/
177 else version( AsmPPC_Posix ) 177 else version( AsmPPC_Posix )
178 { 178 {
179 version( StackGrowsDown ) 179 version( StackGrowsDown )
180 Index: src/common/ldc.mak
181 ===================================================================
182 --- src/common/ldc.mak (revision 0)
183 +++ src/common/ldc.mak (revision 0)
184 @@ -0,0 +1,139 @@
185 +# Makefile to build the D runtime library core components for Posix
186 +# Designed to work with GNU make
187 +# Targets:
188 +# make
189 +# Same as make all
190 +# make lib
191 +# Build the common library
192 +# make doc
193 +# Generate documentation
194 +# make clean
195 +# Delete unneeded files created by build process
196 +
197 +LIB_TARGET=libdruntime-core.a
198 +LIB_MASK=libdruntime-core*.a
199 +
200 +CP=cp -f
201 +RM=rm -f
202 +MD=mkdir -p
203 +
204 +ADD_CFLAGS=
205 +ADD_DFLAGS=
206 +
207 +#CFLAGS=-O $(ADD_CFLAGS)
208 +CFLAGS=-g $(ADD_CFLAGS)
209 +
210 +#DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
211 +DFLAGS=-g -w $(ADD_DFLAGS)
212 +
213 +#TFLAGS=-O -inline -w $(ADD_DFLAGS)
214 +TFLAGS=-g -w $(ADD_DFLAGS)
215 +
216 +DOCFLAGS=-version=DDoc
217 +
218 +CC=gcc
219 +LC=$(AR) -qsv
220 +DC=ldc2
221 +
222 +INC_DEST=../../import
223 +LIB_DEST=../../lib
224 +DOC_DEST=../../doc
225 +
226 +.SUFFIXES: .s .S .c .cpp .d .html .o
227 +
228 +.s.o:
229 + $(CC) -c $(CFLAGS) $< -o$@
230 +
231 +.S.o:
232 + $(CC) -c $(CFLAGS) $< -o$@
233 +
234 +.c.o:
235 + $(CC) -c $(CFLAGS) $< -o$@
236 +
237 +.cpp.o:
238 + g++ -c $(CFLAGS) $< -o$@
239 +
240 +.d.o:
241 + $(DC) -c $(DFLAGS) -Hf$*.di $< -of$@
242 +# $(DC) -c $(DFLAGS) $< -of$@
243 +
244 +.d.html:
245 + $(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
246 +
247 +targets : lib doc
248 +all : lib doc
249 +core : lib
250 +lib : core.lib
251 +doc : core.doc
252 +
253 +######################################################
254 +
255 +OBJ_CORE= \
256 + core/bitmanip.o \
257 + core/exception.o \
258 + core/memory_.o \
259 + core/runtime.o \
260 + core/thread.o
261 +
262 +OBJ_STDC= \
263 + core/stdc/errno.o
264 +
265 +ALL_OBJS= \
266 + $(OBJ_CORE) \
267 + $(OBJ_STDC)
268 +
269 +######################################################
270 +
271 +DOC_CORE= \
272 + core/bitmanip.html \
273 + core/exception.html \
274 + core/memory.html \
275 + core/runtime.html \
276 + core/thread.html
277 +
278 +
279 +ALL_DOCS=
280 +
281 +######################################################
282 +
283 +core.lib : $(LIB_TARGET)
284 +
285 +$(LIB_TARGET) : $(ALL_OBJS)
286 + $(RM) $@
287 + $(LC) $@ $(ALL_OBJS)
288 +
289 +core.doc : $(ALL_DOCS)
290 + echo Documentation generated.
291 +
292 +######################################################
293 +
294 +### bitmanip
295 +
296 +core/bitmanip.o : core/bitmanip.d
297 + $(DC) -c $(DFLAGS) core/bitmanip.d -of$@
298 +
299 +### memory
300 +
301 +core/memory_.o : core/memory.d
302 + $(DC) -c $(DFLAGS) -Hf$*.di $< -of$@
303 +
304 +### thread
305 +
306 +core/thread.o : core/thread.d
307 + $(DC) -c $(DFLAGS) -d -Hf$*.di core/thread.d -of$@
308 +
309 +######################################################
310 +
311 +clean :
312 + find . -name "*.di" | xargs $(RM)
313 + $(RM) $(ALL_OBJS)
314 + $(RM) $(ALL_DOCS)
315 + find . -name "$(LIB_MASK)" | xargs $(RM)
316 +
317 +install :
318 + $(MD) $(INC_DEST)
319 + find . -name "*.di" -exec cp -f {} $(INC_DEST)/{} \;
320 + $(MD) $(DOC_DEST)
321 + find . -name "*.html" -exec cp -f {} $(DOC_DEST)/{} \;
322 + $(MD) $(LIB_DEST)
323 + find . -name "$(LIB_MASK)" -exec cp -f {} $(LIB_DEST)/{} \;
324 Index: src/build-ldc.sh
325 ===================================================================
326 --- src/build-ldc.sh (revision 0)
327 +++ src/build-ldc.sh (revision 0)
328 @@ -0,0 +1,19 @@
329 +#!/usr/bin/env bash
330 +
331 +OLDHOME=$HOME
332 +export HOME=`pwd`
333 +
334 +goerror(){
335 + export HOME=$OLDHOME
336 + echo "="
337 + echo "= *** Error ***"
338 + echo "="
339 + exit 1
340 +}
341 +
342 +make clean -fldc.mak || goerror
343 +make lib doc install -fldc.mak $@ || goerror
344 +make clean -fldc.mak || goerror
345 +chmod 644 ../import/*.di || goerror
346 +
347 +export HOME=$OLDHOME
348 Index: src/ldc2.conf
349 ===================================================================
350 --- src/ldc2.conf (revision 0)
351 +++ src/ldc2.conf (revision 0)
352 @@ -0,0 +1,2 @@
353 +[Environment]
354 +DFLAGS="-I%HOME%/common" "-I%HOME%/../import"
180 Index: src/gc/basic/gcx.d 355 Index: src/gc/basic/gcx.d
181 =================================================================== 356 ===================================================================
182 --- src/gc/basic/gcx.d (revision 46) 357 --- src/gc/basic/gcx.d (revision 46)
183 +++ src/gc/basic/gcx.d (working copy) 358 +++ src/gc/basic/gcx.d (working copy)
184 @@ -55,7 +55,11 @@ 359 @@ -55,7 +55,11 @@
228 - (cast(byte*)&this)[0 .. Gcx.sizeof] = 0; 403 - (cast(byte*)&this)[0 .. Gcx.sizeof] = 0;
229 + (cast(byte*)this)[0 .. Gcx.sizeof] = 0; 404 + (cast(byte*)this)[0 .. Gcx.sizeof] = 0;
230 stackBottom = cast(char*)&dummy; 405 stackBottom = cast(char*)&dummy;
231 log_init(); 406 log_init();
232 debug (THREADINVARIANT) 407 debug (THREADINVARIANT)
408 Index: src/gc/basic/ldc.mak
409 ===================================================================
410 --- src/gc/basic/ldc.mak (revision 0)
411 +++ src/gc/basic/ldc.mak (revision 0)
412 @@ -0,0 +1,100 @@
413 +# Makefile to build the garbage collector D library for Posix
414 +# Designed to work with GNU make
415 +# Targets:
416 +# make
417 +# Same as make all
418 +# make lib
419 +# Build the garbage collector library
420 +# make doc
421 +# Generate documentation
422 +# make clean
423 +# Delete unneeded files created by build process
424 +
425 +LIB_TARGET=libdruntime-gc-basic.a
426 +LIB_MASK=libdruntime-gc-basic*.a
427 +
428 +CP=cp -f
429 +RM=rm -f
430 +MD=mkdir -p
431 +
432 +ADD_CFLAGS=
433 +ADD_DFLAGS=
434 +
435 +#CFLAGS=-O $(ADD_CFLAGS)
436 +CFLAGS=-g $(ADD_CFLAGS)
437 +
438 +#DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
439 +DFLAGS=-g -w -disable-invariants $(ADD_DFLAGS)
440 +
441 +#TFLAGS=-O -inline -w $(ADD_DFLAGS)
442 +TFLAGS=-g -w $(ADD_DFLAGS)
443 +
444 +DOCFLAGS=-version=DDoc
445 +
446 +CC=gcc
447 +LC=$(AR) -qsv
448 +DC=ldc2
449 +
450 +LIB_DEST=../../../lib
451 +
452 +.SUFFIXES: .s .S .c .cpp .d .html .o
453 +
454 +.s.o:
455 + $(CC) -c $(CFLAGS) $< -o$@
456 +
457 +.S.o:
458 + $(CC) -c $(CFLAGS) $< -o$@
459 +
460 +.c.o:
461 + $(CC) -c $(CFLAGS) $< -o$@
462 +
463 +.cpp.o:
464 + g++ -c $(CFLAGS) $< -o$@
465 +
466 +.d.o:
467 + $(DC) -c $(DFLAGS) $< -of$@
468 +
469 +.d.html:
470 + $(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
471 +# $(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
472 +
473 +targets : lib doc
474 +all : lib doc
475 +lib : basic.lib
476 +doc : basic.doc
477 +
478 +######################################################
479 +
480 +ALL_OBJS= \
481 + gc.o \
482 + gcalloc.o \
483 + gcbits.o \
484 + gcstats.o \
485 + gcx.o
486 +
487 +######################################################
488 +
489 +ALL_DOCS=
490 +
491 +######################################################
492 +
493 +basic.lib : $(LIB_TARGET)
494 +
495 +$(LIB_TARGET) : $(ALL_OBJS)
496 + $(RM) $@
497 + $(LC) $@ $(ALL_OBJS)
498 +
499 +basic.doc : $(ALL_DOCS)
500 + echo No documentation available.
501 +
502 +######################################################
503 +
504 +clean :
505 + find . -name "*.di" | xargs $(RM)
506 + $(RM) $(ALL_OBJS)
507 + $(RM) $(ALL_DOCS)
508 + $(RM) $(LIB_MASK)
509 +
510 +install :
511 + $(MD) $(LIB_DEST)
512 + $(CP) $(LIB_MASK) $(LIB_DEST)/.
513 Index: src/gc/stub/ldc.mak
514 ===================================================================
515 --- src/gc/stub/ldc.mak (revision 0)
516 +++ src/gc/stub/ldc.mak (revision 0)
517 @@ -0,0 +1,97 @@
518 +# Makefile to build the garbage collector D library for Posix
519 +# Designed to work with GNU make
520 +# Targets:
521 +# make
522 +# Same as make all
523 +# make lib
524 +# Build the garbage collector library
525 +# make doc
526 +# Generate documentation
527 +# make clean
528 +# Delete unneeded files created by build process
529 +
530 +LIB_TARGET=libdruntime-gc-stub.a
531 +LIB_MASK=libdruntime-gc-stub*.a
532 +
533 +CP=cp -f
534 +RM=rm -f
535 +MD=mkdir -p
536 +
537 +ADD_CFLAGS=
538 +ADD_DFLAGS=
539 +
540 +CFLAGS=-O $(ADD_CFLAGS)
541 +#CFLAGS=-g $(ADD_CFLAGS)
542 +
543 +#DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
544 +DFLAGS=-g -w $(ADD_DFLAGS)
545 +
546 +
547 +#TFLAGS=-O -inline -w $(ADD_DFLAGS)
548 +TFLAGS=-g -w $(ADD_DFLAGS)
549 +
550 +DOCFLAGS=-version=DDoc
551 +
552 +CC=gcc
553 +LC=$(AR) -qsv
554 +DC=ldc2
555 +
556 +LIB_DEST=../../../lib
557 +
558 +.SUFFIXES: .s .S .c .cpp .d .html .o
559 +
560 +.s.o:
561 + $(CC) -c $(CFLAGS) $< -o$@
562 +
563 +.S.o:
564 + $(CC) -c $(CFLAGS) $< -o$@
565 +
566 +.c.o:
567 + $(CC) -c $(CFLAGS) $< -o$@
568 +
569 +.cpp.o:
570 + g++ -c $(CFLAGS) $< -o$@
571 +
572 +.d.o:
573 + $(DC) -c $(DFLAGS) $< -of$@
574 +
575 +.d.html:
576 + $(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
577 +# $(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
578 +
579 +targets : lib doc
580 +all : lib doc
581 +lib : stub.lib
582 +doc : stub.doc
583 +
584 +######################################################
585 +
586 +ALL_OBJS= \
587 + gc.o
588 +
589 +######################################################
590 +
591 +ALL_DOCS=
592 +
593 +######################################################
594 +
595 +stub.lib : $(LIB_TARGET)
596 +
597 +$(LIB_TARGET) : $(ALL_OBJS)
598 + $(RM) $@
599 + $(LC) $@ $(ALL_OBJS)
600 +
601 +stub.doc : $(ALL_DOCS)
602 + echo No documentation available.
603 +
604 +######################################################
605 +
606 +clean :
607 + find . -name "*.di" | xargs $(RM)
608 + $(RM) $(ALL_OBJS)
609 + $(RM) $(ALL_DOCS)
610 + $(RM) $(LIB_MASK)
611 +
612 +install :
613 + $(MD) $(LIB_DEST)
614 + $(CP) $(LIB_MASK) $(LIB_DEST)/.
615 Index: src/compiler/ldc/adi.d
616 ===================================================================
617 --- src/compiler/ldc/adi.d (revision 0)
618 +++ src/compiler/ldc/adi.d (revision 0)
619 @@ -0,0 +1,602 @@
620 +//_ adi.d
621 +
622 +/**
623 + * Part of the D programming language runtime library.
624 + * Dynamic array property support routines
625 + */
626 +
627 +/*
628 + * Copyright (C) 2000-2006 by Digital Mars, www.digitalmars.com
629 + * Written by Walter Bright
630 + *
631 + * This software is provided 'as-is', without any express or implied
632 + * warranty. In no event will the authors be held liable for any damages
633 + * arising from the use of this software.
634 + *
635 + * Permission is granted to anyone to use this software for any purpose,
636 + * including commercial applications, and to alter it and redistribute it
637 + * freely, in both source and binary form, subject to the following
638 + * restrictions:
639 + *
640 + * o The origin of this software must not be misrepresented; you must not
641 + * claim that you wrote the original software. If you use this software
642 + * in a product, an acknowledgment in the product documentation would be
643 + * appreciated but is not required.
644 + * o Altered source versions must be plainly marked as such, and must not
645 + * be misrepresented as being the original software.
646 + * o This notice may not be removed or altered from any source
647 + * distribution.
648 + */
649 +
650 +/*
651 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
652 + */
653 +
654 +
655 +//debug=adi; // uncomment to turn on debugging printf's
656 +
657 +private
658 +{
659 + version( D_Version2 )
660 + {
661 + import core.stdc.stdlib;
662 + import core.stdc.string;
663 + }
664 + else
665 + {
666 + import tango.stdc.stdlib;
667 + import tango.stdc.string;
668 + }
669 + import util.utf;
670 +
671 + enum BlkAttr : uint
672 + {
673 + FINALIZE = 0b0000_0001,
674 + NO_SCAN = 0b0000_0010,
675 + NO_MOVE = 0b0000_0100,
676 + ALL_BITS = 0b1111_1111
677 + }
678 +
679 + extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
680 + extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
681 + extern (C) void gc_free( void* p );
682 +}
683 +
684 +
685 +/**********************************************
686 + * Reverse array of chars.
687 + * Handled separately because embedded multibyte encodings should not be
688 + * reversed.
689 + */
690 +
691 +extern (C) char[] _adReverseChar(char[] a)
692 +{
693 + if (a.length > 1)
694 + {
695 + char[6] tmp;
696 + char[6] tmplo;
697 + char* lo = a.ptr;
698 + char* hi = &a[length - 1];
699 +
700 + while (lo < hi)
701 + { auto clo = *lo;
702 + auto chi = *hi;
703 +
704 + debug(adi) printf("lo = %d, hi = %d\n", lo, hi);
705 + if (clo <= 0x7F && chi <= 0x7F)
706 + {
707 + debug(adi) printf("\tascii\n");
708 + *lo = chi;
709 + *hi = clo;
710 + lo++;
711 + hi--;
712 + continue;
713 + }
714 +
715 + uint stridelo = UTF8stride[clo];
716 + // don't barf on invalid strides, just ignore it
717 + if (stridelo == 0xFF)
718 + stridelo = 1;
719 +
720 + uint stridehi = 1;
721 + while ((chi & 0xC0) == 0x80)
722 + {
723 + chi = *--hi;
724 + stridehi++;
725 + assert(hi >= lo);
726 + }
727 + if (lo == hi)
728 + break;
729 +
730 + debug(adi) printf("\tstridelo = %d, stridehi = %d\n", stridelo, stridehi);
731 + if (stridelo == stridehi)
732 + {
733 +
734 + memcpy(tmp.ptr, lo, stridelo);
735 + memcpy(lo, hi, stridelo);
736 + memcpy(hi, tmp.ptr, stridelo);
737 + lo += stridelo;
738 + hi--;
739 + continue;
740 + }
741 +
742 + /* Shift the whole array. This is woefully inefficient
743 + */
744 + memcpy(tmp.ptr, hi, stridehi);
745 + memcpy(tmplo.ptr, lo, stridelo);
746 + memmove(lo + stridehi, lo + stridelo , cast(size_t)(hi - lo) - stridelo);
747 + memcpy(lo, tmp.ptr, stridehi);
748 + memcpy(hi + stridehi - stridelo, tmplo.ptr, stridelo);
749 +
750 + lo += stridehi;
751 + hi = hi - 1 + (stridehi - stridelo);
752 + }
753 + }
754 + return a;
755 +}
756 +
757 +unittest
758 +{
759 + char[] a = "abcd"c;
760 +
761 + char[] r = a.dup.reverse;
762 + //writefln(r);
763 + assert(r == "dcba");
764 +
765 + a = "a\u1235\u1234c";
766 + //writefln(a);
767 + r = a.dup.reverse;
768 + //writefln(r);
769 + assert(r == "c\u1234\u1235a");
770 +
771 + a = "ab\u1234c";
772 + //writefln(a);
773 + r = a.dup.reverse;
774 + //writefln(r);
775 + assert(r == "c\u1234ba");
776 +
777 + a = "\u3026\u2021\u3061\n";
778 + r = a.dup.reverse;
779 + assert(r == "\n\u3061\u2021\u3026");
780 +}
781 +
782 +
783 +/**********************************************
784 + * Reverse array of wchars.
785 + * Handled separately because embedded multiword encodings should not be
786 + * reversed.
787 + */
788 +
789 +extern (C) wchar[] _adReverseWchar(wchar[] a)
790 +{
791 + if (a.length > 1)
792 + {
793 + wchar[2] tmp;
794 + wchar* lo = a.ptr;
795 + wchar* hi = &a[length - 1];
796 +
797 + while (lo < hi)
798 + { auto clo = *lo;
799 + auto chi = *hi;
800 +
801 + if ((clo < 0xD800 || clo > 0xDFFF) &&
802 + (chi < 0xD800 || chi > 0xDFFF))
803 + {
804 + *lo = chi;
805 + *hi = clo;
806 + lo++;
807 + hi--;
808 + continue;
809 + }
810 +
811 + int stridelo = 1 + (clo >= 0xD800 && clo <= 0xDBFF);
812 +
813 + int stridehi = 1;
814 + if (chi >= 0xDC00 && chi <= 0xDFFF)
815 + {
816 + chi = *--hi;
817 + stridehi++;
818 + assert(hi >= lo);
819 + }
820 + if (lo == hi)
821 + break;
822 +
823 + if (stridelo == stridehi)
824 + { int stmp;
825 +
826 + assert(stridelo == 2);
827 + assert(stmp.sizeof == 2 * (*lo).sizeof);
828 + stmp = *cast(int*)lo;
829 + *cast(int*)lo = *cast(int*)hi;
830 + *cast(int*)hi = stmp;
831 + lo += stridelo;
832 + hi--;
833 + continue;
834 + }
835 +
836 + /* Shift the whole array. This is woefully inefficient
837 + */
838 + memcpy(tmp.ptr, hi, stridehi * wchar.sizeof);
839 + memcpy(hi + stridehi - stridelo, lo, stridelo * wchar.sizeof);
840 + memmove(lo + stridehi, lo + stridelo , (hi - (lo + stridelo)) * wchar.sizeof);
841 + memcpy(lo, tmp.ptr, stridehi * wchar.sizeof);
842 +
843 + lo += stridehi;
844 + hi = hi - 1 + (stridehi - stridelo);
845 + }
846 + }
847 + return a;
848 +}
849 +
850 +unittest
851 +{
852 + wchar[] a = "abcd";
853 + wchar[] r;
854 +
855 + r = a.dup.reverse;
856 + assert(r == "dcba");
857 +
858 + a = "a\U00012356\U00012346c";
859 + r = a.dup.reverse;
860 + assert(r == "c\U00012346\U00012356a");
861 +
862 + a = "ab\U00012345c";
863 + r = a.dup.reverse;
864 + assert(r == "c\U00012345ba");
865 +}
866 +
867 +
868 +/**********************************************
869 + * Support for array.reverse property.
870 + * The actual type is painted on the return value by the frontend
871 + * Given and returned length are number of elements
872 + */
873 +
874 +extern (C) void[] _adReverse(void[] a, size_t szelem)
875 + out (result)
876 + {
877 + assert(result.ptr is a.ptr);
878 + }
879 + body
880 + {
881 + if (a.length >= 2)
882 + {
883 + byte* tmp;
884 + byte[16] buffer;
885 +
886 + void* lo = a.ptr;
887 + void* hi = a.ptr + (a.length - 1) * szelem;
888 +
889 + tmp = buffer.ptr;
890 + if (szelem > 16)
891 + {
892 + //version (Win32)
893 + //tmp = cast(byte*) alloca(szelem);
894 + //else
895 + tmp = cast(byte*) gc_malloc(szelem);
896 + }
897 +
898 + for (; lo < hi; lo += szelem, hi -= szelem)
899 + {
900 + memcpy(tmp, lo, szelem);
901 + memcpy(lo, hi, szelem);
902 + memcpy(hi, tmp, szelem);
903 + }
904 +
905 + version (Win32)
906 + {
907 + }
908 + else
909 + {
910 + //if (szelem > 16)
911 + // BUG: bad code is generate for delete pointer, tries
912 + // to call delclass.
913 + //gc_free(tmp);
914 + }
915 + }
916 + return a.ptr[0 .. a.length];
917 + }
918 +
919 +unittest
920 +{
921 + debug(adi) printf("array.reverse.unittest\n");
922 +
923 + int[] a = new int[5];
924 + int[] b;
925 + size_t i;
926 +
927 + for (i = 0; i < 5; i++)
928 + a[i] = i;
929 + b = a.reverse;
930 + assert(b is a);
931 + for (i = 0; i < 5; i++)
932 + assert(a[i] == 4 - i);
933 +
934 + struct X20
935 + { // More than 16 bytes in size
936 + int a;
937 + int b, c, d, e;
938 + }
939 +
940 + X20[] c = new X20[5];
941 + X20[] d;
942 +
943 + for (i = 0; i < 5; i++)
944 + { c[i].a = i;
945 + c[i].e = 10;
946 + }
947 + d = c.reverse;
948 + assert(d is c);
949 + for (i = 0; i < 5; i++)
950 + {
951 + assert(c[i].a == 4 - i);
952 + assert(c[i].e == 10);
953 + }
954 +}
955 +
956 +/**********************************************
957 + * Sort array of chars.
958 + */
959 +
960 +extern (C) char[] _adSortChar(char[] a)
961 +{
962 + if (a.length > 1)
963 + {
964 + dstring da = toUTF32(a);
965 + da.sort;
966 + size_t i = 0;
967 + foreach (dchar d; da)
968 + { char[4] buf;
969 + auto t = toUTF8(buf, d);
970 + a[i .. i + t.length] = t[];
971 + i += t.length;
972 + }
973 + delete da;
974 + }
975 + return a;
976 +}
977 +
978 +/**********************************************
979 + * Sort array of wchars.
980 + */
981 +
982 +extern (C) wchar[] _adSortWchar(wchar[] a)
983 +{
984 + if (a.length > 1)
985 + {
986 + dstring da = toUTF32(a);
987 + da.sort;
988 + size_t i = 0;
989 + foreach (dchar d; da)
990 + { wchar[2] buf;
991 + auto t = toUTF16(buf, d);
992 + a[i .. i + t.length] = t[];
993 + i += t.length;
994 + }
995 + delete da;
996 + }
997 + return a;
998 +}
999 +
1000 +/***************************************
1001 + * Support for array equality test.
1002 + * The actual type is painted on the return value by the frontend
1003 + * Given lengths are number of elements
1004 + */
1005 +
1006 +extern (C) int _adEq(void[] a1, void[] a2, TypeInfo ti)
1007 +{
1008 + debug(adi) printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
1009 +
1010 + if (a1.length != a2.length)
1011 + return 0; // not equal
1012 + else if (a1.ptr == a2.ptr)
1013 + return 1; // equal
1014 +
1015 + // let typeinfo decide
1016 + return ti.equals(&a1, &a2);
1017 +}
1018 +
1019 +unittest
1020 +{
1021 + debug(adi) printf("array.Eq unittest\n");
1022 +
1023 + char[] a = "hello"c;
1024 +
1025 + assert(a != "hel");
1026 + assert(a != "helloo");
1027 + assert(a != "betty");
1028 + assert(a == "hello");
1029 + assert(a != "hxxxx");
1030 +}
1031 +
1032 +/***************************************
1033 + * Support for array compare test.
1034 + * The actual type is painted on the return value by the frontend
1035 + * Given lengths are number of elements
1036 + */
1037 +
1038 +extern (C) int _adCmp(void[] a1, void[] a2, TypeInfo ti)
1039 +{
1040 + debug(adi) printf("adCmp()\n");
1041 +
1042 + if (a1.ptr == a2.ptr &&
1043 + a1.length == a2.length)
1044 + return 0;
1045 +
1046 + auto len = a1.length;
1047 + if (a2.length < len)
1048 + len = a2.length;
1049 +
1050 + // let typeinfo decide
1051 + return ti.compare(&a1, &a2);
1052 +}
1053 +
1054 +unittest
1055 +{
1056 + debug(adi) printf("array.Cmp unittest\n");
1057 +
1058 + char[] a = "hello"c;
1059 +
1060 + assert(a > "hel");
1061 + assert(a >= "hel");
1062 + assert(a < "helloo");
1063 + assert(a <= "helloo");
1064 + assert(a > "betty");
1065 + assert(a >= "betty");
1066 + assert(a == "hello");
1067 + assert(a <= "hello");
1068 + assert(a >= "hello");
1069 +}
1070 +
1071 +/***************************************
1072 + * Support for array compare test.
1073 + * The actual type is painted on the return value by the frontend
1074 + * Given lengths are number of elements
1075 + */
1076 +
1077 +extern (C) int _adCmpChar(void[] a1, void[] a2)
1078 +{
1079 + version(D_InlineAsm_X86)
1080 + {
1081 + //version = Asm86;
1082 + }
1083 + version (Asm86)
1084 + {
1085 + asm
1086 + { naked ;
1087 +
1088 + push EDI ;
1089 + push ESI ;
1090 +
1091 + mov ESI,a1+4[4+ESP] ;
1092 + mov EDI,a2+4[4+ESP] ;
1093 +
1094 + mov ECX,a1[4+ESP] ;
1095 + mov EDX,a2[4+ESP] ;
1096 +
1097 + cmp ECX,EDX ;
1098 + jb GotLength ;
1099 +
1100 + mov ECX,EDX ;
1101 +
1102 +GotLength:
1103 + cmp ECX,4 ;
1104 + jb DoBytes ;
1105 +
1106 + // Do alignment if neither is dword aligned
1107 + test ESI,3 ;
1108 + jz Aligned ;
1109 +
1110 + test EDI,3 ;
1111 + jz Aligned ;
1112 +DoAlign:
1113 + mov AL,[ESI] ; //align ESI to dword bounds
1114 + mov DL,[EDI] ;
1115 +
1116 + cmp AL,DL ;
1117 + jnz Unequal ;
1118 +
1119 + inc ESI ;
1120 + inc EDI ;
1121 +
1122 + test ESI,3 ;
1123 +
1124 + lea ECX,[ECX-1] ;
1125 + jnz DoAlign ;
1126 +Aligned:
1127 + mov EAX,ECX ;
1128 +
1129 + // do multiple of 4 bytes at a time
1130 +
1131 + shr ECX,2 ;
1132 + jz TryOdd ;
1133 +
1134 + repe ;
1135 + cmpsd ;
1136 +
1137 + jnz UnequalQuad ;
1138 +
1139 +TryOdd:
1140 + mov ECX,EAX ;
1141 +DoBytes:
1142 + // if still equal and not end of string, do up to 3 bytes slightly
1143 + // slower.
1144 +
1145 + and ECX,3 ;
1146 + jz Equal ;
1147 +
1148 + repe ;
1149 + cmpsb ;
1150 +
1151 + jnz Unequal ;
1152 +Equal:
1153 + mov EAX,a1[4+ESP] ;
1154 + mov EDX,a2[4+ESP] ;
1155 +
1156 + sub EAX,EDX ;
1157 + pop ESI ;
1158 +
1159 + pop EDI ;
1160 + ret ;
1161 +
1162 +UnequalQuad:
1163 + mov EDX,[EDI-4] ;
1164 + mov EAX,[ESI-4] ;
1165 +
1166 + cmp AL,DL ;
1167 + jnz Unequal ;
1168 +
1169 + cmp AH,DH ;
1170 + jnz Unequal ;
1171 +
1172 + shr EAX,16 ;
1173 +
1174 + shr EDX,16 ;
1175 +
1176 + cmp AL,DL ;
1177 + jnz Unequal ;
1178 +
1179 + cmp AH,DH ;
1180 +Unequal:
1181 + sbb EAX,EAX ;
1182 + pop ESI ;
1183 +
1184 + or EAX,1 ;
1185 + pop EDI ;
1186 +
1187 + ret ;
1188 + }
1189 + }
1190 + else
1191 + {
1192 + int len;
1193 + int c;
1194 +
1195 + debug(adi) printf("adCmpChar()\n");
1196 + len = cast(int)a1.length;
1197 + if (a2.length < len)
1198 + len = cast(int)a2.length;
1199 + c = memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len);
1200 + if (!c)
1201 + c = cast(int)a1.length - cast(int)a2.length;
1202 + return c;
1203 + }
1204 +}
1205 +
1206 +unittest
1207 +{
1208 + debug(adi) printf("array.CmpChar unittest\n");
1209 +
1210 + char[] a = "hello"c;
1211 +
1212 + assert(a > "hel");
1213 + assert(a >= "hel");
1214 + assert(a < "helloo");
1215 + assert(a <= "helloo");
1216 + assert(a > "betty");
1217 + assert(a >= "betty");
1218 + assert(a == "hello");
1219 + assert(a <= "hello");
1220 + assert(a >= "hello");
1221 +}
1222 Index: src/compiler/ldc/lifetime.d
1223 ===================================================================
1224 --- src/compiler/ldc/lifetime.d (revision 0)
1225 +++ src/compiler/ldc/lifetime.d (revision 0)
1226 @@ -0,0 +1,1147 @@
1227 +/**
1228 + * This module contains all functions related to an object's lifetime:
1229 + * allocation, resizing, deallocation, and finalization.
1230 + *
1231 + * Copyright: Copyright (C) 2004-2007 Digital Mars, www.digitalmars.com.
1232 + * All rights reserved.
1233 + * License:
1234 + * This software is provided 'as-is', without any express or implied
1235 + * warranty. In no event will the authors be held liable for any damages
1236 + * arising from the use of this software.
1237 + *
1238 + * Permission is granted to anyone to use this software for any purpose,
1239 + * including commercial applications, and to alter it and redistribute it
1240 + * freely, in both source and binary form, subject to the following
1241 + * restrictions:
1242 + *
1243 + * o The origin of this software must not be misrepresented; you must not
1244 + * claim that you wrote the original software. If you use this software
1245 + * in a product, an acknowledgment in the product documentation would be
1246 + * appreciated but is not required.
1247 + * o Altered source versions must be plainly marked as such, and must not
1248 + * be misrepresented as being the original software.
1249 + * o This notice may not be removed or altered from any source
1250 + * distribution.
1251 + * Authors: Walter Bright, Sean Kelly, Tomas Lindquist Olsen
1252 + */
1253 +module lifetime;
1254 +
1255 +//debug=PRINTF;
1256 +//debug=PRINTF2;
1257 +
1258 +private
1259 +{
1260 + version( D_Version2 )
1261 + {
1262 + import core.stdc.stdlib;
1263 + import core.stdc.string;
1264 + import core.stdc.stdarg;
1265 + debug(PRINTF) import core.stdc.stdio;
1266 + else debug(PRINTF2) import core.stdc.stdio;
1267 + }
1268 + else
1269 + {
1270 + import tango.stdc.stdlib;
1271 + import tango.stdc.string;
1272 + import tango.stdc.stdarg;
1273 + debug(PRINTF) import tango.stdc.stdio;
1274 + else debug(PRINTF2) import tango.stdc.stdio;
1275 + }
1276 +}
1277 +
1278 +
1279 +private
1280 +{
1281 + enum BlkAttr : uint
1282 + {
1283 + FINALIZE = 0b0000_0001,
1284 + NO_SCAN = 0b0000_0010,
1285 + NO_MOVE = 0b0000_0100,
1286 + ALL_BITS = 0b1111_1111
1287 + }
1288 +
1289 + struct BlkInfo
1290 + {
1291 + void* base;
1292 + size_t size;
1293 + uint attr;
1294 + }
1295 +
1296 + extern (C) uint gc_getAttr( void* p );
1297 + extern (C) uint gc_setAttr( void* p, uint a );
1298 + extern (C) uint gc_clrAttr( void* p, uint a );
1299 +
1300 + extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
1301 + extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
1302 + extern (C) size_t gc_extend( void* p, size_t mx, size_t sz );
1303 + extern (C) void gc_free( void* p );
1304 +
1305 + extern (C) void* gc_addrOf( void* p );
1306 + extern (C) size_t gc_sizeOf( void* p );
1307 + extern (C) BlkInfo gc_query( void* p );
1308 +
1309 + extern (C) bool onCollectResource( Object o );
1310 + extern (C) void onFinalizeError( ClassInfo c, Exception e );
1311 + extern (C) void onOutOfMemoryError();
1312 +
1313 + extern (C) void _d_monitordelete(Object h, bool det = true);
1314 +
1315 + enum
1316 + {
1317 + PAGESIZE = 4096
1318 + }
1319 +
1320 + alias bool function(Object) CollectHandler;
1321 + CollectHandler collectHandler = null;
1322 +}
1323 +
1324 +
1325 +/**
1326 + *
1327 + */
1328 +extern (C) Object _d_allocclass(ClassInfo ci)
1329 +{
1330 + void* p;
1331 +
1332 + debug(PRINTF2) printf("_d_allocclass(ci = %p, %s)\n", ci, cast(char *)ci.name.ptr);
1333 + /+
1334 + if (ci.flags & 1) // if COM object
1335 + { /* COM objects are not garbage collected, they are reference counted
1336 + * using AddRef() and Release(). They get free'd by C's free()
1337 + * function called by Release() when Release()'s reference count goes
1338 + * to zero.
1339 + */
1340 + p = tango.stdc.stdlib.malloc(ci.init.length);
1341 + if (!p)
1342 + onOutOfMemoryError();
1343 + }
1344 + else
1345 + +/
1346 + {
1347 + p = gc_malloc(ci.init.length,
1348 + BlkAttr.FINALIZE | (ci.flags & 2 ? BlkAttr.NO_SCAN : 0));
1349 + debug(PRINTF2) printf(" p = %p\n", p);
1350 + }
1351 +
1352 + debug(PRINTF2)
1353 + {
1354 + printf("p = %p\n", p);
1355 + printf("ci = %p, ci.init = %p, len = %d\n", ci, ci.init.ptr, ci.init.length);
1356 + printf("vptr = %p\n", *cast(void**) ci.init.ptr);
1357 + printf("vtbl[0] = %p\n", (*cast(void***) ci.init.ptr)[0]);
1358 + printf("vtbl[1] = %p\n", (*cast(void***) ci.init.ptr)[1]);
1359 + printf("init[0] = %p\n", (cast(uint**) ci.init.ptr)[0]);
1360 + printf("init[1] = %p\n", (cast(uint**) ci.init.ptr)[1]);
1361 + printf("init[2] = %p\n", (cast(uint**) ci.init.ptr)[2]);
1362 + printf("init[3] = %p\n", (cast(uint**) ci.init.ptr)[3]);
1363 + printf("init[4] = %p\n", (cast(uint**) ci.init.ptr)[4]);
1364 + }
1365 +
1366 + // initialize it
1367 + // ldc does this inline
1368 + //(cast(byte*) p)[0 .. ci.init.length] = ci.init[];
1369 +
1370 + debug(PRINTF) printf("initialization done\n");
1371 + return cast(Object) p;
1372 +}
1373 +
1374 +/**
1375 + *
1376 + */
1377 +extern (C) void _d_delinterface(void* p)
1378 +{
1379 + if (p)
1380 + {
1381 + Interface* pi = **cast(Interface ***)p;
1382 + Object o = cast(Object)(p - pi.offset);
1383 +
1384 + _d_delclass(o);
1385 + //*p = null;
1386 + }
1387 +}
1388 +
1389 +// used for deletion
1390 +private extern (D) alias void function(Object) fp_t;
1391 +
1392 +
1393 +/**
1394 + *
1395 + */
1396 +extern (C) void _d_delclass(Object p)
1397 +{
1398 + if (p)
1399 + {
1400 + debug(PRINTF) printf("_d_delclass(%p)\n", p);
1401 +
1402 + ClassInfo **pc = cast(ClassInfo **)p;
1403 + if (*pc)
1404 + {
1405 + ClassInfo c = **pc;
1406 +
1407 + rt_finalize(cast(void*) p);
1408 +
1409 + if (c.deallocator)
1410 + {
1411 + fp_t fp = cast(fp_t)c.deallocator;
1412 + (*fp)(p); // call deallocator
1413 + //*p = null;
1414 + return;
1415 + }
1416 + }
1417 + else
1418 + {
1419 + rt_finalize(cast(void*) p);
1420 + }
1421 + gc_free(cast(void*) p);
1422 + //*p = null;
1423 + }
1424 +}
1425 +
1426 +/+
1427 +
1428 +/**
1429 + *
1430 + */
1431 +struct Array
1432 +{
1433 + size_t length;
1434 + void* data;
1435 +}
1436 +
1437 ++/
1438 +
1439 +/**
1440 + * Allocate a new array of length elements.
1441 + * ti is the type of the resulting array, or pointer to element.
1442 + * The resulting array is initialized to 0
1443 + */
1444 +extern (C) void* _d_newarrayT(TypeInfo ti, size_t length)
1445 +{
1446 + void* p;
1447 + auto size = ti.next.tsize(); // array element size
1448 +
1449 + debug(PRINTF) printf("_d_newarrayT(length = %u, size = %d)\n", length, size);
1450 + if (length == 0 || size == 0)
1451 + return null;
1452 +
1453 + version (D_InlineAsm_X86)
1454 + {
1455 + asm
1456 + {
1457 + mov EAX,size ;
1458 + mul EAX,length ;
1459 + mov size,EAX ;
1460 + jc Loverflow ;
1461 + }
1462 + }
1463 + else
1464 + size *= length;
1465 + p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1466 + debug(PRINTF) printf(" p = %p\n", p);
1467 + memset(p, 0, size);
1468 + return p;
1469 +
1470 +Loverflow:
1471 + onOutOfMemoryError();
1472 + return null;
1473 +}
1474 +
1475 +/**
1476 + * As _d_newarrayT, but
1477 + * for when the array has a non-zero initializer.
1478 + */
1479 +extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length)
1480 +{
1481 + void* result;
1482 + auto size = ti.next.tsize(); // array element size
1483 +
1484 + debug(PRINTF) printf("_d_newarrayiT(length = %d, size = %d)\n", length, size);
1485 +
1486 + if (length == 0 || size == 0)
1487 + result = null;
1488 + else
1489 + {
1490 + auto initializer = ti.next.init();
1491 + auto isize = initializer.length;
1492 + auto q = initializer.ptr;
1493 + version (D_InlineAsm_X86)
1494 + {
1495 + asm
1496 + {
1497 + mov EAX,size ;
1498 + mul EAX,length ;
1499 + mov size,EAX ;
1500 + jc Loverflow ;
1501 + }
1502 + }
1503 + else
1504 + size *= length;
1505 + auto p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1506 + debug(PRINTF) printf(" p = %p\n", p);
1507 + if (isize == 1)
1508 + memset(p, *cast(ubyte*)q, size);
1509 + else if (isize == int.sizeof)
1510 + {
1511 + int init = *cast(int*)q;
1512 + size /= int.sizeof;
1513 + for (size_t u = 0; u < size; u++)
1514 + {
1515 + (cast(int*)p)[u] = init;
1516 + }
1517 + }
1518 + else
1519 + {
1520 + for (size_t u = 0; u < size; u += isize)
1521 + {
1522 + memcpy(p + u, q, isize);
1523 + }
1524 + }
1525 + result = p;
1526 + }
1527 + return result;
1528 +
1529 +Loverflow:
1530 + onOutOfMemoryError();
1531 + return null;
1532 +}
1533 +
1534 +/**
1535 + * As _d_newarrayT, but without initialization
1536 + */
1537 +extern (C) void* _d_newarrayvT(TypeInfo ti, size_t length)
1538 +{
1539 + void* p;
1540 + auto size = ti.next.tsize(); // array element size
1541 +
1542 + debug(PRINTF) printf("_d_newarrayvT(length = %u, size = %d)\n", length, size);
1543 + if (length == 0 || size == 0)
1544 + return null;
1545 +
1546 + version (D_InlineAsm_X86)
1547 + {
1548 + asm
1549 + {
1550 + mov EAX,size ;
1551 + mul EAX,length ;
1552 + mov size,EAX ;
1553 + jc Loverflow ;
1554 + }
1555 + }
1556 + else
1557 + size *= length;
1558 + p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1559 + debug(PRINTF) printf(" p = %p\n", p);
1560 + return p;
1561 +
1562 +Loverflow:
1563 + onOutOfMemoryError();
1564 + return null;
1565 +}
1566 +
1567 +/**
1568 + * Allocate a new array of arrays of arrays of arrays ...
1569 + * ti is the type of the resulting array.
1570 + * ndims is the number of nested arrays.
1571 + * dims it the array of dimensions, its size is ndims.
1572 + * The resulting array is initialized to 0
1573 + */
1574 +extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
1575 +{
1576 + void* result;
1577 +
1578 + debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims);
1579 + if (ndims == 0)
1580 + result = null;
1581 + else
1582 + {
1583 + static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
1584 + {
1585 + size_t dim = *pdim;
1586 + void[] p;
1587 +
1588 + debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
1589 + if (ndims == 1)
1590 + {
1591 + auto r = _d_newarrayT(ti, dim);
1592 + return r[0 .. dim];
1593 + }
1594 + else
1595 + {
1596 + p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
1597 + for (int i = 0; i < dim; i++)
1598 + {
1599 + (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
1600 + }
1601 + }
1602 + return p;
1603 + }
1604 +
1605 + result = foo(ti, dims, ndims).ptr;
1606 + debug(PRINTF) printf("result = %p\n", result);
1607 +
1608 + version (none)
1609 + {
1610 + for (int i = 0; i < ndims; i++)
1611 + {
1612 + printf("index %d: %d\n", i, *dims++);
1613 + }
1614 + }
1615 + }
1616 + return result;
1617 +}
1618 +
1619 +
1620 +/**
1621 + * As _d_newarraymT, but
1622 + * for when the array has a non-zero initializer.
1623 + */
1624 +extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
1625 +{
1626 + void* result;
1627 +
1628 + debug(PRINTF) printf("_d_newarraymiT(ndims = %d)\n", ndims);
1629 + if (ndims == 0)
1630 + result = null;
1631 + else
1632 + {
1633 + static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
1634 + {
1635 + size_t dim = *pdim;
1636 + void[] p;
1637 +
1638 + if (ndims == 1)
1639 + {
1640 + auto r = _d_newarrayiT(ti, dim);
1641 + p = r[0 .. dim];
1642 + }
1643 + else
1644 + {
1645 + p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
1646 + for (int i = 0; i < dim; i++)
1647 + {
1648 + (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
1649 + }
1650 + }
1651 + return p;
1652 + }
1653 +
1654 + result = foo(ti, dims, ndims).ptr;
1655 + debug(PRINTF) printf("result = %p\n", result);
1656 +
1657 + version (none)
1658 + {
1659 + for (int i = 0; i < ndims; i++)
1660 + {
1661 + printf("index %d: %d\n", i, *dims++);
1662 + printf("init = %d\n", *dims++);
1663 + }
1664 + }
1665 + }
1666 + return result;
1667 +}
1668 +
1669 +/**
1670 + * As _d_newarraymT, but without initialization
1671 + */
1672 +extern (C) void* _d_newarraymvT(TypeInfo ti, int ndims, size_t* dims)
1673 +{
1674 + void* result;
1675 +
1676 + debug(PRINTF) printf("_d_newarraymvT(ndims = %d)\n", ndims);
1677 + if (ndims == 0)
1678 + result = null;
1679 + else
1680 + {
1681 + static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
1682 + {
1683 + size_t dim = *pdim;
1684 + void[] p;
1685 +
1686 + debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
1687 + if (ndims == 1)
1688 + {
1689 + auto r = _d_newarrayvT(ti, dim);
1690 + return r[0 .. dim];
1691 + }
1692 + else
1693 + {
1694 + p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
1695 + for (int i = 0; i < dim; i++)
1696 + {
1697 + (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
1698 + }
1699 + }
1700 + return p;
1701 + }
1702 +
1703 + result = foo(ti, dims, ndims).ptr;
1704 + debug(PRINTF) printf("result = %p\n", result);
1705 +
1706 + version (none)
1707 + {
1708 + for (int i = 0; i < ndims; i++)
1709 + {
1710 + printf("index %d: %d\n", i, *dims++);
1711 + }
1712 + }
1713 + }
1714 + return result;
1715 +}
1716 +
1717 +/+
1718 +
1719 +/**
1720 + *
1721 + */
1722 +void* _d_allocmemory(size_t nbytes)
1723 +{
1724 + return gc_malloc(nbytes);
1725 +}
1726 +
1727 ++/
1728 +
1729 +/**
1730 + * for allocating a single POD value
1731 + */
1732 +extern (C) void* _d_allocmemoryT(TypeInfo ti)
1733 +{
1734 + return gc_malloc(ti.tsize(), !(ti.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1735 +}
1736 +
1737 +/**
1738 + *
1739 + */
1740 +extern (C) void _d_delarray(size_t plength, void* pdata)
1741 +{
1742 +// if (p)
1743 +// {
1744 + assert(!plength || pdata);
1745 +
1746 + if (pdata)
1747 + gc_free(pdata);
1748 +// p.data = null;
1749 +// p.length = 0;
1750 +// }
1751 +}
1752 +
1753 +/**
1754 + *
1755 + */
1756 +extern (C) void _d_delmemory(void* p)
1757 +{
1758 + if (p)
1759 + {
1760 + gc_free(p);
1761 + //*p = null;
1762 + }
1763 +}
1764 +
1765 +/**
1766 + *
1767 + */
1768 +extern (C) void _d_callinterfacefinalizer(void *p)
1769 +{
1770 + if (p)
1771 + {
1772 + Interface *pi = **cast(Interface ***)p;
1773 + Object o = cast(Object)(p - pi.offset);
1774 + rt_finalize(cast(void*)o);
1775 + }
1776 +}
1777 +
1778 +/**
1779 + *
1780 + */
1781 +extern (C) void _d_callfinalizer(void* p)
1782 +{
1783 + rt_finalize( p );
1784 +}
1785 +
1786 +
1787 +/**
1788 + *
1789 + */
1790 +extern (C) void rt_setCollectHandler(CollectHandler h)
1791 +{
1792 + collectHandler = h;
1793 +}
1794 +
1795 +/**
1796 + *
1797 + */
1798 +extern (C) void rt_finalize(void* p, bool det = true)
1799 +{
1800 + debug(PRINTF) printf("rt_finalize(p = %p)\n", p);
1801 +
1802 + if (p) // not necessary if called from gc
1803 + {
1804 + ClassInfo** pc = cast(ClassInfo**)p;
1805 +
1806 + if (*pc)
1807 + {
1808 + ClassInfo c = **pc;
1809 +
1810 + try
1811 + {
1812 + if (det || collectHandler is null || collectHandler(cast(Object)p))
1813 + {
1814 + do
1815 + {
1816 + if (c.destructor)
1817 + {
1818 + debug(PRINTF) printf("calling dtor of %.*s\n", c.name.length, c.name.ptr);
1819 + fp_t fp = cast(fp_t)c.destructor;
1820 + (*fp)(cast(Object)p); // call destructor
1821 + }
1822 + c = c.base;
1823 + } while (c);
1824 + }
1825 + if ((cast(void**)p)[1]) // if monitor is not null
1826 + _d_monitordelete(cast(Object)p, det);
1827 + }
1828 + catch (Exception e)
1829 + {
1830 + onFinalizeError(**pc, e);
1831 + }
1832 + finally
1833 + {
1834 + *pc = null; // zero vptr
1835 + }
1836 + }
1837 + }
1838 +}
1839 +
1840 +/**
1841 + * Resize dynamic arrays with 0 initializers.
1842 + */
1843 +extern (C) byte* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
1844 +in
1845 +{
1846 + assert(ti);
1847 + assert(!plength || pdata);
1848 +}
1849 +body
1850 +{
1851 + byte* newdata;
1852 + size_t sizeelem = ti.next.tsize();
1853 +
1854 + debug(PRINTF)
1855 + {
1856 + printf("_d_arraysetlengthT(sizeelem = %d, newlength = %d)\n", sizeelem, newlength);
1857 + printf("\tp.data = %p, p.length = %d\n", pdata, plength);
1858 + }
1859 +
1860 + if (newlength)
1861 + {
1862 + version (D_InlineAsm_X86)
1863 + {
1864 + size_t newsize = void;
1865 +
1866 + asm
1867 + {
1868 + mov EAX, newlength;
1869 + mul EAX, sizeelem;
1870 + mov newsize, EAX;
1871 + jc Loverflow;
1872 + }
1873 + }
1874 + else
1875 + {
1876 + size_t newsize = sizeelem * newlength;
1877 +
1878 + if (newsize / newlength != sizeelem)
1879 + goto Loverflow;
1880 + }
1881 +
1882 + debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
1883 +
1884 + if (pdata)
1885 + {
1886 + newdata = pdata;
1887 + if (newlength > plength)
1888 + {
1889 + size_t size = plength * sizeelem;
1890 + auto info = gc_query(pdata);
1891 +
1892 + if (info.size <= newsize || info.base != pdata)
1893 + {
1894 + if (info.size >= PAGESIZE && info.base == pdata)
1895 + { // Try to extend in-place
1896 + auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
1897 + if (u)
1898 + {
1899 + goto L1;
1900 + }
1901 + }
1902 + newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
1903 + newdata[0 .. size] = pdata[0 .. size];
1904 + }
1905 + L1:
1906 + newdata[size .. newsize] = 0;
1907 + }
1908 + }
1909 + else
1910 + {
1911 + newdata = cast(byte *)gc_calloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
1912 + }
1913 + }
1914 + else
1915 + {
1916 + newdata = pdata;
1917 + }
1918 +
1919 + return newdata;
1920 +
1921 +Loverflow:
1922 + onOutOfMemoryError();
1923 + return null;
1924 +}
1925 +
1926 +
1927 +/**
1928 + * Resize arrays for non-zero initializers.
1929 + * p pointer to array lvalue to be updated
1930 + * newlength new .length property of array
1931 + * sizeelem size of each element of array
1932 + * initsize size of initializer
1933 + * ... initializer
1934 + */
1935 +extern (C) byte* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
1936 +in
1937 +{
1938 + assert(!plength || pdata);
1939 +}
1940 +body
1941 +{
1942 + byte* newdata;
1943 + TypeInfo tinext = ti.next;
1944 + size_t sizeelem = tinext.tsize();
1945 + void[] initializer = tinext.init();
1946 + size_t initsize = initializer.length;
1947 +
1948 + assert(sizeelem);
1949 + assert(initsize);
1950 + assert(initsize <= sizeelem);
1951 + assert((sizeelem / initsize) * initsize == sizeelem);
1952 +
1953 + debug(PRINTF)
1954 + {
1955 + printf("_d_arraysetlengthiT(sizeelem = %d, newlength = %d, initsize = %d)\n", sizeelem, newlength, initsize);
1956 + printf("\tp.data = %p, p.length = %d\n", pdata, plength);
1957 + }
1958 +
1959 + if (newlength)
1960 + {
1961 + version (D_InlineAsm_X86)
1962 + {
1963 + size_t newsize = void;
1964 +
1965 + asm
1966 + {
1967 + mov EAX,newlength ;
1968 + mul EAX,sizeelem ;
1969 + mov newsize,EAX ;
1970 + jc Loverflow ;
1971 + }
1972 + }
1973 + else
1974 + {
1975 + size_t newsize = sizeelem * newlength;
1976 +
1977 + if (newsize / newlength != sizeelem)
1978 + goto Loverflow;
1979 + }
1980 + debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
1981 +
1982 + size_t size = plength * sizeelem;
1983 +
1984 + if (pdata)
1985 + {
1986 + newdata = pdata;
1987 + if (newlength > plength)
1988 + {
1989 + auto info = gc_query(pdata);
1990 +
1991 + if (info.size <= newsize || info.base != pdata)
1992 + {
1993 + if (info.size >= PAGESIZE && info.base == pdata)
1994 + { // Try to extend in-place
1995 + auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
1996 + if (u)
1997 + {
1998 + goto L1;
1999 + }
2000 + }
2001 + newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
2002 + newdata[0 .. size] = pdata[0 .. size];
2003 + L1: ;
2004 + }
2005 + }
2006 + }
2007 + else
2008 + {
2009 + newdata = cast(byte *)gc_malloc(newsize + 1, !(tinext.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2010 + }
2011 +
2012 + auto q = initializer.ptr; // pointer to initializer
2013 +
2014 + if (newsize > size)
2015 + {
2016 + if (initsize == 1)
2017 + {
2018 + debug(PRINTF) printf("newdata = %p, size = %d, newsize = %d, *q = %d\n", newdata, size, newsize, *cast(byte*)q);
2019 + newdata[size .. newsize] = *(cast(byte*)q);
2020 + }
2021 + else
2022 + {
2023 + for (size_t u = size; u < newsize; u += initsize)
2024 + {
2025 + memcpy(newdata + u, q, initsize);
2026 + }
2027 + }
2028 + }
2029 + }
2030 + else
2031 + {
2032 + newdata = pdata;
2033 + }
2034 +
2035 + return newdata;
2036 +
2037 +Loverflow:
2038 + onOutOfMemoryError();
2039 + return null;
2040 +}
2041 +
2042 +/+
2043 +
2044 +/**
2045 + * Append y[] to array x[].
2046 + * size is size of each array element.
2047 + */
2048 +extern (C) long _d_arrayappendT(TypeInfo ti, Array *px, byte[] y)
2049 +{
2050 + auto sizeelem = ti.next.tsize(); // array element size
2051 + auto info = gc_query(px.data);
2052 + auto length = px.length;
2053 + auto newlength = length + y.length;
2054 + auto newsize = newlength * sizeelem;
2055 +
2056 + if (info.size < newsize || info.base != px.data)
2057 + { byte* newdata;
2058 +
2059 + if (info.size >= PAGESIZE && info.base == px.data)
2060 + { // Try to extend in-place
2061 + auto u = gc_extend(px.data, (newsize + 1) - info.size, (newsize + 1) - info.size);
2062 + if (u)
2063 + {
2064 + goto L1;
2065 + }
2066 + }
2067 + newdata = cast(byte *)gc_malloc(newCapacity(newlength, sizeelem) + 1, info.attr);
2068 + memcpy(newdata, px.data, length * sizeelem);
2069 + px.data = newdata;
2070 + }
2071 + L1:
2072 + px.length = newlength;
2073 + memcpy(px.data + length * sizeelem, y.ptr, y.length * sizeelem);
2074 + return *cast(long*)px;
2075 +}
2076 +
2077 +
2078 +/**
2079 + *
2080 + */
2081 +size_t newCapacity(size_t newlength, size_t size)
2082 +{
2083 + version(none)
2084 + {
2085 + size_t newcap = newlength * size;
2086 + }
2087 + else
2088 + {
2089 + /*
2090 + * Better version by Dave Fladebo:
2091 + * This uses an inverse logorithmic algorithm to pre-allocate a bit more
2092 + * space for larger arrays.
2093 + * - Arrays smaller than PAGESIZE bytes are left as-is, so for the most
2094 + * common cases, memory allocation is 1 to 1. The small overhead added
2095 + * doesn't affect small array perf. (it's virtually the same as
2096 + * current).
2097 + * - Larger arrays have some space pre-allocated.
2098 + * - As the arrays grow, the relative pre-allocated space shrinks.
2099 + * - The logorithmic algorithm allocates relatively more space for
2100 + * mid-size arrays, making it very fast for medium arrays (for
2101 + * mid-to-large arrays, this turns out to be quite a bit faster than the
2102 + * equivalent realloc() code in C, on Linux at least. Small arrays are
2103 + * just as fast as GCC).
2104 + * - Perhaps most importantly, overall memory usage and stress on the GC
2105 + * is decreased significantly for demanding environments.
2106 + */
2107 + size_t newcap = newlength * size;
2108 + size_t newext = 0;
2109 +
2110 + if (newcap > PAGESIZE)
2111 + {
2112 + //double mult2 = 1.0 + (size / log10(pow(newcap * 2.0,2.0)));
2113 +
2114 + // redo above line using only integer math
2115 +
2116 + static int log2plus1(size_t c)
2117 + { int i;
2118 +
2119 + if (c == 0)
2120 + i = -1;
2121 + else
2122 + for (i = 1; c >>= 1; i++)
2123 + {
2124 + }
2125 + return i;
2126 + }
2127 +
2128 + /* The following setting for mult sets how much bigger
2129 + * the new size will be over what is actually needed.
2130 + * 100 means the same size, more means proportionally more.
2131 + * More means faster but more memory consumption.
2132 + */
2133 + //long mult = 100 + (1000L * size) / (6 * log2plus1(newcap));
2134 + long mult = 100 + (1000L * size) / log2plus1(newcap);
2135 +
2136 + // testing shows 1.02 for large arrays is about the point of diminishing return
2137 + if (mult < 102)
2138 + mult = 102;
2139 + newext = cast(size_t)((newcap * mult) / 100);
2140 + newext -= newext % size;
2141 + debug(PRINTF) printf("mult: %2.2f, alloc: %2.2f\n",mult/100.0,newext / cast(double)size);
2142 + }
2143 + newcap = newext > newcap ? newext : newcap;
2144 + debug(PRINTF) printf("newcap = %d, newlength = %d, size = %d\n", newcap, newlength, size);
2145 + }
2146 + return newcap;
2147 +}
2148 +
2149 +
2150 +/**
2151 + *
2152 + */
2153 +extern (C) byte[] _d_arrayappendcT(TypeInfo ti, inout byte[] x, ...)
2154 +{
2155 + auto sizeelem = ti.next.tsize(); // array element size
2156 + auto info = gc_query(x.ptr);
2157 + auto length = x.length;
2158 + auto newlength = length + 1;
2159 + auto newsize = newlength * sizeelem;
2160 +
2161 + assert(info.size == 0 || length * sizeelem <= info.size);
2162 +
2163 + debug(PRINTF) printf("_d_arrayappendcT(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, info.size);
2164 +
2165 + if (info.size <= newsize || info.base != x.ptr)
2166 + { byte* newdata;
2167 +
2168 + if (info.size >= PAGESIZE && info.base == x.ptr)
2169 + { // Try to extend in-place
2170 + auto u = gc_extend(x.ptr, (newsize + 1) - info.size, (newsize + 1) - info.size);
2171 + if (u)
2172 + {
2173 + goto L1;
2174 + }
2175 + }
2176 + debug(PRINTF) printf("_d_arrayappendcT(length = %d, newlength = %d, cap = %d)\n", length, newlength, info.size);
2177 + auto newcap = newCapacity(newlength, sizeelem);
2178 + assert(newcap >= newlength * sizeelem);
2179 + newdata = cast(byte *)gc_malloc(newcap + 1, info.attr);
2180 + memcpy(newdata, x.ptr, length * sizeelem);
2181 + (cast(void**)(&x))[1] = newdata;
2182 + }
2183 + L1:
2184 + byte *argp = cast(byte *)(&ti + 2);
2185 +
2186 + *cast(size_t *)&x = newlength;
2187 + x.ptr[length * sizeelem .. newsize] = argp[0 .. sizeelem];
2188 + assert((cast(size_t)x.ptr & 15) == 0);
2189 + assert(gc_sizeOf(x.ptr) > x.length * sizeelem);
2190 + return x;
2191 +}
2192 +
2193 +
2194 +/**
2195 + *
2196 + */
2197 +extern (C) byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y)
2198 +out (result)
2199 +{
2200 + auto sizeelem = ti.next.tsize(); // array element size
2201 + 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);
2202 + assert(result.length == x.length + y.length);
2203 + for (size_t i = 0; i < x.length * sizeelem; i++)
2204 + assert((cast(byte*)result)[i] == (cast(byte*)x)[i]);
2205 + for (size_t i = 0; i < y.length * sizeelem; i++)
2206 + assert((cast(byte*)result)[x.length * sizeelem + i] == (cast(byte*)y)[i]);
2207 +
2208 + size_t cap = gc_sizeOf(result.ptr);
2209 + assert(!cap || cap > result.length * sizeelem);
2210 +}
2211 +body
2212 +{
2213 + version (none)
2214 + {
2215 + /* Cannot use this optimization because:
2216 + * char[] a, b;
2217 + * char c = 'a';
2218 + * b = a ~ c;
2219 + * c = 'b';
2220 + * will change the contents of b.
2221 + */
2222 + if (!y.length)
2223 + return x;
2224 + if (!x.length)
2225 + return y;
2226 + }
2227 +
2228 + debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p)\n", x.length, x.ptr, y.length, y.ptr);
2229 + auto sizeelem = ti.next.tsize(); // array element size
2230 + debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d)\n", x.length, x.ptr, y.length, y.ptr, sizeelem);
2231 + size_t xlen = x.length * sizeelem;
2232 + size_t ylen = y.length * sizeelem;
2233 + size_t len = xlen + ylen;
2234 +
2235 + if (!len)
2236 + return null;
2237 +
2238 + byte* p = cast(byte*)gc_malloc(len + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2239 + memcpy(p, x.ptr, xlen);
2240 + memcpy(p + xlen, y.ptr, ylen);
2241 + p[len] = 0;
2242 + return p[0 .. x.length + y.length];
2243 +}
2244 +
2245 +
2246 +/**
2247 + *
2248 + */
2249 +extern (C) byte[] _d_arraycatnT(TypeInfo ti, uint n, ...)
2250 +{ void* a;
2251 + size_t length;
2252 + byte[]* p;
2253 + uint i;
2254 + byte[] b;
2255 + auto size = ti.next.tsize(); // array element size
2256 +
2257 + p = cast(byte[]*)(&n + 1);
2258 +
2259 + for (i = 0; i < n; i++)
2260 + {
2261 + b = *p++;
2262 + length += b.length;
2263 + }
2264 + if (!length)
2265 + return null;
2266 +
2267 + a = gc_malloc(length * size, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2268 + p = cast(byte[]*)(&n + 1);
2269 +
2270 + uint j = 0;
2271 + for (i = 0; i < n; i++)
2272 + {
2273 + b = *p++;
2274 + if (b.length)
2275 + {
2276 + memcpy(a + j, b.ptr, b.length * size);
2277 + j += b.length * size;
2278 + }
2279 + }
2280 +
2281 + byte[] result;
2282 + *cast(int *)&result = length; // jam length
2283 + (cast(void **)&result)[1] = a; // jam ptr
2284 + return result;
2285 +}
2286 +
2287 +
2288 +/**
2289 + *
2290 + */
2291 +extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...)
2292 +{
2293 + auto sizeelem = ti.next.tsize(); // array element size
2294 + void* result;
2295 +
2296 + debug(PRINTF) printf("_d_arrayliteralT(sizeelem = %d, length = %d)\n", sizeelem, length);
2297 + if (length == 0 || sizeelem == 0)
2298 + result = null;
2299 + else
2300 + {
2301 + result = gc_malloc(length * sizeelem, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2302 +
2303 + va_list q;
2304 + va_start!(size_t)(q, length);
2305 +
2306 + size_t stacksize = (sizeelem + int.sizeof - 1) & ~(int.sizeof - 1);
2307 +
2308 + if (stacksize == sizeelem)
2309 + {
2310 + memcpy(result, q, length * sizeelem);
2311 + }
2312 + else
2313 + {
2314 + for (size_t i = 0; i < length; i++)
2315 + {
2316 + memcpy(result + i * sizeelem, q, sizeelem);
2317 + q += stacksize;
2318 + }
2319 + }
2320 +
2321 + va_end(q);
2322 + }
2323 + return result;
2324 +}
2325 +
2326 ++/
2327 +
2328 +
2329 +/**
2330 + * Support for array.dup property.
2331 + * The actual type is painted on the return value by the frontend
2332 + * Given length is number of elements
2333 + * Returned length is number of elements
2334 + */
2335 +
2336 +
2337 +/**
2338 + *
2339 + */
2340 +extern (C) void[] _adDupT(TypeInfo ti, void[] a)
2341 +out (result)
2342 +{
2343 + auto sizeelem = ti.next.tsize(); // array element size
2344 + assert(memcmp(result.ptr, a.ptr, a.length * sizeelem) == 0);
2345 +}
2346 +body
2347 +{
2348 + void* ptr;
2349 +
2350 + if (a.length)
2351 + {
2352 + auto sizeelem = ti.next.tsize(); // array element size
2353 + auto size = a.length * sizeelem;
2354 + ptr = gc_malloc(size, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
2355 + memcpy(ptr, a.ptr, size);
2356 + }
2357 + return ptr[0 .. a.length];
2358 +}
2359 +
2360 +
2361 +unittest
2362 +{
2363 + int[] a;
2364 + int[] b;
2365 + int i;
2366 +
2367 + a = new int[3];
2368 + a[0] = 1; a[1] = 2; a[2] = 3;
2369 + b = a.dup;
2370 + assert(b.length == 3);
2371 + for (i = 0; i < 3; i++)
2372 + assert(b[i] == i + 1);
2373 +}
2374 Index: src/compiler/ldc/switch.d
2375 ===================================================================
2376 --- src/compiler/ldc/switch.d (revision 0)
2377 +++ src/compiler/ldc/switch.d (revision 0)
2378 @@ -0,0 +1,428 @@
2379 +/*
2380 + * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
2381 + * Written by Walter Bright
2382 + *
2383 + * This software is provided 'as-is', without any express or implied
2384 + * warranty. In no event will the authors be held liable for any damages
2385 + * arising from the use of this software.
2386 + *
2387 + * Permission is granted to anyone to use this software for any purpose,
2388 + * including commercial applications, and to alter it and redistribute it
2389 + * freely, in both source and binary form, subject to the following
2390 + * restrictions:
2391 + *
2392 + * o The origin of this software must not be misrepresented; you must not
2393 + * claim that you wrote the original software. If you use this software
2394 + * in a product, an acknowledgment in the product documentation would be
2395 + * appreciated but is not required.
2396 + * o Altered source versions must be plainly marked as such, and must not
2397 + * be misrepresented as being the original software.
2398 + * o This notice may not be removed or altered from any source
2399 + * distribution.
2400 + */
2401 +
2402 +/*
2403 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
2404 + */
2405 +
2406 +version( D_Version2 )
2407 +private import core.stdc.string;
2408 +else
2409 +private import tango.stdc.string;
2410 +//private import tango.stdc.stdio;
2411 +
2412 +/******************************************************
2413 + * Support for switch statements switching on strings.
2414 + * Input:
2415 + * table[] sorted array of strings generated by compiler
2416 + * ca string to look up in table
2417 + * Output:
2418 + * result index of match in table[]
2419 + * -1 if not in table
2420 + */
2421 +
2422 +extern (C):
2423 +
2424 +int _d_switch_string(char[][] table, char[] ca)
2425 +in
2426 +{
2427 + //printf("in _d_switch_string()\n");
2428 + assert(table.length >= 0);
2429 + assert(ca.length >= 0);
2430 +
2431 + // Make sure table[] is sorted correctly
2432 + int j;
2433 +
2434 + for (j = 1; j < table.length; j++)
2435 + {
2436 + size_t len1 = table[j - 1].length;
2437 + size_t len2 = table[j].length;
2438 +
2439 + assert(len1 <= len2);
2440 + if (len1 == len2)
2441 + {
2442 + int ci;
2443 +
2444 + ci = memcmp(table[j - 1].ptr, table[j].ptr, len1);
2445 + assert(ci < 0); // ci==0 means a duplicate
2446 + }
2447 + }
2448 +}
2449 +out (result)
2450 +{
2451 + int i;
2452 + int cj;
2453 +
2454 + //printf("out _d_switch_string()\n");
2455 + if (result == -1)
2456 + {
2457 + // Not found
2458 + for (i = 0; i < table.length; i++)
2459 + {
2460 + if (table[i].length == ca.length)
2461 + { cj = memcmp(table[i].ptr, ca.ptr, ca.length);
2462 + assert(cj != 0);
2463 + }
2464 + }
2465 + }
2466 + else
2467 + {
2468 + assert(0 <= result && result < table.length);
2469 + for (i = 0; 1; i++)
2470 + {
2471 + assert(i < table.length);
2472 + if (table[i].length == ca.length)
2473 + {
2474 + cj = memcmp(table[i].ptr, ca.ptr, ca.length);
2475 + if (cj == 0)
2476 + {
2477 + assert(i == result);
2478 + break;
2479 + }
2480 + }
2481 + }
2482 + }
2483 +}
2484 +body
2485 +{
2486 + //printf("body _d_switch_string(%.*s)\n", ca.length, ca.ptr);
2487 + size_t low;
2488 + size_t high;
2489 + size_t mid;
2490 + ptrdiff_t c;
2491 + char[] pca;
2492 +
2493 + low = 0;
2494 + high = table.length;
2495 +
2496 + version (none)
2497 + {
2498 + // Print table
2499 + printf("ca[] = '%s'\n", cast(char *)ca);
2500 + for (mid = 0; mid < high; mid++)
2501 + {
2502 + pca = table[mid];
2503 + printf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
2504 + }
2505 + }
2506 + if (high &&
2507 + ca.length >= table[0].length &&
2508 + ca.length <= table[high - 1].length)
2509 + {
2510 + // Looking for 0 length string, which would only be at the beginning
2511 + if (ca.length == 0)
2512 + return 0;
2513 +
2514 + char c1 = ca[0];
2515 +
2516 + // Do binary search
2517 + while (low < high)
2518 + {
2519 + mid = (low + high) >> 1;
2520 + pca = table[mid];
2521 + c = cast(ptrdiff_t)(ca.length - pca.length);
2522 + if (c == 0)
2523 + {
2524 + c = cast(ubyte)c1 - cast(ubyte)pca[0];
2525 + if (c == 0)
2526 + {
2527 + c = memcmp(ca.ptr, pca.ptr, ca.length);
2528 + if (c == 0)
2529 + { //printf("found %d\n", mid);
2530 + return cast(int)mid;
2531 + }
2532 + }
2533 + }
2534 + if (c < 0)
2535 + {
2536 + high = mid;
2537 + }
2538 + else
2539 + {
2540 + low = mid + 1;
2541 + }
2542 + }
2543 + }
2544 +
2545 + //printf("not found\n");
2546 + return -1; // not found
2547 +}
2548 +
2549 +unittest
2550 +{
2551 + switch (cast(char []) "c")
2552 + {
2553 + case "coo":
2554 + default:
2555 + break;
2556 + }
2557 +}
2558 +
2559 +/**********************************
2560 + * Same thing, but for wide chars.
2561 + */
2562 +
2563 +int _d_switch_ustring(wchar[][] table, wchar[] ca)
2564 +in
2565 +{
2566 + //printf("in _d_switch_ustring()\n");
2567 + assert(table.length >= 0);
2568 + assert(ca.length >= 0);
2569 +
2570 + // Make sure table[] is sorted correctly
2571 + int j;
2572 +
2573 + for (j = 1; j < table.length; j++)
2574 + {
2575 + size_t len1 = table[j - 1].length;
2576 + size_t len2 = table[j].length;
2577 +
2578 + assert(len1 <= len2);
2579 + if (len1 == len2)
2580 + {
2581 + int c;
2582 +
2583 + c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof);
2584 + assert(c < 0); // c==0 means a duplicate
2585 + }
2586 + }
2587 +}
2588 +out (result)
2589 +{
2590 + int i;
2591 + int c;
2592 +
2593 + //printf("out _d_switch_string()\n");
2594 + if (result == -1)
2595 + {
2596 + // Not found
2597 + for (i = 0; i < table.length; i++)
2598 + {
2599 + if (table[i].length == ca.length)
2600 + { c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
2601 + assert(c != 0);
2602 + }
2603 + }
2604 + }
2605 + else
2606 + {
2607 + assert(0 <= result && result < table.length);
2608 + for (i = 0; 1; i++)
2609 + {
2610 + assert(i < table.length);
2611 + if (table[i].length == ca.length)
2612 + {
2613 + c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
2614 + if (c == 0)
2615 + {
2616 + assert(i == result);
2617 + break;
2618 + }
2619 + }
2620 + }
2621 + }
2622 +}
2623 +body
2624 +{
2625 + //printf("body _d_switch_ustring()\n");
2626 + size_t low;
2627 + size_t high;
2628 + size_t mid;
2629 + ptrdiff_t c;
2630 + wchar[] pca;
2631 +
2632 + low = 0;
2633 + high = table.length;
2634 +
2635 +/*
2636 + // Print table
2637 + wprintf("ca[] = '%.*s'\n", ca);
2638 + for (mid = 0; mid < high; mid++)
2639 + {
2640 + pca = table[mid];
2641 + wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
2642 + }
2643 +*/
2644 +
2645 + // Do binary search
2646 + while (low < high)
2647 + {
2648 + mid = (low + high) >> 1;
2649 + pca = table[mid];
2650 + c = cast(ptrdiff_t)(ca.length - pca.length);
2651 + if (c == 0)
2652 + {
2653 + c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof);
2654 + if (c == 0)
2655 + { //printf("found %d\n", mid);
2656 + return cast(int)mid;
2657 + }
2658 + }
2659 + if (c < 0)
2660 + {
2661 + high = mid;
2662 + }
2663 + else
2664 + {
2665 + low = mid + 1;
2666 + }
2667 + }
2668 + //printf("not found\n");
2669 + return -1; // not found
2670 +}
2671 +
2672 +
2673 +unittest
2674 +{
2675 + switch (cast(wchar []) "c")
2676 + {
2677 + case "coo":
2678 + default:
2679 + break;
2680 + }
2681 +}
2682 +
2683 +
2684 +/**********************************
2685 + * Same thing, but for wide chars.
2686 + */
2687 +
2688 +int _d_switch_dstring(dchar[][] table, dchar[] ca)
2689 +in
2690 +{
2691 + //printf("in _d_switch_dstring()\n");
2692 + assert(table.length >= 0);
2693 + assert(ca.length >= 0);
2694 +
2695 + // Make sure table[] is sorted correctly
2696 + int j;
2697 +
2698 + for (j = 1; j < table.length; j++)
2699 + {
2700 + size_t len1 = table[j - 1].length;
2701 + size_t len2 = table[j].length;
2702 +
2703 + assert(len1 <= len2);
2704 + if (len1 == len2)
2705 + {
2706 + int c;
2707 +
2708 + c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof);
2709 + assert(c < 0); // c==0 means a duplicate
2710 + }
2711 + }
2712 +}
2713 +out (result)
2714 +{
2715 + int i;
2716 + int c;
2717 +
2718 + //printf("out _d_switch_string()\n");
2719 + if (result == -1)
2720 + {
2721 + // Not found
2722 + for (i = 0; i < table.length; i++)
2723 + {
2724 + if (table[i].length == ca.length)
2725 + { c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
2726 + assert(c != 0);
2727 + }
2728 + }
2729 + }
2730 + else
2731 + {
2732 + assert(0 <= result && result < table.length);
2733 + for (i = 0; 1; i++)
2734 + {
2735 + assert(i < table.length);
2736 + if (table[i].length == ca.length)
2737 + {
2738 + c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
2739 + if (c == 0)
2740 + {
2741 + assert(i == result);
2742 + break;
2743 + }
2744 + }
2745 + }
2746 + }
2747 +}
2748 +body
2749 +{
2750 + //printf("body _d_switch_ustring()\n");
2751 + size_t low;
2752 + size_t high;
2753 + size_t mid;
2754 + ptrdiff_t c;
2755 + dchar[] pca;
2756 +
2757 + low = 0;
2758 + high = table.length;
2759 +
2760 +/*
2761 + // Print table
2762 + wprintf("ca[] = '%.*s'\n", ca);
2763 + for (mid = 0; mid < high; mid++)
2764 + {
2765 + pca = table[mid];
2766 + wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
2767 + }
2768 +*/
2769 +
2770 + // Do binary search
2771 + while (low < high)
2772 + {
2773 + mid = (low + high) >> 1;
2774 + pca = table[mid];
2775 + c = cast(ptrdiff_t)(ca.length - pca.length);
2776 + if (c == 0)
2777 + {
2778 + c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);
2779 + if (c == 0)
2780 + { //printf("found %d\n", mid);
2781 + return cast(int)mid;
2782 + }
2783 + }
2784 + if (c < 0)
2785 + {
2786 + high = mid;
2787 + }
2788 + else
2789 + {
2790 + low = mid + 1;
2791 + }
2792 + }
2793 + //printf("not found\n");
2794 + return -1; // not found
2795 +}
2796 +
2797 +
2798 +unittest
2799 +{
2800 + switch (cast(dchar []) "c")
2801 + {
2802 + case "coo":
2803 + default:
2804 + break;
2805 + }
2806 +}
2807 Index: src/compiler/ldc/arrayInit.d
2808 ===================================================================
2809 --- src/compiler/ldc/arrayInit.d (revision 0)
2810 +++ src/compiler/ldc/arrayInit.d (revision 0)
2811 @@ -0,0 +1,158 @@
2812 +private import ldc.intrinsics;
2813 +
2814 +extern(C):
2815 +
2816 +int memcmp(void*,void*,size_t);
2817 +size_t strlen(char*);
2818 +
2819 +version(LLVM64)
2820 +alias llvm_memcpy_i64 llvm_memcpy;
2821 +else
2822 +alias llvm_memcpy_i32 llvm_memcpy;
2823 +
2824 +// per-element array init routines
2825 +
2826 +void _d_array_init_i1(bool* a, size_t n, bool v)
2827 +{
2828 + auto p = a;
2829 + auto end = a+n;
2830 + while (p !is end)
2831 + *p++ = v;
2832 +}
2833 +
2834 +void _d_array_init_i8(ubyte* a, size_t n, ubyte v)
2835 +{
2836 + auto p = a;
2837 + auto end = a+n;
2838 + while (p !is end)
2839 + *p++ = v;
2840 +}
2841 +
2842 +void _d_array_init_i16(ushort* a, size_t n, ushort v)
2843 +{
2844 + auto p = a;
2845 + auto end = a+n;
2846 + while (p !is end)
2847 + *p++ = v;
2848 +}
2849 +
2850 +void _d_array_init_i32(uint* a, size_t n, uint v)
2851 +{
2852 + auto p = a;
2853 + auto end = a+n;
2854 + while (p !is end)
2855 + *p++ = v;
2856 +}
2857 +
2858 +void _d_array_init_i64(ulong* a, size_t n, ulong v)
2859 +{
2860 + auto p = a;
2861 + auto end = a+n;
2862 + while (p !is end)
2863 + *p++ = v;
2864 +}
2865 +
2866 +void _d_array_init_float(float* a, size_t n, float v)
2867 +{
2868 + auto p = a;
2869 + auto end = a+n;
2870 + while (p !is end)
2871 + *p++ = v;
2872 +}
2873 +
2874 +void _d_array_init_double(double* a, size_t n, double v)
2875 +{
2876 + auto p = a;
2877 + auto end = a+n;
2878 + while (p !is end)
2879 + *p++ = v;
2880 +}
2881 +
2882 +void _d_array_init_real(real* a, size_t n, real v)
2883 +{
2884 + auto p = a;
2885 + auto end = a+n;
2886 + while (p !is end)
2887 + *p++ = v;
2888 +}
2889 +
2890 +void _d_array_init_cfloat(cfloat* a, size_t n, cfloat v)
2891 +{
2892 + auto p = a;
2893 + auto end = a+n;
2894 + while (p !is end)
2895 + *p++ = v;
2896 +}
2897 +
2898 +void _d_array_init_cdouble(cdouble* a, size_t n, cdouble v)
2899 +{
2900 + auto p = a;
2901 + auto end = a+n;
2902 + while (p !is end)
2903 + *p++ = v;
2904 +}
2905 +
2906 +void _d_array_init_creal(creal* a, size_t n, creal v)
2907 +{
2908 + auto p = a;
2909 + auto end = a+n;
2910 + while (p !is end)
2911 + *p++ = v;
2912 +}
2913 +
2914 +void _d_array_init_pointer(void** a, size_t n, void* v)
2915 +{
2916 + auto p = a;
2917 + auto end = a+n;
2918 + while (p !is end)
2919 + *p++ = v;
2920 +}
2921 +
2922 +void _d_array_init_mem(void* a, size_t na, void* v, size_t nv)
2923 +{
2924 + auto p = a;
2925 + auto end = a + na*nv;
2926 + while (p !is end) {
2927 + llvm_memcpy(p,v,nv,0);
2928 + p += nv;
2929 + }
2930 +}
2931 +
2932 +/*
2933 +void _d_array_init(TypeInfo ti, void* a)
2934 +{
2935 + auto initializer = ti.next.init();
2936 + auto isize = initializer.length;
2937 + auto q = initializer.ptr;
2938 +
2939 + if (isize == 1)
2940 + memset(p, *cast(ubyte*)q, size);
2941 + else if (isize == int.sizeof)
2942 + {
2943 + int init = *cast(int*)q;
2944 + size /= int.sizeof;
2945 + for (size_t u = 0; u < size; u++)
2946 + {
2947 + (cast(int*)p)[u] = init;
2948 + }
2949 + }
2950 + else
2951 + {
2952 + for (size_t u = 0; u < size; u += isize)
2953 + {
2954 + memcpy(p + u, q, isize);
2955 + }
2956 + }
2957 +}*/
2958 +
2959 +// for array cast
2960 +size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
2961 +{
2962 + if (newelemsz == 1) {
2963 + return len*elemsz;
2964 + }
2965 + else if ((len*elemsz) % newelemsz) {
2966 + throw new Exception("Bad array cast");
2967 + }
2968 + return (len*elemsz)/newelemsz;
2969 +}
2970 Index: src/compiler/ldc/genobj.d
2971 ===================================================================
2972 --- src/compiler/ldc/genobj.d (revision 0)
2973 +++ src/compiler/ldc/genobj.d (revision 0)
2974 @@ -0,0 +1,1527 @@
2975 +/**
2976 + * Part of the D programming language runtime library.
2977 + * Forms the symbols available to all D programs. Includes
2978 + * Object, which is the root of the class object hierarchy.
2979 + *
2980 + * This module is implicitly imported.
2981 + * Macros:
2982 + * WIKI = Object
2983 + */
2984 +
2985 +/*
2986 + * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
2987 + * Written by Walter Bright
2988 + *
2989 + * This software is provided 'as-is', without any express or implied
2990 + * warranty. In no event will the authors be held liable for any damages
2991 + * arising from the use of this software.
2992 + *
2993 + * Permission is granted to anyone to use this software for any purpose,
2994 + * including commercial applications, and to alter it and redistribute it
2995 + * freely, in both source and binary form, subject to the following
2996 + * restrictions:
2997 + *
2998 + * o The origin of this software must not be misrepresented; you must not
2999 + * claim that you wrote the original software. If you use this software
3000 + * in a product, an acknowledgment in the product documentation would be
3001 + * appreciated but is not required.
3002 + * o Altered source versions must be plainly marked as such, and must not
3003 + * be misrepresented as being the original software.
3004 + * o This notice may not be removed or altered from any source
3005 + * distribution.
3006 + */
3007 +
3008 +/*
3009 + * Modified by Sean Kelly for use with the D Runtime Project
3010 + */
3011 +
3012 +/*
3013 + * Modified by Tomas Lindquist Olsen for use with the LLVM D Compiler
3014 + */
3015 +
3016 +module object;
3017 +
3018 +//debug = PRINTF;
3019 +
3020 +private
3021 +{
3022 + import core.stdc.string;
3023 + import core.stdc.stdlib;
3024 + import util.string;
3025 + debug(PRINTF) import core.stdc.stdio;
3026 +
3027 + extern (C) void onOutOfMemoryError();
3028 + extern (C) Object _d_allocclass(ClassInfo ci);
3029 +}
3030 +
3031 +// NOTE: For some reason, this declaration method doesn't work
3032 +// in this particular file (and this file only). It must
3033 +// be a DMD thing.
3034 +//alias typeof(int.sizeof) size_t;
3035 +//alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
3036 +
3037 +version(X86_64)
3038 +{
3039 + alias ulong size_t;
3040 + alias long ptrdiff_t;
3041 +}
3042 +else
3043 +{
3044 + alias uint size_t;
3045 + alias int ptrdiff_t;
3046 +}
3047 +
3048 +alias size_t hash_t;
3049 +alias bool equals_t;
3050 +
3051 +alias invariant(char)[] string;
3052 +alias invariant(wchar)[] wstring;
3053 +alias invariant(dchar)[] dstring;
3054 +
3055 +/**
3056 + * All D class objects inherit from Object.
3057 + */
3058 +class Object
3059 +{
3060 + /**
3061 + * Convert Object to a human readable string.
3062 + */
3063 + string toString()
3064 + {
3065 + return this.classinfo.name;
3066 + }
3067 +
3068 + /**
3069 + * Compute hash function for Object.
3070 + */
3071 + hash_t toHash()
3072 + {
3073 + // BUG: this prevents a compacting GC from working, needs to be fixed
3074 + return cast(hash_t)cast(void*)this;
3075 + }
3076 +
3077 + /**
3078 + * Compare with another Object obj.
3079 + * Returns:
3080 + * $(TABLE
3081 + * $(TR $(TD this &lt; obj) $(TD &lt; 0))
3082 + * $(TR $(TD this == obj) $(TD 0))
3083 + * $(TR $(TD this &gt; obj) $(TD &gt; 0))
3084 + * )
3085 + */
3086 + int opCmp(Object o)
3087 + {
3088 + // BUG: this prevents a compacting GC from working, needs to be fixed
3089 + //return cast(int)cast(void*)this - cast(int)cast(void*)o;
3090 +
3091 + throw new Exception("need opCmp for class " ~ this.classinfo.name);
3092 + //return this !is o;
3093 + }
3094 +
3095 + /**
3096 + * Returns !=0 if this object does have the same contents as obj.
3097 + */
3098 + equals_t opEquals(Object o)
3099 + {
3100 + return this is o;
3101 + }
3102 +
3103 + interface Monitor
3104 + {
3105 + void lock();
3106 + void unlock();
3107 + }
3108 +
3109 + /**
3110 + * Create instance of class specified by classname.
3111 + * The class must either have no constructors or have
3112 + * a default constructor.
3113 + * Returns:
3114 + * null if failed
3115 + */
3116 + static Object factory(string classname)
3117 + {
3118 + auto ci = ClassInfo.find(classname);
3119 + if (ci)
3120 + {
3121 + return ci.create();
3122 + }
3123 + return null;
3124 + }
3125 +}
3126 +
3127 +/**
3128 + * Information about an interface.
3129 + * When an object is accessed via an interface, an Interface* appears as the
3130 + * first entry in its vtbl.
3131 + */
3132 +struct Interface
3133 +{
3134 + ClassInfo classinfo; /// .classinfo for this interface (not for containing class)
3135 + void*[] vtbl;
3136 + ptrdiff_t offset; /// offset to Interface 'this' from Object 'this'
3137 +}
3138 +
3139 +/**
3140 + * Runtime type information about a class. Can be retrieved for any class type
3141 + * or instance by using the .classinfo property.
3142 + * A pointer to this appears as the first entry in the class's vtbl[].
3143 + */
3144 +class ClassInfo : Object
3145 +{
3146 + byte[] init; /** class static initializer
3147 + * (init.length gives size in bytes of class)
3148 + */
3149 + string name; /// class name
3150 + void*[] vtbl; /// virtual function pointer table
3151 + Interface[] interfaces; /// interfaces this class implements
3152 + ClassInfo base; /// base class
3153 + void* destructor;
3154 + void function(Object) classInvariant;
3155 + uint flags;
3156 + // 1: // is IUnknown or is derived from IUnknown
3157 + // 2: // has no possible pointers into GC memory
3158 + // 4: // has offTi[] member
3159 + // 8: // has constructors
3160 + // 16: // has xgetMembers member
3161 + void* deallocator;
3162 + OffsetTypeInfo[] offTi;
3163 + void function(Object) defaultConstructor; // default Constructor
3164 + const(MemberInfo[]) function(in char[]) xgetMembers;
3165 +
3166 + /**
3167 + * Search all modules for ClassInfo corresponding to classname.
3168 + * Returns: null if not found
3169 + */
3170 + static ClassInfo find(in char[] classname)
3171 + {
3172 + foreach (m; ModuleInfo)
3173 + {
3174 + //writefln("module %s, %d", m.name, m.localClasses.length);
3175 + foreach (c; m.localClasses)
3176 + {
3177 + //writefln("\tclass %s", c.name);
3178 + if (c.name == classname)
3179 + return c;
3180 + }
3181 + }
3182 + return null;
3183 + }
3184 +
3185 + /**
3186 + * Create instance of Object represented by 'this'.
3187 + */
3188 + Object create()
3189 + {
3190 + if (flags & 8 && !defaultConstructor)
3191 + return null;
3192 +
3193 + Object o = _d_allocclass(this);
3194 + // initialize it
3195 + (cast(byte*) o)[0 .. init.length] = init[];
3196 +
3197 + if (flags & 8 && defaultConstructor)
3198 + {
3199 + defaultConstructor(o);
3200 + }
3201 + return o;
3202 + }
3203 +
3204 + /**
3205 + * Search for all members with the name 'name'.
3206 + * If name[] is null, return all members.
3207 + */
3208 + const(MemberInfo[]) getMembers(in char[] name)
3209 + {
3210 + if (flags & 16 && xgetMembers)
3211 + return xgetMembers(name);
3212 + return null;
3213 + }
3214 +}
3215 +
3216 +/**
3217 + * Array of pairs giving the offset and type information for each
3218 + * member in an aggregate.
3219 + */
3220 +struct OffsetTypeInfo
3221 +{
3222 + size_t offset; /// Offset of member from start of object
3223 + TypeInfo ti; /// TypeInfo for this member
3224 +}
3225 +
3226 +/**
3227 + * Runtime type information about a type.
3228 + * Can be retrieved for any type using a
3229 + * <a href="../expression.html#typeidexpression">TypeidExpression</a>.
3230 + */
3231 +class TypeInfo
3232 +{
3233 + override hash_t toHash()
3234 + {
3235 + hash_t hash;
3236 +
3237 + foreach (char c; this.toString())
3238 + hash = hash * 9 + c;
3239 + return hash;
3240 + }
3241 +
3242 + override int opCmp(Object o)
3243 + {
3244 + if (this is o)
3245 + return 0;
3246 + TypeInfo ti = cast(TypeInfo)o;
3247 + if (ti is null)
3248 + return 1;
3249 + return dstrcmp(this.toString(), ti.toString());
3250 + }
3251 +
3252 + override equals_t opEquals(Object o)
3253 + {
3254 + /* TypeInfo instances are singletons, but duplicates can exist
3255 + * across DLL's. Therefore, comparing for a name match is
3256 + * sufficient.
3257 + */
3258 + if (this is o)
3259 + return true;
3260 + TypeInfo ti = cast(TypeInfo)o;
3261 + return ti && this.toString() == ti.toString();
3262 + }
3263 +
3264 + /// Returns a hash of the instance of a type.
3265 + hash_t getHash(in void* p) { return cast(hash_t)p; }
3266 +
3267 + /// Compares two instances for equality.
3268 + equals_t equals(in void* p1, in void* p2) { return p1 == p2; }
3269 +
3270 + /// Compares two instances for &lt;, ==, or &gt;.
3271 + int compare(in void* p1, in void* p2) { return 0; }
3272 +
3273 + /// Returns size of the type.
3274 + size_t tsize() { return 0; }
3275 +
3276 + /// Swaps two instances of the type.
3277 + void swap(void* p1, void* p2)
3278 + {
3279 + size_t n = tsize();
3280 + for (size_t i = 0; i < n; i++)
3281 + {
3282 + byte t = (cast(byte *)p1)[i];
3283 + (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
3284 + (cast(byte*)p2)[i] = t;
3285 + }
3286 + }
3287 +
3288 + /// Get TypeInfo for 'next' type, as defined by what kind of type this is,
3289 + /// null if none.
3290 + TypeInfo next() { return null; }
3291 +
3292 + /// Return default initializer, null if default initialize to 0
3293 + void[] init() { return null; }
3294 +
3295 + /// Get flags for type: 1 means GC should scan for pointers
3296 + uint flags() { return 0; }
3297 +
3298 + /// Get type information on the contents of the type; null if not available
3299 + OffsetTypeInfo[] offTi() { return null; }
3300 + /// Run the destructor on the object and all its sub-objects
3301 + void destroy(void* p) {}
3302 + /// Run the postblit on the object and all its sub-objects
3303 + void postblit(void* p) {}
3304 +}
3305 +
3306 +class TypeInfo_Typedef : TypeInfo
3307 +{
3308 + override string toString() { return name; }
3309 +
3310 + override equals_t opEquals(Object o)
3311 + {
3312 + TypeInfo_Typedef c;
3313 + return this is o ||
3314 + ((c = cast(TypeInfo_Typedef)o) !is null &&
3315 + this.name == c.name &&
3316 + this.base == c.base);
3317 + }
3318 +
3319 + override hash_t getHash(in void* p) { return base.getHash(p); }
3320 + override equals_t equals(in void* p1, in void* p2) { return base.equals(p1, p2); }
3321 + override int compare(in void* p1, in void* p2) { return base.compare(p1, p2); }
3322 + override size_t tsize() { return base.tsize(); }
3323 + override void swap(void* p1, void* p2) { return base.swap(p1, p2); }
3324 +
3325 + override TypeInfo next() { return base.next(); }
3326 + override uint flags() { return base.flags(); }
3327 + override void[] init() { return m_init.length ? m_init : base.init(); }
3328 +
3329 + TypeInfo base;
3330 + string name;
3331 + void[] m_init;
3332 +}
3333 +
3334 +class TypeInfo_Enum : TypeInfo_Typedef
3335 +{
3336 +
3337 +}
3338 +
3339 +class TypeInfo_Pointer : TypeInfo
3340 +{
3341 + override string toString() { return m_next.toString() ~ "*"; }
3342 +
3343 + override equals_t opEquals(Object o)
3344 + {
3345 + TypeInfo_Pointer c;
3346 + return this is o ||
3347 + ((c = cast(TypeInfo_Pointer)o) !is null &&
3348 + this.m_next == c.m_next);
3349 + }
3350 +
3351 + override hash_t getHash(in void* p)
3352 + {
3353 + return cast(hash_t)*cast(void**)p;
3354 + }
3355 +
3356 + override equals_t equals(in void* p1, in void* p2)
3357 + {
3358 + return *cast(void**)p1 == *cast(void**)p2;
3359 + }
3360 +
3361 + override int compare(in void* p1, in void* p2)
3362 + {
3363 + if (*cast(void**)p1 < *cast(void**)p2)
3364 + return -1;
3365 + else if (*cast(void**)p1 > *cast(void**)p2)
3366 + return 1;
3367 + else
3368 + return 0;
3369 + }
3370 +
3371 + override size_t tsize()
3372 + {
3373 + return (void*).sizeof;
3374 + }
3375 +
3376 + override void swap(void* p1, void* p2)
3377 + {
3378 + void* tmp = *cast(void**)p1;
3379 + *cast(void**)p1 = *cast(void**)p2;
3380 + *cast(void**)p2 = tmp;
3381 + }
3382 +
3383 + override TypeInfo next() { return m_next; }
3384 + override uint flags() { return 1; }
3385 +
3386 + TypeInfo m_next;
3387 +}
3388 +
3389 +class TypeInfo_Array : TypeInfo
3390 +{
3391 + override string toString() { return value.toString() ~ "[]"; }
3392 +
3393 + override equals_t opEquals(Object o)
3394 + {
3395 + TypeInfo_Array c;
3396 + return this is o ||
3397 + ((c = cast(TypeInfo_Array)o) !is null &&
3398 + this.value == c.value);
3399 + }
3400 +
3401 + override hash_t getHash(in void* p)
3402 + {
3403 + size_t sz = value.tsize();
3404 + hash_t hash = 0;
3405 + void[] a = *cast(void[]*)p;
3406 + for (size_t i = 0; i < a.length; i++)
3407 + hash += value.getHash(a.ptr + i * sz);
3408 + return hash;
3409 + }
3410 +
3411 + override equals_t equals(in void* p1, in void* p2)
3412 + {
3413 + void[] a1 = *cast(void[]*)p1;
3414 + void[] a2 = *cast(void[]*)p2;
3415 + if (a1.length != a2.length)
3416 + return false;
3417 + size_t sz = value.tsize();
3418 + for (size_t i = 0; i < a1.length; i++)
3419 + {
3420 + if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))
3421 + return false;
3422 + }
3423 + return true;
3424 + }
3425 +
3426 + override int compare(in void* p1, in void* p2)
3427 + {
3428 + void[] a1 = *cast(void[]*)p1;
3429 + void[] a2 = *cast(void[]*)p2;
3430 + size_t sz = value.tsize();
3431 + size_t len = a1.length;
3432 +
3433 + if (a2.length < len)
3434 + len = a2.length;
3435 + for (size_t u = 0; u < len; u++)
3436 + {
3437 + int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
3438 + if (result)
3439 + return result;
3440 + }
3441 + return cast(int)a1.length - cast(int)a2.length;
3442 + }
3443 +
3444 + override size_t tsize()
3445 + {
3446 + return (void[]).sizeof;
3447 + }
3448 +
3449 + override void swap(void* p1, void* p2)
3450 + {
3451 + void[] tmp = *cast(void[]*)p1;
3452 + *cast(void[]*)p1 = *cast(void[]*)p2;
3453 + *cast(void[]*)p2 = tmp;
3454 + }
3455 +
3456 + TypeInfo value;
3457 +
3458 + override TypeInfo next()
3459 + {
3460 + return value;
3461 + }
3462 +
3463 + override uint flags() { return 1; }
3464 +}
3465 +
3466 +class TypeInfo_StaticArray : TypeInfo
3467 +{
3468 + override string toString()
3469 + {
3470 + char[10] tmp = void;
3471 + return cast(string)(value.toString() ~ "[" ~ tmp.intToString(len) ~ "]");
3472 + }
3473 +
3474 + override equals_t opEquals(Object o)
3475 + {
3476 + TypeInfo_StaticArray c;
3477 + return this is o ||
3478 + ((c = cast(TypeInfo_StaticArray)o) !is null &&
3479 + this.len == c.len &&
3480 + this.value == c.value);
3481 + }
3482 +
3483 + override hash_t getHash(in void* p)
3484 + {
3485 + size_t sz = value.tsize();
3486 + hash_t hash = 0;
3487 + for (size_t i = 0; i < len; i++)
3488 + hash += value.getHash(p + i * sz);
3489 + return hash;
3490 + }
3491 +
3492 + override equals_t equals(in void* p1, in void* p2)
3493 + {
3494 + size_t sz = value.tsize();
3495 +
3496 + for (size_t u = 0; u < len; u++)
3497 + {
3498 + if (!value.equals(p1 + u * sz, p2 + u * sz))
3499 + return false;
3500 + }
3501 + return true;
3502 + }
3503 +
3504 + override int compare(in void* p1, in void* p2)
3505 + {
3506 + size_t sz = value.tsize();
3507 +
3508 + for (size_t u = 0; u < len; u++)
3509 + {
3510 + int result = value.compare(p1 + u * sz, p2 + u * sz);
3511 + if (result)
3512 + return result;
3513 + }
3514 + return 0;
3515 + }
3516 +
3517 + override size_t tsize()
3518 + {
3519 + return len * value.tsize();
3520 + }
3521 +
3522 + override void swap(void* p1, void* p2)
3523 + {
3524 + void* tmp;
3525 + size_t sz = value.tsize();
3526 + ubyte[16] buffer;
3527 + void* pbuffer;
3528 +
3529 + if (sz < buffer.sizeof)
3530 + tmp = buffer.ptr;
3531 + else
3532 + tmp = pbuffer = (new void[sz]).ptr;
3533 +
3534 + for (size_t u = 0; u < len; u += sz)
3535 + { size_t o = u * sz;
3536 + memcpy(tmp, p1 + o, sz);
3537 + memcpy(p1 + o, p2 + o, sz);
3538 + memcpy(p2 + o, tmp, sz);
3539 + }
3540 + if (pbuffer)
3541 + delete pbuffer;
3542 + }
3543 +
3544 + override void[] init() { return value.init(); }
3545 + override TypeInfo next() { return value; }
3546 + override uint flags() { return value.flags(); }
3547 +
3548 + override void destroy(void* p)
3549 + {
3550 + auto sz = value.tsize();
3551 + p += sz * len;
3552 + foreach (i; 0 .. len)
3553 + {
3554 + p -= sz;
3555 + value.destroy(p);
3556 + }
3557 + }
3558 +
3559 + override void postblit(void* p)
3560 + {
3561 + auto sz = value.tsize();
3562 + foreach (i; 0 .. len)
3563 + {
3564 + value.postblit(p);
3565 + p += sz;
3566 + }
3567 + }
3568 +
3569 + TypeInfo value;
3570 + size_t len;
3571 +}
3572 +
3573 +class TypeInfo_AssociativeArray : TypeInfo
3574 +{
3575 + override string toString()
3576 + {
3577 + return cast(string)(next.toString() ~ "[" ~ key.toString() ~ "]");
3578 + }
3579 +
3580 + override equals_t opEquals(Object o)
3581 + {
3582 + TypeInfo_AssociativeArray c;
3583 + return this is o ||
3584 + ((c = cast(TypeInfo_AssociativeArray)o) !is null &&
3585 + this.key == c.key &&
3586 + this.value == c.value);
3587 + }
3588 +
3589 + // BUG: need to add the rest of the functions
3590 +
3591 + override size_t tsize()
3592 + {
3593 + return (char[int]).sizeof;
3594 + }
3595 +
3596 + override TypeInfo next() { return value; }
3597 + override uint flags() { return 1; }
3598 +
3599 + TypeInfo value;
3600 + TypeInfo key;
3601 +}
3602 +
3603 +class TypeInfo_Function : TypeInfo
3604 +{
3605 + override string toString()
3606 + {
3607 + return cast(string)(next.toString() ~ "()");
3608 + }
3609 +
3610 + override equals_t opEquals(Object o)
3611 + {
3612 + TypeInfo_Function c;
3613 + return this is o ||
3614 + ((c = cast(TypeInfo_Function)o) !is null &&
3615 + this.next == c.next);
3616 + }
3617 +
3618 + // BUG: need to add the rest of the functions
3619 +
3620 + override size_t tsize()
3621 + {
3622 + return 0; // no size for functions
3623 + }
3624 +
3625 + TypeInfo next;
3626 +}
3627 +
3628 +class TypeInfo_Delegate : TypeInfo
3629 +{
3630 + override string toString()
3631 + {
3632 + return cast(string)(next.toString() ~ " delegate()");
3633 + }
3634 +
3635 + override equals_t opEquals(Object o)
3636 + {
3637 + TypeInfo_Delegate c;
3638 + return this is o ||
3639 + ((c = cast(TypeInfo_Delegate)o) !is null &&
3640 + this.next == c.next);
3641 + }
3642 +
3643 + // BUG: need to add the rest of the functions
3644 +
3645 + override size_t tsize()
3646 + {
3647 + alias int delegate() dg;
3648 + return dg.sizeof;
3649 + }
3650 +
3651 + override uint flags() { return 1; }
3652 +
3653 + TypeInfo next;
3654 +}
3655 +
3656 +class TypeInfo_Class : TypeInfo
3657 +{
3658 + override string toString() { return info.name; }
3659 +
3660 + override equals_t opEquals(Object o)
3661 + {
3662 + TypeInfo_Class c;
3663 + return this is o ||
3664 + ((c = cast(TypeInfo_Class)o) !is null &&
3665 + this.info.name == c.classinfo.name);
3666 + }
3667 +
3668 + override hash_t getHash(in void* p)
3669 + {
3670 + Object o = *cast(Object*)p;
3671 + return o ? o.toHash() : 0;
3672 + }
3673 +
3674 + override equals_t equals(in void* p1, in void* p2)
3675 + {
3676 + Object o1 = *cast(Object*)p1;
3677 + Object o2 = *cast(Object*)p2;
3678 +
3679 + return (o1 is o2) || (o1 && o1.opEquals(o2));
3680 + }
3681 +
3682 + override int compare(in void* p1, in void* p2)
3683 + {
3684 + Object o1 = *cast(Object*)p1;
3685 + Object o2 = *cast(Object*)p2;
3686 + int c = 0;
3687 +
3688 + // Regard null references as always being "less than"
3689 + if (o1 !is o2)
3690 + {
3691 + if (o1)
3692 + {
3693 + if (!o2)
3694 + c = 1;
3695 + else
3696 + c = o1.opCmp(o2);
3697 + }
3698 + else
3699 + c = -1;
3700 + }
3701 + return c;
3702 + }
3703 +
3704 + override size_t tsize()
3705 + {
3706 + return Object.sizeof;
3707 + }
3708 +
3709 + override uint flags() { return 1; }
3710 +
3711 + override OffsetTypeInfo[] offTi()
3712 + {
3713 + return (info.flags & 4) ? info.offTi : null;
3714 + }
3715 +
3716 + ClassInfo info;
3717 +}
3718 +
3719 +class TypeInfo_Interface : TypeInfo
3720 +{
3721 + override string toString() { return info.name; }
3722 +
3723 + override equals_t opEquals(Object o)
3724 + {
3725 + TypeInfo_Interface c;
3726 + return this is o ||
3727 + ((c = cast(TypeInfo_Interface)o) !is null &&
3728 + this.info.name == c.classinfo.name);
3729 + }
3730 +
3731 + override hash_t getHash(in void* p)
3732 + {
3733 + Interface* pi = **cast(Interface ***)*cast(void**)p;
3734 + Object o = cast(Object)(*cast(void**)p - pi.offset);
3735 + assert(o);
3736 + return o.toHash();
3737 + }
3738 +
3739 + override equals_t equals(in void* p1, in void* p2)
3740 + {
3741 + Interface* pi = **cast(Interface ***)*cast(void**)p1;
3742 + Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
3743 + pi = **cast(Interface ***)*cast(void**)p2;
3744 + Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
3745 +
3746 + return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
3747 + }
3748 +
3749 + override int compare(in void* p1, in void* p2)
3750 + {
3751 + Interface* pi = **cast(Interface ***)*cast(void**)p1;
3752 + Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
3753 + pi = **cast(Interface ***)*cast(void**)p2;
3754 + Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
3755 + int c = 0;
3756 +
3757 + // Regard null references as always being "less than"
3758 + if (o1 != o2)
3759 + {
3760 + if (o1)
3761 + {
3762 + if (!o2)
3763 + c = 1;
3764 + else
3765 + c = o1.opCmp(o2);
3766 + }
3767 + else
3768 + c = -1;
3769 + }
3770 + return c;
3771 + }
3772 +
3773 + override size_t tsize()
3774 + {
3775 + return Object.sizeof;
3776 + }
3777 +
3778 + override uint flags() { return 1; }
3779 +
3780 + ClassInfo info;
3781 +}
3782 +
3783 +class TypeInfo_Struct : TypeInfo
3784 +{
3785 + override string toString() { return name; }
3786 +
3787 + override equals_t opEquals(Object o)
3788 + {
3789 + TypeInfo_Struct s;
3790 + return this is o ||
3791 + ((s = cast(TypeInfo_Struct)o) !is null &&
3792 + this.name == s.name &&
3793 + this.init.length == s.init.length);
3794 + }
3795 +
3796 + override hash_t getHash(in void* p)
3797 + {
3798 + assert(p);
3799 + if (xtoHash)
3800 + {
3801 + debug(PRINTF) printf("getHash() using xtoHash\n");
3802 + return (*xtoHash)(p);
3803 + }
3804 + else
3805 + {
3806 + hash_t h;
3807 + debug(PRINTF) printf("getHash() using default hash\n");
3808 + // A sorry hash algorithm.
3809 + // Should use the one for strings.
3810 + // BUG: relies on the GC not moving objects
3811 + auto q = cast(const(ubyte)*)p;
3812 + for (size_t i = 0; i < init.length; i++)
3813 + {
3814 + h = h * 9 + *q;
3815 + q++;
3816 + }
3817 + return h;
3818 + }
3819 + }
3820 +
3821 + override equals_t equals(in void* p1, in void* p2)
3822 + {
3823 + if (p1 == p2)
3824 + return true;
3825 + else if (!p1 || !p2)
3826 + return false;
3827 + else if (xopEquals)
3828 + return (*xopEquals)(p1, p2);
3829 + else
3830 + // BUG: relies on the GC not moving objects
3831 + return memcmp(p1, p2, init.length) == 0;
3832 + }
3833 +
3834 + override int compare(in void* p1, in void* p2)
3835 + {
3836 + // Regard null references as always being "less than"
3837 + if (p1 != p2)
3838 + {
3839 + if (p1)
3840 + {
3841 + if (!p2)
3842 + return true;
3843 + else if (xopCmp)
3844 + return (*xopCmp)(p2, p1);
3845 + else
3846 + // BUG: relies on the GC not moving objects
3847 + return memcmp(p1, p2, init.length);
3848 + }
3849 + else
3850 + return -1;
3851 + }
3852 + return 0;
3853 + }
3854 +
3855 + override size_t tsize()
3856 + {
3857 + return init.length;
3858 + }
3859 +
3860 + override void[] init() { return m_init; }
3861 +
3862 + override uint flags() { return m_flags; }
3863 +
3864 + override void destroy(void* p)
3865 + {
3866 + if (xdtor)
3867 + (*xdtor)(p);
3868 + }
3869 +
3870 + override void postblit(void* p)
3871 + {
3872 + if (xpostblit)
3873 + (*xpostblit)(p);
3874 + }
3875 +
3876 + string name;
3877 + void[] m_init; // initializer; init.ptr == null if 0 initialize
3878 +
3879 + hash_t function(in void*) xtoHash;
3880 + equals_t function(in void*, in void*) xopEquals;
3881 + int function(in void*, in void*) xopCmp;
3882 + char[] function(in void*) xtoString;
3883 +
3884 + uint m_flags;
3885 +
3886 + const(MemberInfo[]) function(in char[]) xgetMembers;
3887 + void function(void*) xdtor;
3888 + void function(void*) xpostblit;
3889 +}
3890 +
3891 +class TypeInfo_Tuple : TypeInfo
3892 +{
3893 + TypeInfo[] elements;
3894 +
3895 + override string toString()
3896 + {
3897 + string s = "(";
3898 + foreach (i, element; elements)
3899 + {
3900 + if (i)
3901 + s ~= ',';
3902 + s ~= element.toString();
3903 + }
3904 + s ~= ")";
3905 + return s;
3906 + }
3907 +
3908 + override equals_t opEquals(Object o)
3909 + {
3910 + if (this is o)
3911 + return true;
3912 +
3913 + auto t = cast(TypeInfo_Tuple)o;
3914 + if (t && elements.length == t.elements.length)
3915 + {
3916 + for (size_t i = 0; i < elements.length; i++)
3917 + {
3918 + if (elements[i] != t.elements[i])
3919 + return false;
3920 + }
3921 + return true;
3922 + }
3923 + return false;
3924 + }
3925 +
3926 + override hash_t getHash(in void* p)
3927 + {
3928 + assert(0);
3929 + }
3930 +
3931 + override equals_t equals(in void* p1, in void* p2)
3932 + {
3933 + assert(0);
3934 + }
3935 +
3936 + override int compare(in void* p1, in void* p2)
3937 + {
3938 + assert(0);
3939 + }
3940 +
3941 + override size_t tsize()
3942 + {
3943 + assert(0);
3944 + }
3945 +
3946 + override void swap(void* p1, void* p2)
3947 + {
3948 + assert(0);
3949 + }
3950 +
3951 + override void destroy(void* p)
3952 + {
3953 + assert(0);
3954 + }
3955 +
3956 + override void postblit(void* p)
3957 + {
3958 + assert(0);
3959 + }
3960 +}
3961 +
3962 +class TypeInfo_Const : TypeInfo
3963 +{
3964 + override string toString()
3965 + {
3966 + return cast(string) ("const(" ~ base.toString() ~ ")");
3967 + }
3968 +
3969 + override equals_t opEquals(Object o) { return base.opEquals(o); }
3970 + override hash_t getHash(in void *p) { return base.getHash(p); }
3971 + override equals_t equals(in void *p1, in void *p2) { return base.equals(p1, p2); }
3972 + override int compare(in void *p1, in void *p2) { return base.compare(p1, p2); }
3973 + override size_t tsize() { return base.tsize(); }
3974 + override void swap(void *p1, void *p2) { return base.swap(p1, p2); }
3975 +
3976 + override TypeInfo next() { return base.next(); }
3977 + override uint flags() { return base.flags(); }
3978 + override void[] init() { return base.init(); }
3979 +
3980 + TypeInfo base;
3981 +}
3982 +
3983 +class TypeInfo_Invariant : TypeInfo_Const
3984 +{
3985 + override string toString()
3986 + {
3987 + return cast(string) ("invariant(" ~ base.toString() ~ ")");
3988 + }
3989 +}
3990 +
3991 +abstract class MemberInfo
3992 +{
3993 + string name();
3994 +}
3995 +
3996 +class MemberInfo_field : MemberInfo
3997 +{
3998 + this(string name, TypeInfo ti, size_t offset)
3999 + {
4000 + m_name = name;
4001 + m_typeinfo = ti;
4002 + m_offset = offset;
4003 + }
4004 +
4005 + override string name() { return m_name; }
4006 + TypeInfo typeInfo() { return m_typeinfo; }
4007 + size_t offset() { return m_offset; }
4008 +
4009 + string m_name;
4010 + TypeInfo m_typeinfo;
4011 + size_t m_offset;
4012 +}
4013 +
4014 +class MemberInfo_function : MemberInfo
4015 +{
4016 + this(string name, TypeInfo ti, void* fp, uint flags)
4017 + {
4018 + m_name = name;
4019 + m_typeinfo = ti;
4020 + m_fp = fp;
4021 + m_flags = flags;
4022 + }
4023 +
4024 + override string name() { return m_name; }
4025 + TypeInfo typeInfo() { return m_typeinfo; }
4026 + void* fp() { return m_fp; }
4027 + uint flags() { return m_flags; }
4028 +
4029 + string m_name;
4030 + TypeInfo m_typeinfo;
4031 + void* m_fp;
4032 + uint m_flags;
4033 +}
4034 +
4035 +
4036 +///////////////////////////////////////////////////////////////////////////////
4037 +// Throwable
4038 +///////////////////////////////////////////////////////////////////////////////
4039 +
4040 +
4041 +class Throwable : Object
4042 +{
4043 + interface TraceInfo
4044 + {
4045 + int opApply(int delegate(inout char[]));
4046 + }
4047 +
4048 + string msg;
4049 + string file;
4050 + size_t line;
4051 + TraceInfo info;
4052 + Throwable next;
4053 +
4054 + this(string msg, Throwable next = null)
4055 + {
4056 + this.msg = msg;
4057 + this.next = next;
4058 + this.info = traceContext();
4059 + }
4060 +
4061 + this(string msg, string file, size_t line, Throwable next = null)
4062 + {
4063 + this(msg, next);
4064 + this.file = file;
4065 + this.line = line;
4066 + this.info = traceContext();
4067 + }
4068 +
4069 + override string toString()
4070 + {
4071 + char[10] tmp = void;
4072 + char[] buf;
4073 +
4074 + for (Throwable e = this; e !is null; e = e.next)
4075 + {
4076 + if (e.file)
4077 + {
4078 + buf ~= e.classinfo.name ~ "@" ~ e.file ~ "(" ~ tmp.intToString(e.line) ~ "): " ~ e.msg;
4079 + }
4080 + else
4081 + {
4082 + buf ~= e.classinfo.name ~ ": " ~ e.msg;
4083 + }
4084 + if (e.info)
4085 + {
4086 + buf ~= "\n----------------";
4087 + foreach (t; e.info)
4088 + buf ~= "\n" ~ t;
4089 + }
4090 + if (e.next)
4091 + buf ~= "\n";
4092 + }
4093 + return cast(string) buf;
4094 + }
4095 +}
4096 +
4097 +
4098 +alias Throwable.TraceInfo function(void* ptr = null) TraceHandler;
4099 +private TraceHandler traceHandler = null;
4100 +
4101 +
4102 +/**
4103 + * Overrides the default trace hander with a user-supplied version.
4104 + *
4105 + * Params:
4106 + * h = The new trace handler. Set to null to use the default handler.
4107 + */
4108 +extern (C) void rt_setTraceHandler(TraceHandler h)
4109 +{
4110 + traceHandler = h;
4111 +}
4112 +
4113 +
4114 +/**
4115 + * This function will be called when an exception is constructed. The
4116 + * user-supplied trace handler will be called if one has been supplied,
4117 + * otherwise no trace will be generated.
4118 + *
4119 + * Params:
4120 + * ptr = A pointer to the location from which to generate the trace, or null
4121 + * if the trace should be generated from within the trace handler
4122 + * itself.
4123 + *
4124 + * Returns:
4125 + * An object describing the current calling context or null if no handler is
4126 + * supplied.
4127 + */
4128 +Throwable.TraceInfo traceContext(void* ptr = null)
4129 +{
4130 + if (traceHandler is null)
4131 + return null;
4132 + return traceHandler(ptr);
4133 +}
4134 +
4135 +
4136 +class Exception : Throwable
4137 +{
4138 + this(string msg, Throwable next = null)
4139 + {
4140 + super(msg, next);
4141 + }
4142 +
4143 + this(string msg, string file, size_t line, Throwable next = null)
4144 + {
4145 + super(msg, file, line, next);
4146 + }
4147 +}
4148 +
4149 +
4150 +class Error : Throwable
4151 +{
4152 + this(string msg, Throwable next = null)
4153 + {
4154 + super(msg, next);
4155 + }
4156 +
4157 + this(string msg, string file, size_t line, Throwable next = null)
4158 + {
4159 + super(msg, file, line, next);
4160 + }
4161 +}
4162 +
4163 +
4164 +///////////////////////////////////////////////////////////////////////////////
4165 +// ModuleInfo
4166 +///////////////////////////////////////////////////////////////////////////////
4167 +
4168 +
4169 +enum
4170 +{
4171 + MIctorstart = 1, // we've started constructing it
4172 + MIctordone = 2, // finished construction
4173 + MIstandalone = 4, // module ctor does not depend on other module
4174 + // ctors being done first
4175 + MIhasictor = 8, // has ictor member
4176 +}
4177 +
4178 +
4179 +class ModuleInfo
4180 +{
4181 + string name;
4182 + ModuleInfo[] importedModules;
4183 + ClassInfo[] localClasses;
4184 + uint flags;
4185 +
4186 + void function() ctor; // module static constructor (order dependent)
4187 + void function() dtor; // module static destructor
4188 + void function() unitTest; // module unit tests
4189 +
4190 + void* xgetMembers; // module getMembers() function
4191 +
4192 + void function() ictor; // module static constructor (order independent)
4193 +
4194 + static int opApply(int delegate(inout ModuleInfo) dg)
4195 + {
4196 + int ret = 0;
4197 +
4198 + foreach (m; _moduleinfo_array)
4199 + {
4200 + ret = dg(m);
4201 + if (ret)
4202 + break;
4203 + }
4204 + return ret;
4205 + }
4206 +}
4207 +
4208 +
4209 +// Windows: this gets initialized by minit.asm
4210 +// linux: this gets initialized in _moduleCtor()
4211 +extern (C) ModuleInfo[] _moduleinfo_array;
4212 +
4213 +
4214 +version (linux)
4215 +{
4216 + // This linked list is created by a compiler generated function inserted
4217 + // into the .ctor list by the compiler.
4218 + struct ModuleReference
4219 + {
4220 + ModuleReference* next;
4221 + ModuleInfo mod;
4222 + }
4223 +
4224 + extern (C) ModuleReference* _Dmodule_ref; // start of linked list
4225 +}
4226 +
4227 +ModuleInfo[] _moduleinfo_dtors;
4228 +uint _moduleinfo_dtors_i;
4229 +
4230 +// Register termination function pointers
4231 +extern (C) int _fatexit(void*);
4232 +
4233 +/**
4234 + * Initialize the modules.
4235 + */
4236 +
4237 +extern (C) void _moduleCtor()
4238 +{
4239 + debug(PRINTF) printf("_moduleCtor()\n");
4240 + version (linux)
4241 + {
4242 + int len = 0;
4243 + ModuleReference *mr;
4244 +
4245 + for (mr = _Dmodule_ref; mr; mr = mr.next)
4246 + len++;
4247 + _moduleinfo_array = new ModuleInfo[len];
4248 + len = 0;
4249 + for (mr = _Dmodule_ref; mr; mr = mr.next)
4250 + { _moduleinfo_array[len] = mr.mod;
4251 + len++;
4252 + }
4253 + }
4254 +
4255 + version (Windows)
4256 + {
4257 + // Ensure module destructors also get called on program termination
4258 + //_fatexit(&_STD_moduleDtor);
4259 + }
4260 +
4261 + _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length];
4262 + debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void*)_moduleinfo_dtors);
4263 + _moduleIndependentCtors();
4264 + _moduleCtor2(_moduleinfo_array, 0);
4265 +}
4266 +
4267 +extern (C) void _moduleIndependentCtors()
4268 +{
4269 + debug(PRINTF) printf("_moduleIndependentCtors()\n");
4270 + foreach (m; _moduleinfo_array)
4271 + {
4272 + if (m && m.flags & MIhasictor && m.ictor)
4273 + {
4274 + (*m.ictor)();
4275 + }
4276 + }
4277 +}
4278 +
4279 +void _moduleCtor2(ModuleInfo[] mi, int skip)
4280 +{
4281 + debug(PRINTF) printf("_moduleCtor2(): %d modules\n", mi.length);
4282 + for (uint i = 0; i < mi.length; i++)
4283 + {
4284 + ModuleInfo m = mi[i];
4285 +
4286 + debug(PRINTF) printf("\tmodule[%d] = '%p'\n", i, m);
4287 + if (!m)
4288 + continue;
4289 + debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name);
4290 + if (m.flags & MIctordone)
4291 + continue;
4292 + debug(PRINTF) printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m);
4293 +
4294 + if (m.ctor || m.dtor)
4295 + {
4296 + if (m.flags & MIctorstart)
4297 + { if (skip || m.flags & MIstandalone)
4298 + continue;
4299 + throw new Exception("Cyclic dependency in module " ~ m.name);
4300 + }
4301 +
4302 + m.flags |= MIctorstart;
4303 + _moduleCtor2(m.importedModules, 0);
4304 + if (m.ctor)
4305 + (*m.ctor)();
4306 + m.flags &= ~MIctorstart;
4307 + m.flags |= MIctordone;
4308 +
4309 + // Now that construction is done, register the destructor
4310 + //printf("\tadding module dtor x%x\n", m);
4311 + assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length);
4312 + _moduleinfo_dtors[_moduleinfo_dtors_i++] = m;
4313 + }
4314 + else
4315 + {
4316 + m.flags |= MIctordone;
4317 + _moduleCtor2(m.importedModules, 1);
4318 + }
4319 + }
4320 +}
4321 +
4322 +/**
4323 + * Destruct the modules.
4324 + */
4325 +
4326 +// Starting the name with "_STD" means under linux a pointer to the
4327 +// function gets put in the .dtors segment.
4328 +
4329 +extern (C) void _moduleDtor()
4330 +{
4331 + debug(PRINTF) printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i);
4332 +
4333 + for (uint i = _moduleinfo_dtors_i; i-- != 0;)
4334 + {
4335 + ModuleInfo m = _moduleinfo_dtors[i];
4336 +
4337 + debug(PRINTF) printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m);
4338 + if (m.dtor)
4339 + {
4340 + (*m.dtor)();
4341 + }
4342 + }
4343 + debug(PRINTF) printf("_moduleDtor() done\n");
4344 +}
4345 +
4346 +///////////////////////////////////////////////////////////////////////////////
4347 +// Monitor
4348 +///////////////////////////////////////////////////////////////////////////////
4349 +
4350 +alias Object.Monitor IMonitor;
4351 +alias void delegate(Object) DEvent;
4352 +
4353 +// NOTE: The dtor callback feature is only supported for monitors that are not
4354 +// supplied by the user. The assumption is that any object with a user-
4355 +// supplied monitor may have special storage or lifetime requirements and
4356 +// that as a result, storing references to local objects within Monitor
4357 +// may not be safe or desirable. Thus, devt is only valid if impl is
4358 +// null.
4359 +struct Monitor
4360 +{
4361 + IMonitor impl;
4362 + /* internal */
4363 + DEvent[] devt;
4364 + /* stuff */
4365 +}
4366 +
4367 +Monitor* getMonitor(Object h)
4368 +{
4369 + return cast(Monitor*) (cast(void**) h)[1];
4370 +}
4371 +
4372 +void setMonitor(Object h, Monitor* m)
4373 +{
4374 + (cast(void**) h)[1] = m;
4375 +}
4376 +
4377 +extern (C) void _d_monitor_create(Object);
4378 +extern (C) void _d_monitor_destroy(Object);
4379 +extern (C) void _d_monitor_lock(Object);
4380 +extern (C) int _d_monitor_unlock(Object);
4381 +
4382 +extern (C) void _d_monitordelete(Object h, bool det)
4383 +{
4384 + Monitor* m = getMonitor(h);
4385 +
4386 + if (m !is null)
4387 + {
4388 + IMonitor i = m.impl;
4389 + if (i is null)
4390 + {
4391 + _d_monitor_devt(m, h);
4392 + _d_monitor_destroy(h);
4393 + setMonitor(h, null);
4394 + return;
4395 + }
4396 + if (det && (cast(void*) i) !is (cast(void*) h))
4397 + delete i;
4398 + setMonitor(h, null);
4399 + }
4400 +}
4401 +
4402 +extern (C) void _d_monitorenter(Object h)
4403 +{
4404 + Monitor* m = getMonitor(h);
4405 +
4406 + if (m is null)
4407 + {
4408 + _d_monitor_create(h);
4409 + m = getMonitor(h);
4410 + }
4411 +
4412 + IMonitor i = m.impl;
4413 +
4414 + if (i is null)
4415 + {
4416 + _d_monitor_lock(h);
4417 + return;
4418 + }
4419 + i.lock();
4420 +}
4421 +
4422 +extern (C) void _d_monitorexit(Object h)
4423 +{
4424 + Monitor* m = getMonitor(h);
4425 + IMonitor i = m.impl;
4426 +
4427 + if (i is null)
4428 + {
4429 + _d_monitor_unlock(h);
4430 + return;
4431 + }
4432 + i.unlock();
4433 +}
4434 +
4435 +extern (C) void _d_monitor_devt(Monitor* m, Object h)
4436 +{
4437 + if (m.devt.length)
4438 + {
4439 + DEvent[] devt;
4440 +
4441 + synchronized (h)
4442 + {
4443 + devt = m.devt;
4444 + m.devt = null;
4445 + }
4446 + foreach (v; devt)
4447 + {
4448 + if (v)
4449 + v(h);
4450 + }
4451 + free(devt.ptr);
4452 + }
4453 +}
4454 +
4455 +extern (C) void rt_attachDisposeEvent(Object h, DEvent e)
4456 +{
4457 + synchronized (h)
4458 + {
4459 + Monitor* m = getMonitor(h);
4460 + assert(m.impl is null);
4461 +
4462 + foreach (inout v; m.devt)
4463 + {
4464 + if (v is null || v == e)
4465 + {
4466 + v = e;
4467 + return;
4468 + }
4469 + }
4470 +
4471 + auto len = m.devt.length + 4; // grow by 4 elements
4472 + auto pos = m.devt.length; // insert position
4473 + auto p = realloc(m.devt.ptr, DEvent.sizeof * len);
4474 + if (!p)
4475 + onOutOfMemoryError();
4476 + m.devt = (cast(DEvent*)p)[0 .. len];
4477 + m.devt[pos+1 .. len] = null;
4478 + m.devt[pos] = e;
4479 + }
4480 +}
4481 +
4482 +extern (C) void rt_detachDisposeEvent(Object h, DEvent e)
4483 +{
4484 + synchronized (h)
4485 + {
4486 + Monitor* m = getMonitor(h);
4487 + assert(m.impl is null);
4488 +
4489 + foreach (p, v; m.devt)
4490 + {
4491 + if (v == e)
4492 + {
4493 + memmove(&m.devt[p],
4494 + &m.devt[p+1],
4495 + (m.devt.length - p - 1) * DEvent.sizeof);
4496 + m.devt[$ - 1] = null;
4497 + return;
4498 + }
4499 + }
4500 + }
4501 +}
4502 Index: src/compiler/ldc/mars.h
4503 ===================================================================
4504 --- src/compiler/ldc/mars.h (revision 0)
4505 +++ src/compiler/ldc/mars.h (revision 0)
4506 @@ -0,0 +1,105 @@
4507 +
4508 +/*
4509 + * Placed into the Public Domain
4510 + * written by Walter Bright, Digital Mars
4511 + * www.digitalmars.com
4512 + */
4513 +
4514 +/*
4515 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
4516 + */
4517 +
4518 +#include <stddef.h>
4519 +
4520 +#if __cplusplus
4521 +extern "C" {
4522 +#endif
4523 +
4524 +struct ClassInfo;
4525 +struct Vtbl;
4526 +
4527 +typedef struct Vtbl
4528 +{
4529 + size_t len;
4530 + void **vptr;
4531 +} Vtbl;
4532 +
4533 +typedef struct Interface
4534 +{
4535 + struct ClassInfo *classinfo;
4536 + struct Vtbl vtbl;
4537 + int offset;
4538 +} Interface;
4539 +
4540 +typedef struct Object
4541 +{
4542 + void **vptr;
4543 + void *monitor;
4544 +} Object;
4545 +
4546 +typedef struct ClassInfo
4547 +{
4548 + Object object;
4549 +
4550 + size_t initlen;
4551 + void *init;
4552 +
4553 + size_t namelen;
4554 + char *name;
4555 +
4556 + Vtbl vtbl;
4557 +
4558 + size_t interfacelen;
4559 + Interface *interfaces;
4560 +
4561 + struct ClassInfo *baseClass;
4562 +
4563 + void *destructor;
4564 + void *invariant;
4565 +
4566 + int flags;
4567 +} ClassInfo;
4568 +
4569 +typedef struct Exception
4570 +{
4571 + Object object;
4572 +
4573 + size_t msglen;
4574 + char* msg;
4575 +
4576 + size_t filelen;
4577 + char* file;
4578 +
4579 + size_t line;
4580 +
4581 + struct Interface *info;
4582 + struct Exception *next;
4583 +} Exception;
4584 +
4585 +typedef struct Array
4586 +{
4587 + size_t length;
4588 + void *ptr;
4589 +} Array;
4590 +
4591 +typedef struct Delegate
4592 +{
4593 + void *thisptr;
4594 + void (*funcptr)();
4595 +} Delegate;
4596 +
4597 +void _d_monitorenter(Object *h);
4598 +void _d_monitorexit(Object *h);
4599 +
4600 +int _d_isbaseof(ClassInfo *b, ClassInfo *c);
4601 +Object *_d_dynamic_cast(Object *o, ClassInfo *ci);
4602 +
4603 +Object * _d_allocclass(ClassInfo *ci);
4604 +void _d_delclass(Object **p);
4605 +
4606 +void _d_OutOfMemory();
4607 +
4608 +#if __cplusplus
4609 +}
4610 +#endif
4611 +
4612 Index: src/compiler/ldc/aApplyR.d
4613 ===================================================================
4614 --- src/compiler/ldc/aApplyR.d (revision 0)
4615 +++ src/compiler/ldc/aApplyR.d (revision 0)
4616 @@ -0,0 +1,975 @@
4617 +
4618 +/**
4619 + * Part of the D programming language runtime library.
4620 + */
4621 +
4622 +/*
4623 + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
4624 + * Written by Walter Bright
4625 + *
4626 + * This software is provided 'as-is', without any express or implied
4627 + * warranty. In no event will the authors be held liable for any damages
4628 + * arising from the use of this software.
4629 + *
4630 + * Permission is granted to anyone to use this software for any purpose,
4631 + * including commercial applications, and to alter it and redistribute it
4632 + * freely, in both source and binary form, subject to the following
4633 + * restrictions:
4634 + *
4635 + * o The origin of this software must not be misrepresented; you must not
4636 + * claim that you wrote the original software. If you use this software
4637 + * in a product, an acknowledgment in the product documentation would be
4638 + * appreciated but is not required.
4639 + * o Altered source versions must be plainly marked as such, and must not
4640 + * be misrepresented as being the original software.
4641 + * o This notice may not be removed or altered from any source
4642 + * distribution.
4643 + */
4644 +
4645 +/*
4646 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
4647 + */
4648 +
4649 +/* This code handles decoding UTF strings for foreach_reverse loops.
4650 + * There are 6 combinations of conversions between char, wchar,
4651 + * and dchar, and 2 of each of those.
4652 + */
4653 +
4654 +private import util.utf;
4655 +
4656 +/**********************************************/
4657 +/* 1 argument versions */
4658 +
4659 +// dg is D, but _aApplyRcd() is C
4660 +extern (D) typedef int delegate(void *) dg_t;
4661 +
4662 +extern (C) int _aApplyRcd1(in char[] aa, dg_t dg)
4663 +{ int result;
4664 +
4665 + debug(apply) printf("_aApplyRcd1(), len = %d\n", aa.length);
4666 + for (size_t i = aa.length; i != 0; )
4667 + { dchar d;
4668 +
4669 + i--;
4670 + d = aa[i];
4671 + if (d & 0x80)
4672 + { char c = cast(char)d;
4673 + uint j;
4674 + uint m = 0x3F;
4675 + d = 0;
4676 + while ((c & 0xC0) != 0xC0)
4677 + { if (i == 0)
4678 + onUnicodeError("Invalid UTF-8 sequence", 0);
4679 + i--;
4680 + d |= (c & 0x3F) << j;
4681 + j += 6;
4682 + m >>= 1;
4683 + c = aa[i];
4684 + }
4685 + d |= (c & m) << j;
4686 + }
4687 + result = dg(cast(void *)&d);
4688 + if (result)
4689 + break;
4690 + }
4691 + return result;
4692 +}
4693 +
4694 +unittest
4695 +{
4696 + debug(apply) printf("_aApplyRcd1.unittest\n");
4697 +
4698 + char[] s = "hello"c;
4699 + int i;
4700 +
4701 + foreach_reverse(dchar d; s)
4702 + {
4703 + switch (i)
4704 + {
4705 + case 0: assert(d == 'o'); break;
4706 + case 1: assert(d == 'l'); break;
4707 + case 2: assert(d == 'l'); break;
4708 + case 3: assert(d == 'e'); break;
4709 + case 4: assert(d == 'h'); break;
4710 + default: assert(0);
4711 + }
4712 + i++;
4713 + }
4714 + assert(i == 5);
4715 +
4716 + s = "a\u1234\U00100456b";
4717 + i = 0;
4718 + foreach_reverse(dchar d; s)
4719 + {
4720 + //printf("i = %d, d = %x\n", i, d);
4721 + switch (i)
4722 + {
4723 + case 0: assert(d == 'b'); break;
4724 + case 1: assert(d == '\U00100456'); break;
4725 + case 2: assert(d == '\u1234'); break;
4726 + case 3: assert(d == 'a'); break;
4727 + default: assert(0);
4728 + }
4729 + i++;
4730 + }
4731 + assert(i == 4);
4732 +}
4733 +
4734 +/*****************************/
4735 +
4736 +extern (C) int _aApplyRwd1(in wchar[] aa, dg_t dg)
4737 +{ int result;
4738 +
4739 + debug(apply) printf("_aApplyRwd1(), len = %d\n", aa.length);
4740 + for (size_t i = aa.length; i != 0; )
4741 + { dchar d;
4742 +
4743 + i--;
4744 + d = aa[i];
4745 + if (d >= 0xDC00 && d <= 0xDFFF)
4746 + { if (i == 0)
4747 + onUnicodeError("Invalid UTF-16 sequence", 0);
4748 + i--;
4749 + d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
4750 + }
4751 + result = dg(cast(void *)&d);
4752 + if (result)
4753 + break;
4754 + }
4755 + return result;
4756 +}
4757 +
4758 +unittest
4759 +{
4760 + debug(apply) printf("_aApplyRwd1.unittest\n");
4761 +
4762 + wchar[] s = "hello"w;
4763 + int i;
4764 +
4765 + foreach_reverse(dchar d; s)
4766 + {
4767 + switch (i)
4768 + {
4769 + case 0: assert(d == 'o'); break;
4770 + case 1: assert(d == 'l'); break;
4771 + case 2: assert(d == 'l'); break;
4772 + case 3: assert(d == 'e'); break;
4773 + case 4: assert(d == 'h'); break;
4774 + default: assert(0);
4775 + }
4776 + i++;
4777 + }
4778 + assert(i == 5);
4779 +
4780 + s = "a\u1234\U00100456b";
4781 + i = 0;
4782 + foreach_reverse(dchar d; s)
4783 + {
4784 + //printf("i = %d, d = %x\n", i, d);
4785 + switch (i)
4786 + {
4787 + case 0: assert(d == 'b'); break;
4788 + case 1: assert(d == '\U00100456'); break;
4789 + case 2: assert(d == '\u1234'); break;
4790 + case 3: assert(d == 'a'); break;
4791 + default: assert(0);
4792 + }
4793 + i++;
4794 + }
4795 + assert(i == 4);
4796 +}
4797 +
4798 +/*****************************/
4799 +
4800 +extern (C) int _aApplyRcw1(in char[] aa, dg_t dg)
4801 +{ int result;
4802 +
4803 + debug(apply) printf("_aApplyRcw1(), len = %d\n", aa.length);
4804 + for (size_t i = aa.length; i != 0; )
4805 + { dchar d;
4806 + wchar w;
4807 +
4808 + i--;
4809 + w = aa[i];
4810 + if (w & 0x80)
4811 + { char c = cast(char)w;
4812 + uint j;
4813 + uint m = 0x3F;
4814 + d = 0;
4815 + while ((c & 0xC0) != 0xC0)
4816 + { if (i == 0)
4817 + onUnicodeError("Invalid UTF-8 sequence", 0);
4818 + i--;
4819 + d |= (c & 0x3F) << j;
4820 + j += 6;
4821 + m >>= 1;
4822 + c = aa[i];
4823 + }
4824 + d |= (c & m) << j;
4825 +
4826 + if (d <= 0xFFFF)
4827 + w = cast(wchar) d;
4828 + else
4829 + {
4830 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
4831 + result = dg(cast(void *)&w);
4832 + if (result)
4833 + break;
4834 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
4835 + }
4836 + }
4837 + result = dg(cast(void *)&w);
4838 + if (result)
4839 + break;
4840 + }
4841 + return result;
4842 +}
4843 +
4844 +unittest
4845 +{
4846 + debug(apply) printf("_aApplyRcw1.unittest\n");
4847 +
4848 + char[] s = "hello"c;
4849 + int i;
4850 +
4851 + foreach_reverse(wchar d; s)
4852 + {
4853 + switch (i)
4854 + {
4855 + case 0: assert(d == 'o'); break;
4856 + case 1: assert(d == 'l'); break;
4857 + case 2: assert(d == 'l'); break;
4858 + case 3: assert(d == 'e'); break;
4859 + case 4: assert(d == 'h'); break;
4860 + default: assert(0);
4861 + }
4862 + i++;
4863 + }
4864 + assert(i == 5);
4865 +
4866 + s = "a\u1234\U00100456b";
4867 + i = 0;
4868 + foreach_reverse(wchar d; s)
4869 + {
4870 + //printf("i = %d, d = %x\n", i, d);
4871 + switch (i)
4872 + {
4873 + case 0: assert(d == 'b'); break;
4874 + case 1: assert(d == 0xDBC1); break;
4875 + case 2: assert(d == 0xDC56); break;
4876 + case 3: assert(d == 0x1234); break;
4877 + case 4: assert(d == 'a'); break;
4878 + default: assert(0);
4879 + }
4880 + i++;
4881 + }
4882 + assert(i == 5);
4883 +}
4884 +
4885 +/*****************************/
4886 +
4887 +extern (C) int _aApplyRwc1(in wchar[] aa, dg_t dg)
4888 +{ int result;
4889 +
4890 + debug(apply) printf("_aApplyRwc1(), len = %d\n", aa.length);
4891 + for (size_t i = aa.length; i != 0; )
4892 + { dchar d;
4893 + char c;
4894 +
4895 + i--;
4896 + d = aa[i];
4897 + if (d >= 0xDC00 && d <= 0xDFFF)
4898 + { if (i == 0)
4899 + onUnicodeError("Invalid UTF-16 sequence", 0);
4900 + i--;
4901 + d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
4902 + }
4903 +
4904 + if (d & ~0x7F)
4905 + {
4906 + char[4] buf;
4907 +
4908 + auto b = toUTF8(buf, d);
4909 + foreach (char c2; b)
4910 + {
4911 + result = dg(cast(void *)&c2);
4912 + if (result)
4913 + return result;
4914 + }
4915 + continue;
4916 + }
4917 + c = cast(char)d;
4918 + result = dg(cast(void *)&c);
4919 + if (result)
4920 + break;
4921 + }
4922 + return result;
4923 +}
4924 +
4925 +unittest
4926 +{
4927 + debug(apply) printf("_aApplyRwc1.unittest\n");
4928 +
4929 + wchar[] s = "hello"w;
4930 + int i;
4931 +
4932 + foreach_reverse(char d; s)
4933 + {
4934 + switch (i)
4935 + {
4936 + case 0: assert(d == 'o'); break;
4937 + case 1: assert(d == 'l'); break;
4938 + case 2: assert(d == 'l'); break;
4939 + case 3: assert(d == 'e'); break;
4940 + case 4: assert(d == 'h'); break;
4941 + default: assert(0);
4942 + }
4943 + i++;
4944 + }
4945 + assert(i == 5);
4946 +
4947 + s = "a\u1234\U00100456b";
4948 + i = 0;
4949 + foreach_reverse(char d; s)
4950 + {
4951 + //printf("i = %d, d = %x\n", i, d);
4952 + switch (i)
4953 + {
4954 + case 0: assert(d == 'b'); break;
4955 + case 1: assert(d == 0xF4); break;
4956 + case 2: assert(d == 0x80); break;
4957 + case 3: assert(d == 0x91); break;
4958 + case 4: assert(d == 0x96); break;
4959 + case 5: assert(d == 0xE1); break;
4960 + case 6: assert(d == 0x88); break;
4961 + case 7: assert(d == 0xB4); break;
4962 + case 8: assert(d == 'a'); break;
4963 + default: assert(0);
4964 + }
4965 + i++;
4966 + }
4967 + assert(i == 9);
4968 +}
4969 +
4970 +/*****************************/
4971 +
4972 +extern (C) int _aApplyRdc1(in dchar[] aa, dg_t dg)
4973 +{ int result;
4974 +
4975 + debug(apply) printf("_aApplyRdc1(), len = %d\n", aa.length);
4976 + for (size_t i = aa.length; i != 0;)
4977 + { dchar d = aa[--i];
4978 + char c;
4979 +
4980 + if (d & ~0x7F)
4981 + {
4982 + char[4] buf;
4983 +
4984 + auto b = toUTF8(buf, d);
4985 + foreach (char c2; b)
4986 + {
4987 + result = dg(cast(void *)&c2);
4988 + if (result)
4989 + return result;
4990 + }
4991 + continue;
4992 + }
4993 + else
4994 + {
4995 + c = cast(char)d;
4996 + }
4997 + result = dg(cast(void *)&c);
4998 + if (result)
4999 + break;
5000 + }
5001 + return result;
5002 +}
5003 +
5004 +unittest
5005 +{
5006 + debug(apply) printf("_aApplyRdc1.unittest\n");
5007 +
5008 + dchar[] s = "hello"d;
5009 + int i;
5010 +
5011 + foreach_reverse(char d; s)
5012 + {
5013 + switch (i)
5014 + {
5015 + case 0: assert(d == 'o'); break;
5016 + case 1: assert(d == 'l'); break;
5017 + case 2: assert(d == 'l'); break;
5018 + case 3: assert(d == 'e'); break;
5019 + case 4: assert(d == 'h'); break;
5020 + default: assert(0);
5021 + }
5022 + i++;
5023 + }
5024 + assert(i == 5);
5025 +
5026 + s = "a\u1234\U00100456b";
5027 + i = 0;
5028 + foreach_reverse(char d; s)
5029 + {
5030 + //printf("i = %d, d = %x\n", i, d);
5031 + switch (i)
5032 + {
5033 + case 0: assert(d == 'b'); break;
5034 + case 1: assert(d == 0xF4); break;
5035 + case 2: assert(d == 0x80); break;
5036 + case 3: assert(d == 0x91); break;
5037 + case 4: assert(d == 0x96); break;
5038 + case 5: assert(d == 0xE1); break;
5039 + case 6: assert(d == 0x88); break;
5040 + case 7: assert(d == 0xB4); break;
5041 + case 8: assert(d == 'a'); break;
5042 + default: assert(0);
5043 + }
5044 + i++;
5045 + }
5046 + assert(i == 9);
5047 +}
5048 +
5049 +/*****************************/
5050 +
5051 +extern (C) int _aApplyRdw1(in dchar[] aa, dg_t dg)
5052 +{ int result;
5053 +
5054 + debug(apply) printf("_aApplyRdw1(), len = %d\n", aa.length);
5055 + for (size_t i = aa.length; i != 0; )
5056 + { dchar d = aa[--i];
5057 + wchar w;
5058 +
5059 + if (d <= 0xFFFF)
5060 + w = cast(wchar) d;
5061 + else
5062 + {
5063 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
5064 + result = dg(cast(void *)&w);
5065 + if (result)
5066 + break;
5067 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
5068 + }
5069 + result = dg(cast(void *)&w);
5070 + if (result)
5071 + break;
5072 + }
5073 + return result;
5074 +}
5075 +
5076 +unittest
5077 +{
5078 + debug(apply) printf("_aApplyRdw1.unittest\n");
5079 +
5080 + dchar[] s = "hello"d;
5081 + int i;
5082 +
5083 + foreach_reverse(wchar d; s)
5084 + {
5085 + switch (i)
5086 + {
5087 + case 0: assert(d == 'o'); break;
5088 + case 1: assert(d == 'l'); break;
5089 + case 2: assert(d == 'l'); break;
5090 + case 3: assert(d == 'e'); break;
5091 + case 4: assert(d == 'h'); break;
5092 + default: assert(0);
5093 + }
5094 + i++;
5095 + }
5096 + assert(i == 5);
5097 +
5098 + s = "a\u1234\U00100456b";
5099 + i = 0;
5100 + foreach_reverse(wchar d; s)
5101 + {
5102 + //printf("i = %d, d = %x\n", i, d);
5103 + switch (i)
5104 + {
5105 + case 0: assert(d == 'b'); break;
5106 + case 1: assert(d == 0xDBC1); break;
5107 + case 2: assert(d == 0xDC56); break;
5108 + case 3: assert(d == 0x1234); break;
5109 + case 4: assert(d == 'a'); break;
5110 + default: assert(0);
5111 + }
5112 + i++;
5113 + }
5114 + assert(i == 5);
5115 +}
5116 +
5117 +
5118 +/****************************************************************************/
5119 +/* 2 argument versions */
5120 +
5121 +// dg is D, but _aApplyRcd2() is C
5122 +extern (D) typedef int delegate(void *, void *) dg2_t;
5123 +
5124 +extern (C) int _aApplyRcd2(in char[] aa, dg2_t dg)
5125 +{ int result;
5126 + size_t i;
5127 + size_t len = aa.length;
5128 +
5129 + debug(apply) printf("_aApplyRcd2(), len = %d\n", len);
5130 + for (i = len; i != 0; )
5131 + { dchar d;
5132 +
5133 + i--;
5134 + d = aa[i];
5135 + if (d & 0x80)
5136 + { char c = cast(char)d;
5137 + uint j;
5138 + uint m = 0x3F;
5139 + d = 0;
5140 + while ((c & 0xC0) != 0xC0)
5141 + { if (i == 0)
5142 + onUnicodeError("Invalid UTF-8 sequence", 0);
5143 + i--;
5144 + d |= (c & 0x3F) << j;
5145 + j += 6;
5146 + m >>= 1;
5147 + c = aa[i];
5148 + }
5149 + d |= (c & m) << j;
5150 + }
5151 + result = dg(&i, cast(void *)&d);
5152 + if (result)
5153 + break;
5154 + }
5155 + return result;
5156 +}
5157 +
5158 +unittest
5159 +{
5160 + debug(apply) printf("_aApplyRcd2.unittest\n");
5161 +
5162 + char[] s = "hello"c;
5163 + int i;
5164 +
5165 + foreach_reverse(k, dchar d; s)
5166 + {
5167 + assert(k == 4 - i);
5168 + switch (i)
5169 + {
5170 + case 0: assert(d == 'o'); break;
5171 + case 1: assert(d == 'l'); break;
5172 + case 2: assert(d == 'l'); break;
5173 + case 3: assert(d == 'e'); break;
5174 + case 4: assert(d == 'h'); break;
5175 + default: assert(0);
5176 + }
5177 + i++;
5178 + }
5179 + assert(i == 5);
5180 +
5181 + s = "a\u1234\U00100456b";
5182 + i = 0;
5183 + foreach_reverse(k, dchar d; s)
5184 + {
5185 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5186 + switch (i)
5187 + {
5188 + case 0: assert(d == 'b'); assert(k == 8); break;
5189 + case 1: assert(d == '\U00100456'); assert(k == 4); break;
5190 + case 2: assert(d == '\u1234'); assert(k == 1); break;
5191 + case 3: assert(d == 'a'); assert(k == 0); break;
5192 + default: assert(0);
5193 + }
5194 + i++;
5195 + }
5196 + assert(i == 4);
5197 +}
5198 +
5199 +/*****************************/
5200 +
5201 +extern (C) int _aApplyRwd2(in wchar[] aa, dg2_t dg)
5202 +{ int result;
5203 +
5204 + debug(apply) printf("_aApplyRwd2(), len = %d\n", aa.length);
5205 + for (size_t i = aa.length; i != 0; )
5206 + { dchar d;
5207 +
5208 + i--;
5209 + d = aa[i];
5210 + if (d >= 0xDC00 && d <= 0xDFFF)
5211 + { if (i == 0)
5212 + onUnicodeError("Invalid UTF-16 sequence", 0);
5213 + i--;
5214 + d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
5215 + }
5216 + result = dg(&i, cast(void *)&d);
5217 + if (result)
5218 + break;
5219 + }
5220 + return result;
5221 +}
5222 +
5223 +unittest
5224 +{
5225 + debug(apply) printf("_aApplyRwd2.unittest\n");
5226 +
5227 + wchar[] s = "hello"w;
5228 + int i;
5229 +
5230 + foreach_reverse(k, dchar d; s)
5231 + {
5232 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5233 + assert(k == 4 - i);
5234 + switch (i)
5235 + {
5236 + case 0: assert(d == 'o'); break;
5237 + case 1: assert(d == 'l'); break;
5238 + case 2: assert(d == 'l'); break;
5239 + case 3: assert(d == 'e'); break;
5240 + case 4: assert(d == 'h'); break;
5241 + default: assert(0);
5242 + }
5243 + i++;
5244 + }
5245 + assert(i == 5);
5246 +
5247 + s = "a\u1234\U00100456b";
5248 + i = 0;
5249 + foreach_reverse(k, dchar d; s)
5250 + {
5251 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5252 + switch (i)
5253 + {
5254 + case 0: assert(k == 4); assert(d == 'b'); break;
5255 + case 1: assert(k == 2); assert(d == '\U00100456'); break;
5256 + case 2: assert(k == 1); assert(d == '\u1234'); break;
5257 + case 3: assert(k == 0); assert(d == 'a'); break;
5258 + default: assert(0);
5259 + }
5260 + i++;
5261 + }
5262 + assert(i == 4);
5263 +}
5264 +
5265 +/*****************************/
5266 +
5267 +extern (C) int _aApplyRcw2(in char[] aa, dg2_t dg)
5268 +{ int result;
5269 +
5270 + debug(apply) printf("_aApplyRcw2(), len = %d\n", aa.length);
5271 + for (size_t i = aa.length; i != 0; )
5272 + { dchar d;
5273 + wchar w;
5274 +
5275 + i--;
5276 + w = aa[i];
5277 + if (w & 0x80)
5278 + { char c = cast(char)w;
5279 + uint j;
5280 + uint m = 0x3F;
5281 + d = 0;
5282 + while ((c & 0xC0) != 0xC0)
5283 + { if (i == 0)
5284 + onUnicodeError("Invalid UTF-8 sequence", 0);
5285 + i--;
5286 + d |= (c & 0x3F) << j;
5287 + j += 6;
5288 + m >>= 1;
5289 + c = aa[i];
5290 + }
5291 + d |= (c & m) << j;
5292 +
5293 + if (d <= 0xFFFF)
5294 + w = cast(wchar) d;
5295 + else
5296 + {
5297 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
5298 + result = dg(&i, cast(void *)&w);
5299 + if (result)
5300 + break;
5301 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
5302 + }
5303 + }
5304 + result = dg(&i, cast(void *)&w);
5305 + if (result)
5306 + break;
5307 + }
5308 + return result;
5309 +}
5310 +
5311 +unittest
5312 +{
5313 + debug(apply) printf("_aApplyRcw2.unittest\n");
5314 +
5315 + char[] s = "hello"c;
5316 + int i;
5317 +
5318 + foreach_reverse(k, wchar d; s)
5319 + {
5320 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5321 + assert(k == 4 - i);
5322 + switch (i)
5323 + {
5324 + case 0: assert(d == 'o'); break;
5325 + case 1: assert(d == 'l'); break;
5326 + case 2: assert(d == 'l'); break;
5327 + case 3: assert(d == 'e'); break;
5328 + case 4: assert(d == 'h'); break;
5329 + default: assert(0);
5330 + }
5331 + i++;
5332 + }
5333 + assert(i == 5);
5334 +
5335 + s = "a\u1234\U00100456b";
5336 + i = 0;
5337 + foreach_reverse(k, wchar d; s)
5338 + {
5339 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5340 + switch (i)
5341 + {
5342 + case 0: assert(k == 8); assert(d == 'b'); break;
5343 + case 1: assert(k == 4); assert(d == 0xDBC1); break;
5344 + case 2: assert(k == 4); assert(d == 0xDC56); break;
5345 + case 3: assert(k == 1); assert(d == 0x1234); break;
5346 + case 4: assert(k == 0); assert(d == 'a'); break;
5347 + default: assert(0);
5348 + }
5349 + i++;
5350 + }
5351 + assert(i == 5);
5352 +}
5353 +
5354 +/*****************************/
5355 +
5356 +extern (C) int _aApplyRwc2(in wchar[] aa, dg2_t dg)
5357 +{ int result;
5358 +
5359 + debug(apply) printf("_aApplyRwc2(), len = %d\n", aa.length);
5360 + for (size_t i = aa.length; i != 0; )
5361 + { dchar d;
5362 + char c;
5363 +
5364 + i--;
5365 + d = aa[i];
5366 + if (d >= 0xDC00 && d <= 0xDFFF)
5367 + { if (i == 0)
5368 + onUnicodeError("Invalid UTF-16 sequence", 0);
5369 + i--;
5370 + d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
5371 + }
5372 +
5373 + if (d & ~0x7F)
5374 + {
5375 + char[4] buf;
5376 +
5377 + auto b = toUTF8(buf, d);
5378 + foreach (char c2; b)
5379 + {
5380 + result = dg(&i, cast(void *)&c2);
5381 + if (result)
5382 + return result;
5383 + }
5384 + continue;
5385 + }
5386 + c = cast(char)d;
5387 + result = dg(&i, cast(void *)&c);
5388 + if (result)
5389 + break;
5390 + }
5391 + return result;
5392 +}
5393 +
5394 +unittest
5395 +{
5396 + debug(apply) printf("_aApplyRwc2.unittest\n");
5397 +
5398 + wchar[] s = "hello"w;
5399 + int i;
5400 +
5401 + foreach_reverse(k, char d; s)
5402 + {
5403 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5404 + assert(k == 4 - i);
5405 + switch (i)
5406 + {
5407 + case 0: assert(d == 'o'); break;
5408 + case 1: assert(d == 'l'); break;
5409 + case 2: assert(d == 'l'); break;
5410 + case 3: assert(d == 'e'); break;
5411 + case 4: assert(d == 'h'); break;
5412 + default: assert(0);
5413 + }
5414 + i++;
5415 + }
5416 + assert(i == 5);
5417 +
5418 + s = "a\u1234\U00100456b";
5419 + i = 0;
5420 + foreach_reverse(k, char d; s)
5421 + {
5422 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5423 + switch (i)
5424 + {
5425 + case 0: assert(k == 4); assert(d == 'b'); break;
5426 + case 1: assert(k == 2); assert(d == 0xF4); break;
5427 + case 2: assert(k == 2); assert(d == 0x80); break;
5428 + case 3: assert(k == 2); assert(d == 0x91); break;
5429 + case 4: assert(k == 2); assert(d == 0x96); break;
5430 + case 5: assert(k == 1); assert(d == 0xE1); break;
5431 + case 6: assert(k == 1); assert(d == 0x88); break;
5432 + case 7: assert(k == 1); assert(d == 0xB4); break;
5433 + case 8: assert(k == 0); assert(d == 'a'); break;
5434 + default: assert(0);
5435 + }
5436 + i++;
5437 + }
5438 + assert(i == 9);
5439 +}
5440 +
5441 +/*****************************/
5442 +
5443 +extern (C) int _aApplyRdc2(in dchar[] aa, dg2_t dg)
5444 +{ int result;
5445 +
5446 + debug(apply) printf("_aApplyRdc2(), len = %d\n", aa.length);
5447 + for (size_t i = aa.length; i != 0; )
5448 + { dchar d = aa[--i];
5449 + char c;
5450 +
5451 + if (d & ~0x7F)
5452 + {
5453 + char[4] buf;
5454 +
5455 + auto b = toUTF8(buf, d);
5456 + foreach (char c2; b)
5457 + {
5458 + result = dg(&i, cast(void *)&c2);
5459 + if (result)
5460 + return result;
5461 + }
5462 + continue;
5463 + }
5464 + else
5465 + { c = cast(char)d;
5466 + }
5467 + result = dg(&i, cast(void *)&c);
5468 + if (result)
5469 + break;
5470 + }
5471 + return result;
5472 +}
5473 +
5474 +unittest
5475 +{
5476 + debug(apply) printf("_aApplyRdc2.unittest\n");
5477 +
5478 + dchar[] s = "hello"d;
5479 + int i;
5480 +
5481 + foreach_reverse(k, char d; s)
5482 + {
5483 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5484 + assert(k == 4 - i);
5485 + switch (i)
5486 + {
5487 + case 0: assert(d == 'o'); break;
5488 + case 1: assert(d == 'l'); break;
5489 + case 2: assert(d == 'l'); break;
5490 + case 3: assert(d == 'e'); break;
5491 + case 4: assert(d == 'h'); break;
5492 + default: assert(0);
5493 + }
5494 + i++;
5495 + }
5496 + assert(i == 5);
5497 +
5498 + s = "a\u1234\U00100456b";
5499 + i = 0;
5500 + foreach_reverse(k, char d; s)
5501 + {
5502 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5503 + switch (i)
5504 + {
5505 + case 0: assert(k == 3); assert(d == 'b'); break;
5506 + case 1: assert(k == 2); assert(d == 0xF4); break;
5507 + case 2: assert(k == 2); assert(d == 0x80); break;
5508 + case 3: assert(k == 2); assert(d == 0x91); break;
5509 + case 4: assert(k == 2); assert(d == 0x96); break;
5510 + case 5: assert(k == 1); assert(d == 0xE1); break;
5511 + case 6: assert(k == 1); assert(d == 0x88); break;
5512 + case 7: assert(k == 1); assert(d == 0xB4); break;
5513 + case 8: assert(k == 0); assert(d == 'a'); break;
5514 + default: assert(0);
5515 + }
5516 + i++;
5517 + }
5518 + assert(i == 9);
5519 +}
5520 +
5521 +/*****************************/
5522 +
5523 +extern (C) int _aApplyRdw2(in dchar[] aa, dg2_t dg)
5524 +{ int result;
5525 +
5526 + debug(apply) printf("_aApplyRdw2(), len = %d\n", aa.length);
5527 + for (size_t i = aa.length; i != 0; )
5528 + { dchar d = aa[--i];
5529 + wchar w;
5530 +
5531 + if (d <= 0xFFFF)
5532 + w = cast(wchar) d;
5533 + else
5534 + {
5535 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
5536 + result = dg(&i, cast(void *)&w);
5537 + if (result)
5538 + break;
5539 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
5540 + }
5541 + result = dg(&i, cast(void *)&w);
5542 + if (result)
5543 + break;
5544 + }
5545 + return result;
5546 +}
5547 +
5548 +unittest
5549 +{
5550 + debug(apply) printf("_aApplyRdw2.unittest\n");
5551 +
5552 + dchar[] s = "hello"d;
5553 + int i;
5554 +
5555 + foreach_reverse(k, wchar d; s)
5556 + {
5557 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5558 + assert(k == 4 - i);
5559 + switch (i)
5560 + {
5561 + case 0: assert(d == 'o'); break;
5562 + case 1: assert(d == 'l'); break;
5563 + case 2: assert(d == 'l'); break;
5564 + case 3: assert(d == 'e'); break;
5565 + case 4: assert(d == 'h'); break;
5566 + default: assert(0);
5567 + }
5568 + i++;
5569 + }
5570 + assert(i == 5);
5571 +
5572 + s = "a\u1234\U00100456b";
5573 + i = 0;
5574 + foreach_reverse(k, wchar d; s)
5575 + {
5576 + //printf("i = %d, k = %d, d = %x\n", i, k, d);
5577 + switch (i)
5578 + {
5579 + case 0: assert(k == 3); assert(d == 'b'); break;
5580 + case 1: assert(k == 2); assert(d == 0xDBC1); break;
5581 + case 2: assert(k == 2); assert(d == 0xDC56); break;
5582 + case 3: assert(k == 1); assert(d == 0x1234); break;
5583 + case 4: assert(k == 0); assert(d == 'a'); break;
5584 + default: assert(0);
5585 + }
5586 + i++;
5587 + }
5588 + assert(i == 5);
5589 +}
5590 +
5591 +
5592 Index: src/compiler/ldc/memory.d
5593 ===================================================================
5594 --- src/compiler/ldc/memory.d (revision 0)
5595 +++ src/compiler/ldc/memory.d (revision 0)
5596 @@ -0,0 +1,323 @@
5597 +/**
5598 + * This module exposes functionality for inspecting and manipulating memory.
5599 + *
5600 + * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com.
5601 + * All rights reserved.
5602 + * License:
5603 + * This software is provided 'as-is', without any express or implied
5604 + * warranty. In no event will the authors be held liable for any damages
5605 + * arising from the use of this software.
5606 + *
5607 + * Permission is granted to anyone to use this software for any purpose,
5608 + * including commercial applications, and to alter it and redistribute it
5609 + * freely, in both source and binary form, subject to the following
5610 + * restrictions:
5611 + *
5612 + * o The origin of this software must not be misrepresented; you must not
5613 + * claim that you wrote the original software. If you use this software
5614 + * in a product, an acknowledgment in the product documentation would be
5615 + * appreciated but is not required.
5616 + * o Altered source versions must be plainly marked as such, and must not
5617 + * be misrepresented as being the original software.
5618 + * o This notice may not be removed or altered from any source
5619 + * distribution.
5620 + * Authors: Walter Bright, Sean Kelly
5621 + */
5622 +module memory;
5623 +
5624 +version = GC_Use_Dynamic_Ranges;
5625 +
5626 +// does Posix suffice?
5627 +version(Posix)
5628 +{
5629 + version = GC_Use_Data_Proc_Maps;
5630 +}
5631 +
5632 +version(GC_Use_Data_Proc_Maps)
5633 +{
5634 + version(Posix) {} else {
5635 + static assert(false, "Proc Maps only supported on Posix systems");
5636 + }
5637 +
5638 + version( D_Version2 )
5639 + {
5640 + private import core.sys.posix.unistd;
5641 + private import core.sys.posix.fcntl;
5642 + private import core.stdc.string;
5643 + }
5644 + else
5645 + {
5646 + private import tango.stdc.posix.unistd;
5647 + private import tango.stdc.posix.fcntl;
5648 + private import tango.stdc.string;
5649 + }
5650 +
5651 + version = GC_Use_Dynamic_Ranges;
5652 +}
5653 +
5654 +private
5655 +{
5656 + version( linux )
5657 + {
5658 + //version = SimpleLibcStackEnd;
5659 +
5660 + version( SimpleLibcStackEnd )
5661 + {
5662 + extern (C) extern void* __libc_stack_end;
5663 + }
5664 + else
5665 + {
5666 + version( D_Version2 )
5667 + import core.sys.posix.dlfcn;
5668 + else
5669 + import tango.stdc.posix.dlfcn;
5670 + }
5671 + }
5672 + version(LDC)
5673 + {
5674 + pragma(intrinsic, "llvm.frameaddress")
5675 + {
5676 + void* llvm_frameaddress(uint level=0);
5677 + }
5678 + }
5679 +}
5680 +
5681 +
5682 +/**
5683 + *
5684 + */
5685 +extern (C) void* rt_stackBottom()
5686 +{
5687 + version( Win32 )
5688 + {
5689 + void* bottom;
5690 + asm
5691 + {
5692 + mov EAX, FS:4;
5693 + mov bottom, EAX;
5694 + }
5695 + return bottom;
5696 + }
5697 + else version( linux )
5698 + {
5699 + version( SimpleLibcStackEnd )
5700 + {
5701 + return __libc_stack_end;
5702 + }
5703 + else
5704 + {
5705 + // See discussion: http://autopackage.org/forums/viewtopic.php?t=22
5706 + static void** libc_stack_end;
5707 +
5708 + if( libc_stack_end == libc_stack_end.init )
5709 + {
5710 + void* handle = dlopen( null, RTLD_NOW );
5711 + libc_stack_end = cast(void**) dlsym( handle, "__libc_stack_end" );
5712 + dlclose( handle );
5713 + }
5714 + return *libc_stack_end;
5715 + }
5716 + }
5717 + else version( darwin )
5718 + {
5719 + // darwin has a fixed stack bottom
5720 + return cast(void*) 0xc0000000;
5721 + }
5722 + else
5723 + {
5724 + static assert( false, "Operating system not supported." );
5725 + }
5726 +}
5727 +
5728 +
5729 +/**
5730 + *
5731 + */
5732 +extern (C) void* rt_stackTop()
5733 +{
5734 + version( D_InlineAsm_X86 )
5735 + {
5736 + asm
5737 + {
5738 + naked;
5739 + mov EAX, ESP;
5740 + ret;
5741 + }
5742 + }
5743 + else
5744 + {
5745 + return llvm_frameaddress();
5746 + }
5747 +}
5748 +
5749 +
5750 +private
5751 +{
5752 + version( Win32 )
5753 + {
5754 + extern (C)
5755 + {
5756 + extern int _data_start__;
5757 + extern int _bss_end__;
5758 +
5759 + alias _data_start__ Data_Start;
5760 + alias _bss_end__ Data_End;
5761 + }
5762 + }
5763 + else version( linux )
5764 + {
5765 + extern (C)
5766 + {
5767 + extern int _data;
5768 + extern int __data_start;
5769 + extern int _end;
5770 + extern int _data_start__;
5771 + extern int _data_end__;
5772 + extern int _bss_start__;
5773 + extern int _bss_end__;
5774 + extern int __fini_array_end;
5775 + }
5776 +
5777 + alias __data_start Data_Start;
5778 + alias _end Data_End;
5779 + }
5780 +
5781 + version( GC_Use_Dynamic_Ranges )
5782 + {
5783 + version( D_Version2 )
5784 + private import core.stdc.stdlib;
5785 + else
5786 + private import tango.stdc.stdlib;
5787 + }
5788 +
5789 + extern (C) void gc_addRange( void* p, size_t sz );
5790 + extern (C) void gc_removeRange( void *p );
5791 +}
5792 +
5793 +
5794 +void initStaticDataGC()
5795 +{
5796 + enum S = (void*).sizeof;
5797 +
5798 + // Can't assume the input addresses are word-aligned
5799 + static void* adjust_up( void* p )
5800 + {
5801 + return p + ((S - (cast(size_t)p & (S-1))) & (S-1)); // cast ok even if 64-bit
5802 + }
5803 +
5804 + static void * adjust_down( void* p )
5805 + {
5806 + return p - (cast(size_t) p & (S-1));
5807 + }
5808 +
5809 + version( Win32 )
5810 + {
5811 + void* start = adjust_up( &Data_Start );
5812 + void* end = adjust_down( &Data_End );
5813 + gc_addRange(start, cast(size_t)end - cast(size_t)start);
5814 + }
5815 + else version( GC_Use_Data_Proc_Maps )
5816 + {
5817 + // TODO: Exclude zero-mapped regions
5818 +
5819 + int fd = open("/proc/self/maps", O_RDONLY);
5820 + int count; // %% need to configure ret for read..
5821 + char buf[2024];
5822 + char* p;
5823 + char* e;
5824 + char* s;
5825 + void* start;
5826 + void* end;
5827 +
5828 + void* dataStart = adjust_up( &Data_Start );
5829 + void* dataEnd = adjust_down( &Data_End );
5830 +
5831 + gc_addRange(dataStart, cast(size_t)dataEnd - cast(size_t)dataStart);
5832 +
5833 + p = buf.ptr;
5834 + if (fd != -1)
5835 + {
5836 + while ( (count = read(fd, p, buf.sizeof - (p - buf.ptr))) > 0 )
5837 + {
5838 + e = p + count;
5839 + p = buf.ptr;
5840 + while (true)
5841 + {
5842 + s = p;
5843 + while (p < e && *p != '\n')
5844 + p++;
5845 + if (p < e)
5846 + {
5847 + // parse the entry in [s, p)
5848 + static if( S == 4 )
5849 + {
5850 + enum Ofs
5851 + {
5852 + Write_Prot = 19,
5853 + Start_Addr = 0,
5854 + End_Addr = 9,
5855 + Addr_Len = 8,
5856 + }
5857 + }
5858 + else static if( S == 8 )
5859 + {
5860 + enum Ofs
5861 + {
5862 + Write_Prot = 35,
5863 + Start_Addr = 0,
5864 + End_Addr = 9,
5865 + Addr_Len = 17,
5866 + }
5867 + }
5868 + else
5869 + {
5870 + static assert( false );
5871 + }
5872 +
5873 + // %% this is wrong for 64-bit:
5874 + // uint strtoul(char *,char **,int);
5875 +
5876 + if( s[Ofs.Write_Prot] == 'w' )
5877 + {
5878 + s[Ofs.Start_Addr + Ofs.Addr_Len] = '\0';
5879 + s[Ofs.End_Addr + Ofs.Addr_Len] = '\0';
5880 + start = cast(void*) strtoul(s + Ofs.Start_Addr, null, 16);
5881 + end = cast(void*) strtoul(s + Ofs.End_Addr, null, 16);
5882 +
5883 + // 1. Exclude anything overlapping [dataStart, dataEnd)
5884 + // 2. Exclude stack
5885 + if ( ( !dataEnd ||
5886 + !( dataStart >= start && dataEnd <= end ) ) &&
5887 + !( &buf[0] >= start && &buf[0] < end ) )
5888 + {
5889 + // we already have static data from this region. anything else
5890 + // is heap (%% check)
5891 + debug (ProcMaps) printf("Adding map range %p 0%p\n", start, end);
5892 + gc_addRange(start, cast(size_t)end - cast(size_t)start);
5893 + }
5894 + }
5895 + p++;
5896 + }
5897 + else
5898 + {
5899 + count = p - s;
5900 + memmove(buf.ptr, s, count);
5901 + p = buf.ptr + count;
5902 + break;
5903 + }
5904 + }
5905 + }
5906 + close(fd);
5907 + }
5908 + }
5909 + else version(linux)
5910 + {
5911 + void* start = adjust_up( &Data_Start );
5912 + void* end = adjust_down( &Data_End );
5913 + gc_addRange(start, cast(size_t)end - cast(size_t)start);
5914 + }
5915 + else
5916 + {
5917 + static assert( false, "Operating system not supported." );
5918 + }
5919 +}
5920 Index: src/compiler/ldc/dmain2.d
5921 ===================================================================
5922 --- src/compiler/ldc/dmain2.d (revision 0)
5923 +++ src/compiler/ldc/dmain2.d (revision 0)
5924 @@ -0,0 +1,378 @@
5925 +/*
5926 + * Placed into the Public Domain.
5927 + * written by Walter Bright
5928 + * www.digitalmars.com
5929 + */
5930 +
5931 +/*
5932 + * Modified by Sean Kelly for use with the D Runtime Project
5933 + */
5934 +
5935 +/*
5936 + * Modified by Tomas Lindquist Olsen for use with the LLVM D Compiler
5937 + */
5938 +
5939 +module rt.dmain2;
5940 +
5941 +private
5942 +{
5943 + import memory;
5944 + import util.console;
5945 + import core.stdc.stddef;
5946 + import core.stdc.stdlib;
5947 + import core.stdc.string;
5948 +}
5949 +
5950 +version (Windows)
5951 +{
5952 + extern (Windows) alias int function() FARPROC;
5953 + extern (Windows) FARPROC GetProcAddress(void*, in char*);
5954 + extern (Windows) void* LoadLibraryA(in char*);
5955 + extern (Windows) int FreeLibrary(void*);
5956 + extern (Windows) void* LocalFree(void*);
5957 + extern (Windows) wchar_t* GetCommandLineW();
5958 + extern (Windows) wchar_t** CommandLineToArgvW(wchar_t*, int*);
5959 + extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int);
5960 + pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
5961 +}
5962 +
5963 +extern (C) void _STI_monitor_staticctor();
5964 +extern (C) void _STD_monitor_staticdtor();
5965 +extern (C) void _STI_critical_init();
5966 +extern (C) void _STD_critical_term();
5967 +extern (C) void gc_init();
5968 +extern (C) void gc_term();
5969 +extern (C) void _minit();
5970 +extern (C) void _moduleCtor();
5971 +extern (C) void _moduleDtor();
5972 +extern (C) void thread_joinAll();
5973 +
5974 +/***********************************
5975 + * These are a temporary means of providing a GC hook for DLL use. They may be
5976 + * replaced with some other similar functionality later.
5977 + */
5978 +extern (C)
5979 +{
5980 + void* gc_getProxy();
5981 + void gc_setProxy(void* p);
5982 + void gc_clrProxy();
5983 +
5984 + alias void* function() gcGetFn;
5985 + alias void function(void*) gcSetFn;
5986 + alias void function() gcClrFn;
5987 +}
5988 +
5989 +extern (C) void* rt_loadLibrary(in char[] name)
5990 +{
5991 + version (Windows)
5992 + {
5993 + char[260] temp = void;
5994 + temp[0 .. name.length] = name[];
5995 + temp[name.length] = cast(char) 0;
5996 + void* ptr = LoadLibraryA(temp.ptr);
5997 + if (ptr is null)
5998 + return ptr;
5999 + gcSetFn gcSet = cast(gcSetFn) GetProcAddress(ptr, "gc_setProxy");
6000 + if (gcSet !is null)
6001 + gcSet(gc_getProxy());
6002 + return ptr;
6003 +
6004 + }
6005 + else version (linux)
6006 + {
6007 + throw new Exception("rt_loadLibrary not yet implemented on linux.");
6008 + }
6009 +}
6010 +
6011 +extern (C) bool rt_unloadLibrary(void* ptr)
6012 +{
6013 + version (Windows)
6014 + {
6015 + gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
6016 + if (gcClr !is null)
6017 + gcClr();
6018 + return FreeLibrary(ptr) != 0;
6019 + }
6020 + else version (linux)
6021 + {
6022 + throw new Exception("rt_unloadLibrary not yet implemented on linux.");
6023 + }
6024 +}
6025 +
6026 +/***********************************
6027 + * These functions must be defined for any D program linked
6028 + * against this library.
6029 + */
6030 +extern (C) void onAssertError(string file, size_t line);
6031 +extern (C) void onAssertErrorMsg(string file, size_t line, string msg);
6032 +extern (C) void onRangeError(string file, size_t line);
6033 +extern (C) void onHiddenFuncError(Object o);
6034 +extern (C) void onSwitchError(string file, size_t line);
6035 +extern (C) bool runModuleUnitTests();
6036 +
6037 +// this function is called from the utf module
6038 +//extern (C) void onUnicodeError(string msg, size_t idx);
6039 +
6040 +/***********************************
6041 + * These are internal callbacks for various language errors.
6042 + */
6043 +extern (C) void _d_assert(string file, uint line)
6044 +{
6045 + onAssertError(file, line);
6046 +}
6047 +
6048 +extern (C) static void _d_assert_msg(string msg, string file, uint line)
6049 +{
6050 + onAssertErrorMsg(file, line, msg);
6051 +}
6052 +
6053 +extern (C) void _d_array_bounds(string file, uint line)
6054 +{
6055 + onRangeError(file, line);
6056 +}
6057 +
6058 +extern (C) void _d_switch_error(string file, uint line)
6059 +{
6060 + onSwitchError(file, line);
6061 +}
6062 +
6063 +extern (C) void _d_hidden_func()
6064 +{
6065 + Object o;
6066 + asm
6067 + {
6068 + mov o, EAX;
6069 + }
6070 + onHiddenFuncError(o);
6071 +}
6072 +
6073 +bool _d_isHalting = false;
6074 +
6075 +extern (C) bool rt_isHalting()
6076 +{
6077 + return _d_isHalting;
6078 +}
6079 +
6080 +extern (C) bool rt_trapExceptions = true;
6081 +
6082 +void _d_criticalInit()
6083 +{
6084 + version (linux)
6085 + {
6086 + _STI_monitor_staticctor();
6087 + _STI_critical_init();
6088 + }
6089 +}
6090 +
6091 +alias void delegate(Throwable) ExceptionHandler;
6092 +
6093 +extern (C) bool rt_init(ExceptionHandler dg = null)
6094 +{
6095 + _d_criticalInit();
6096 +
6097 + try
6098 + {
6099 + gc_init();
6100 + initStaticDataGC();
6101 + version (Windows)
6102 + _minit();
6103 + _moduleCtor();
6104 + return true;
6105 + }
6106 + catch (Throwable e)
6107 + {
6108 + if (dg)
6109 + dg(e);
6110 + }
6111 + catch
6112 + {
6113 +
6114 + }
6115 + _d_criticalTerm();
6116 + return false;
6117 +}
6118 +
6119 +void _d_criticalTerm()
6120 +{
6121 + version (linux)
6122 + {
6123 + _STD_critical_term();
6124 + _STD_monitor_staticdtor();
6125 + }
6126 +}
6127 +
6128 +extern (C) bool rt_term(ExceptionHandler dg = null)
6129 +{
6130 + try
6131 + {
6132 + thread_joinAll();
6133 + _d_isHalting = true;
6134 + _moduleDtor();
6135 + gc_term();
6136 + return true;
6137 + }
6138 + catch (Throwable e)
6139 + {
6140 + if (dg)
6141 + dg(e);
6142 + }
6143 + catch
6144 + {
6145 +
6146 + }
6147 + finally
6148 + {
6149 + _d_criticalTerm();
6150 + }
6151 + return false;
6152 +}
6153 +
6154 +/***********************************
6155 + * The D main() function supplied by the user's program
6156 + */
6157 +int main(char[][] args);
6158 +
6159 +/***********************************
6160 + * Substitutes for the C main() function.
6161 + * It's purpose is to wrap the call to the D main()
6162 + * function and catch any unhandled exceptions.
6163 + */
6164 +
6165 +extern (C) int main(int argc, char **argv)
6166 +{
6167 + char[][] args;
6168 + int result;
6169 +
6170 + version (linux)
6171 + {
6172 + _STI_monitor_staticctor();
6173 + _STI_critical_init();
6174 + }
6175 +
6176 + version (Windows)
6177 + {
6178 + wchar_t* wcbuf = GetCommandLineW();
6179 + size_t wclen = wcslen(wcbuf);
6180 + int wargc = 0;
6181 + wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
6182 + assert(wargc == argc);
6183 +
6184 + char* cargp = null;
6185 + size_t cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
6186 +
6187 + cargp = cast(char*) alloca(cargl);
6188 + args = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
6189 +
6190 + for (size_t i = 0, p = 0; i < wargc; i++)
6191 + {
6192 + int wlen = wcslen(wargs[i]);
6193 + int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
6194 + args[i] = cargp[p .. p+clen];
6195 + p += clen; assert(p <= cargl);
6196 + WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
6197 + }
6198 + LocalFree(wargs);
6199 + wargs = null;
6200 + wargc = 0;
6201 + }
6202 + else version (linux)
6203 + {
6204 + char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
6205 + scope(exit) free(am);
6206 +
6207 + for (size_t i = 0; i < argc; i++)
6208 + {
6209 + auto len = strlen(argv[i]);
6210 + am[i] = argv[i][0 .. len];
6211 + }
6212 + args = am[0 .. argc];
6213 + }
6214 +
6215 + bool trapExceptions = rt_trapExceptions;
6216 +
6217 + void tryExec(scope void delegate() dg)
6218 + {
6219 +
6220 + if (trapExceptions)
6221 + {
6222 + try
6223 + {
6224 + dg();
6225 + }
6226 + catch (Throwable e)
6227 + {
6228 + while (e)
6229 + {
6230 + if (e.file)
6231 + {
6232 + // fprintf(stderr, "%.*s(%u): %.*s\n", e.file, e.line, e.msg);
6233 + console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.msg)("\n");
6234 + }
6235 + else
6236 + {
6237 + // fprintf(stderr, "%.*s\n", e.toString());
6238 + console (e.toString)("\n");
6239 + }
6240 + if (e.info)
6241 + {
6242 + console ("----------------\n");
6243 + foreach (t; e.info)
6244 + console (t)("\n");
6245 + }
6246 + if (e.next)
6247 + console ("\n");
6248 + e = e.next;
6249 + }
6250 + result = EXIT_FAILURE;
6251 + }
6252 + catch (Object o)
6253 + {
6254 + // fprintf(stderr, "%.*s\n", o.toString());
6255 + console (o.toString)("\n");
6256 + result = EXIT_FAILURE;
6257 + }
6258 + }
6259 + else
6260 + {
6261 + dg();
6262 + }
6263 + }
6264 +
6265 + // NOTE: The lifetime of a process is much like the lifetime of an object:
6266 + // it is initialized, then used, then destroyed. If initialization
6267 + // fails, the successive two steps are never reached. However, if
6268 + // initialization succeeds, then cleanup will occur even if the use
6269 + // step fails in some way. Here, the use phase consists of running
6270 + // the user's main function. If main terminates with an exception,
6271 + // the exception is handled and then cleanup begins. An exception
6272 + // thrown during cleanup, however, will abort the cleanup process.
6273 +
6274 + void runMain()
6275 + {
6276 + result = main(args);
6277 + }
6278 +
6279 + void runAll()
6280 + {
6281 + gc_init();
6282 + initStaticDataGC();
6283 + version (Windows)
6284 + _minit();
6285 + _moduleCtor();
6286 + if (runModuleUnitTests())
6287 + tryExec(&runMain);
6288 + thread_joinAll();
6289 + _d_isHalting = true;
6290 + _moduleDtor();
6291 + gc_term();
6292 + }
6293 +
6294 + tryExec(&runAll);
6295 +
6296 + version (linux)
6297 + {
6298 + _STD_critical_term();
6299 + _STD_monitor_staticdtor();
6300 + }
6301 + return result;
6302 +}
6303 Index: src/compiler/ldc/typeinfo/ti_void.d
6304 ===================================================================
6305 --- src/compiler/ldc/typeinfo/ti_void.d (revision 0)
6306 +++ src/compiler/ldc/typeinfo/ti_void.d (revision 0)
6307 @@ -0,0 +1,43 @@
6308 +
6309 +// void
6310 +
6311 +module rt.typeinfo.ti_void;
6312 +
6313 +class TypeInfo_v : TypeInfo
6314 +{
6315 + override string toString() { return "void"; }
6316 +
6317 + override hash_t getHash(in void* p)
6318 + {
6319 + assert(0);
6320 + }
6321 +
6322 + override equals_t equals(in void* p1, in void* p2)
6323 + {
6324 + return *cast(byte *)p1 == *cast(byte *)p2;
6325 + }
6326 +
6327 + override int compare(in void* p1, in void* p2)
6328 + {
6329 + return *cast(byte *)p1 - *cast(byte *)p2;
6330 + }
6331 +
6332 + override size_t tsize()
6333 + {
6334 + return void.sizeof;
6335 + }
6336 +
6337 + override void swap(void *p1, void *p2)
6338 + {
6339 + byte t;
6340 +
6341 + t = *cast(byte *)p1;
6342 + *cast(byte *)p1 = *cast(byte *)p2;
6343 + *cast(byte *)p2 = t;
6344 + }
6345 +
6346 + override uint flags()
6347 + {
6348 + return 1;
6349 + }
6350 +}
6351 Index: src/compiler/ldc/typeinfo/ti_wchar.d
6352 ===================================================================
6353 --- src/compiler/ldc/typeinfo/ti_wchar.d (revision 0)
6354 +++ src/compiler/ldc/typeinfo/ti_wchar.d (revision 0)
6355 @@ -0,0 +1,43 @@
6356 +
6357 +module rt.typeinfo.ti_wchar;
6358 +
6359 +
6360 +class TypeInfo_u : TypeInfo
6361 +{
6362 + override string toString() { return "wchar"; }
6363 +
6364 + override hash_t getHash(in void* p)
6365 + {
6366 + return *cast(wchar *)p;
6367 + }
6368 +
6369 + override equals_t equals(in void* p1, in void* p2)
6370 + {
6371 + return *cast(wchar *)p1 == *cast(wchar *)p2;
6372 + }
6373 +
6374 + override int compare(in void* p1, in void* p2)
6375 + {
6376 + return *cast(wchar *)p1 - *cast(wchar *)p2;
6377 + }
6378 +
6379 + override size_t tsize()
6380 + {
6381 + return wchar.sizeof;
6382 + }
6383 +
6384 + override void swap(void *p1, void *p2)
6385 + {
6386 + wchar t;
6387 +
6388 + t = *cast(wchar *)p1;
6389 + *cast(wchar *)p1 = *cast(wchar *)p2;
6390 + *cast(wchar *)p2 = t;
6391 + }
6392 +
6393 + override void[] init()
6394 + { static wchar c;
6395 +
6396 + return (cast(wchar *)&c)[0 .. 1];
6397 + }
6398 +}
6399 Index: src/compiler/ldc/typeinfo/ti_ptr.d
6400 ===================================================================
6401 --- src/compiler/ldc/typeinfo/ti_ptr.d (revision 0)
6402 +++ src/compiler/ldc/typeinfo/ti_ptr.d (revision 0)
6403 @@ -0,0 +1,46 @@
6404 +
6405 +// pointer
6406 +
6407 +module rt.typeinfo.ti_ptr;
6408 +
6409 +class TypeInfo_P : TypeInfo
6410 +{
6411 + override hash_t getHash(in void* p)
6412 + {
6413 + return cast(uint)*cast(void* *)p;
6414 + }
6415 +
6416 + override equals_t equals(in void* p1, in void* p2)
6417 + {
6418 + return *cast(void* *)p1 == *cast(void* *)p2;
6419 + }
6420 +
6421 + override int compare(in void* p1, in void* p2)
6422 + {
6423 + auto c = *cast(void* *)p1 - *cast(void* *)p2;
6424 + if (c < 0)
6425 + return -1;
6426 + else if (c > 0)
6427 + return 1;
6428 + return 0;
6429 + }
6430 +
6431 + override size_t tsize()
6432 + {
6433 + return (void*).sizeof;
6434 + }
6435 +
6436 + override void swap(void *p1, void *p2)
6437 + {
6438 + void* t;
6439 +
6440 + t = *cast(void* *)p1;
6441 + *cast(void* *)p1 = *cast(void* *)p2;
6442 + *cast(void* *)p2 = t;
6443 + }
6444 +
6445 + override uint flags()
6446 + {
6447 + return 1;
6448 + }
6449 +}
6450 Index: src/compiler/ldc/typeinfo/ti_Afloat.d
6451 ===================================================================
6452 --- src/compiler/ldc/typeinfo/ti_Afloat.d (revision 0)
6453 +++ src/compiler/ldc/typeinfo/ti_Afloat.d (revision 0)
6454 @@ -0,0 +1,114 @@
6455 +/*
6456 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
6457 + * Written by Walter Bright
6458 + *
6459 + * This software is provided 'as-is', without any express or implied
6460 + * warranty. In no event will the authors be held liable for any damages
6461 + * arising from the use of this software.
6462 + *
6463 + * Permission is granted to anyone to use this software for any purpose,
6464 + * including commercial applications, and to alter it and redistribute it
6465 + * freely, in both source and binary form, subject to the following
6466 + * restrictions:
6467 + *
6468 + * o The origin of this software must not be misrepresented; you must not
6469 + * claim that you wrote the original software. If you use this software
6470 + * in a product, an acknowledgment in the product documentation would be
6471 + * appreciated but is not required.
6472 + * o Altered source versions must be plainly marked as such, and must not
6473 + * be misrepresented as being the original software.
6474 + * o This notice may not be removed or altered from any source
6475 + * distribution.
6476 + */
6477 +
6478 +module rt.typeinfo.ti_Afloat;
6479 +
6480 +private import typeinfo.ti_float;
6481 +
6482 +// float[]
6483 +
6484 +class TypeInfo_Af : TypeInfo
6485 +{
6486 + override string toString() { return "float[]"; }
6487 +
6488 + override hash_t getHash(in void* p)
6489 + { float[] s = *cast(float[]*)p;
6490 + size_t len = s.length;
6491 + auto str = s.ptr;
6492 + hash_t hash = 0;
6493 +
6494 + while (len)
6495 + {
6496 + hash *= 9;
6497 + hash += *cast(uint *)str;
6498 + str++;
6499 + len--;
6500 + }
6501 +
6502 + return hash;
6503 + }
6504 +
6505 + override equals_t equals(in void* p1, in void* p2)
6506 + {
6507 + float[] s1 = *cast(float[]*)p1;
6508 + float[] s2 = *cast(float[]*)p2;
6509 + size_t len = s1.length;
6510 +
6511 + if (len != s2.length)
6512 + return 0;
6513 + for (size_t u = 0; u < len; u++)
6514 + {
6515 + if (!TypeInfo_f._equals(s1[u], s2[u]))
6516 + return false;
6517 + }
6518 + return true;
6519 + }
6520 +
6521 + override int compare(in void* p1, in void* p2)
6522 + {
6523 + float[] s1 = *cast(float[]*)p1;
6524 + float[] s2 = *cast(float[]*)p2;
6525 + size_t len = s1.length;
6526 +
6527 + if (s2.length < len)
6528 + len = s2.length;
6529 + for (size_t u = 0; u < len; u++)
6530 + {
6531 + int c = TypeInfo_f._compare(s1[u], s2[u]);
6532 + if (c)
6533 + return c;
6534 + }
6535 + if (s1.length < s2.length)
6536 + return -1;
6537 + else if (s1.length > s2.length)
6538 + return 1;
6539 + return 0;
6540 + }
6541 +
6542 + override size_t tsize()
6543 + {
6544 + return (float[]).sizeof;
6545 + }
6546 +
6547 + override uint flags()
6548 + {
6549 + return 1;
6550 + }
6551 +
6552 + override TypeInfo next()
6553 + {
6554 + return typeid(float);
6555 + }
6556 +}
6557 +
6558 +// ifloat[]
6559 +
6560 +class TypeInfo_Ao : TypeInfo_Af
6561 +{
6562 + override string toString() { return "ifloat[]"; }
6563 +
6564 + override TypeInfo next()
6565 + {
6566 + return typeid(ifloat);
6567 + }
6568 +}
6569 Index: src/compiler/ldc/typeinfo/ti_double.d
6570 ===================================================================
6571 --- src/compiler/ldc/typeinfo/ti_double.d (revision 0)
6572 +++ src/compiler/ldc/typeinfo/ti_double.d (revision 0)
6573 @@ -0,0 +1,64 @@
6574 +
6575 +// double
6576 +
6577 +module rt.typeinfo.ti_double;
6578 +
6579 +class TypeInfo_d : TypeInfo
6580 +{
6581 + override string toString() { return "double"; }
6582 +
6583 + override hash_t getHash(in void* p)
6584 + {
6585 + return (cast(uint *)p)[0] + (cast(uint *)p)[1];
6586 + }
6587 +
6588 + static equals_t _equals(double f1, double f2)
6589 + {
6590 + return f1 == f2 ||
6591 + (f1 !<>= f1 && f2 !<>= f2);
6592 + }
6593 +
6594 + static int _compare(double d1, double d2)
6595 + {
6596 + if (d1 !<>= d2) // if either are NaN
6597 + {
6598 + if (d1 !<>= d1)
6599 + { if (d2 !<>= d2)
6600 + return 0;
6601 + return -1;
6602 + }
6603 + return 1;
6604 + }
6605 + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
6606 + }
6607 +
6608 + override equals_t equals(in void* p1, in void* p2)
6609 + {
6610 + return _equals(*cast(double *)p1, *cast(double *)p2);
6611 + }
6612 +
6613 + override int compare(in void* p1, in void* p2)
6614 + {
6615 + return _compare(*cast(double *)p1, *cast(double *)p2);
6616 + }
6617 +
6618 + override size_t tsize()
6619 + {
6620 + return double.sizeof;
6621 + }
6622 +
6623 + override void swap(void *p1, void *p2)
6624 + {
6625 + double t;
6626 +
6627 + t = *cast(double *)p1;
6628 + *cast(double *)p1 = *cast(double *)p2;
6629 + *cast(double *)p2 = t;
6630 + }
6631 +
6632 + override void[] init()
6633 + { static double r;
6634 +
6635 + return (cast(double *)&r)[0 .. 1];
6636 + }
6637 +}
6638 Index: src/compiler/ldc/typeinfo/ti_delegate.d
6639 ===================================================================
6640 --- src/compiler/ldc/typeinfo/ti_delegate.d (revision 0)
6641 +++ src/compiler/ldc/typeinfo/ti_delegate.d (revision 0)
6642 @@ -0,0 +1,39 @@
6643 +
6644 +// delegate
6645 +
6646 +module rt.typeinfo.ti_delegate;
6647 +
6648 +alias void delegate(int) dg;
6649 +
6650 +class TypeInfo_D : TypeInfo
6651 +{
6652 + override hash_t getHash(in void* p)
6653 + { long l = *cast(long *)p;
6654 +
6655 + return cast(uint)(l + (l >> 32));
6656 + }
6657 +
6658 + override equals_t equals(in void* p1, in void* p2)
6659 + {
6660 + return *cast(dg *)p1 == *cast(dg *)p2;
6661 + }
6662 +
6663 + override size_t tsize()
6664 + {
6665 + return dg.sizeof;
6666 + }
6667 +
6668 + override void swap(void *p1, void *p2)
6669 + {
6670 + dg t;
6671 +
6672 + t = *cast(dg *)p1;
6673 + *cast(dg *)p1 = *cast(dg *)p2;
6674 + *cast(dg *)p2 = t;
6675 + }
6676 +
6677 + override uint flags()
6678 + {
6679 + return 1;
6680 + }
6681 +}
6682 Index: src/compiler/ldc/typeinfo/ti_Adouble.d
6683 ===================================================================
6684 --- src/compiler/ldc/typeinfo/ti_Adouble.d (revision 0)
6685 +++ src/compiler/ldc/typeinfo/ti_Adouble.d (revision 0)
6686 @@ -0,0 +1,115 @@
6687 +/*
6688 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
6689 + * Written by Walter Bright
6690 + *
6691 + * This software is provided 'as-is', without any express or implied
6692 + * warranty. In no event will the authors be held liable for any damages
6693 + * arising from the use of this software.
6694 + *
6695 + * Permission is granted to anyone to use this software for any purpose,
6696 + * including commercial applications, and to alter it and redistribute it
6697 + * freely, in both source and binary form, subject to the following
6698 + * restrictions:
6699 + *
6700 + * o The origin of this software must not be misrepresented; you must not
6701 + * claim that you wrote the original software. If you use this software
6702 + * in a product, an acknowledgment in the product documentation would be
6703 + * appreciated but is not required.
6704 + * o Altered source versions must be plainly marked as such, and must not
6705 + * be misrepresented as being the original software.
6706 + * o This notice may not be removed or altered from any source
6707 + * distribution.
6708 + */
6709 +
6710 +module rt.typeinfo.ti_Adouble;
6711 +
6712 +private import typeinfo.ti_double;
6713 +
6714 +// double[]
6715 +
6716 +class TypeInfo_Ad : TypeInfo
6717 +{
6718 + override string toString() { return "double[]"; }
6719 +
6720 + override hash_t getHash(in void* p)
6721 + { double[] s = *cast(double[]*)p;
6722 + size_t len = s.length;
6723 + auto str = s.ptr;
6724 + hash_t hash = 0;
6725 +
6726 + while (len)
6727 + {
6728 + hash *= 9;
6729 + hash += (cast(uint *)str)[0];
6730 + hash += (cast(uint *)str)[1];
6731 + str++;
6732 + len--;
6733 + }
6734 +
6735 + return hash;
6736 + }
6737 +
6738 + override equals_t equals(in void* p1, in void* p2)
6739 + {
6740 + double[] s1 = *cast(double[]*)p1;
6741 + double[] s2 = *cast(double[]*)p2;
6742 + size_t len = s1.length;
6743 +
6744 + if (len != s2.length)
6745 + return 0;
6746 + for (size_t u = 0; u < len; u++)
6747 + {
6748 + if (!TypeInfo_d._equals(s1[u], s2[u]))
6749 + return false;
6750 + }
6751 + return true;
6752 + }
6753 +
6754 + override int compare(in void* p1, in void* p2)
6755 + {
6756 + double[] s1 = *cast(double[]*)p1;
6757 + double[] s2 = *cast(double[]*)p2;
6758 + size_t len = s1.length;
6759 +
6760 + if (s2.length < len)
6761 + len = s2.length;
6762 + for (size_t u = 0; u < len; u++)
6763 + {
6764 + int c = TypeInfo_d._compare(s1[u], s2[u]);
6765 + if (c)
6766 + return c;
6767 + }
6768 + if (s1.length < s2.length)
6769 + return -1;
6770 + else if (s1.length > s2.length)
6771 + return 1;
6772 + return 0;
6773 + }
6774 +
6775 + override size_t tsize()
6776 + {
6777 + return (double[]).sizeof;
6778 + }
6779 +
6780 + override uint flags()
6781 + {
6782 + return 1;
6783 + }
6784 +
6785 + override TypeInfo next()
6786 + {
6787 + return typeid(double);
6788 + }
6789 +}
6790 +
6791 +// idouble[]
6792 +
6793 +class TypeInfo_Ap : TypeInfo_Ad
6794 +{
6795 + override string toString() { return "idouble[]"; }
6796 +
6797 + override TypeInfo next()
6798 + {
6799 + return typeid(idouble);
6800 + }
6801 +}
6802 Index: src/compiler/ldc/typeinfo/ti_char.d
6803 ===================================================================
6804 --- src/compiler/ldc/typeinfo/ti_char.d (revision 0)
6805 +++ src/compiler/ldc/typeinfo/ti_char.d (revision 0)
6806 @@ -0,0 +1,42 @@
6807 +
6808 +module rt.typeinfo.ti_char;
6809 +
6810 +class TypeInfo_a : TypeInfo
6811 +{
6812 + override string toString() { return "char"; }
6813 +
6814 + override hash_t getHash(in void* p)
6815 + {
6816 + return *cast(char *)p;
6817 + }
6818 +
6819 + override equals_t equals(in void* p1, in void* p2)
6820 + {
6821 + return *cast(char *)p1 == *cast(char *)p2;
6822 + }
6823 +
6824 + override int compare(in void* p1, in void* p2)
6825 + {
6826 + return *cast(char *)p1 - *cast(char *)p2;
6827 + }
6828 +
6829 + override size_t tsize()
6830 + {
6831 + return char.sizeof;
6832 + }
6833 +
6834 + override void swap(void *p1, void *p2)
6835 + {
6836 + char t;
6837 +
6838 + t = *cast(char *)p1;
6839 + *cast(char *)p1 = *cast(char *)p2;
6840 + *cast(char *)p2 = t;
6841 + }
6842 +
6843 + override void[] init()
6844 + { static char c;
6845 +
6846 + return (cast(char *)&c)[0 .. 1];
6847 + }
6848 +}
6849 Index: src/compiler/ldc/typeinfo/ti_Acdouble.d
6850 ===================================================================
6851 --- src/compiler/ldc/typeinfo/ti_Acdouble.d (revision 0)
6852 +++ src/compiler/ldc/typeinfo/ti_Acdouble.d (revision 0)
6853 @@ -0,0 +1,105 @@
6854 +/*
6855 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
6856 + * Written by Walter Bright
6857 + *
6858 + * This software is provided 'as-is', without any express or implied
6859 + * warranty. In no event will the authors be held liable for any damages
6860 + * arising from the use of this software.
6861 + *
6862 + * Permission is granted to anyone to use this software for any purpose,
6863 + * including commercial applications, and to alter it and redistribute it
6864 + * freely, in both source and binary form, subject to the following
6865 + * restrictions:
6866 + *
6867 + * o The origin of this software must not be misrepresented; you must not
6868 + * claim that you wrote the original software. If you use this software
6869 + * in a product, an acknowledgment in the product documentation would be
6870 + * appreciated but is not required.
6871 + * o Altered source versions must be plainly marked as such, and must not
6872 + * be misrepresented as being the original software.
6873 + * o This notice may not be removed or altered from any source
6874 + * distribution.
6875 + */
6876 +
6877 +module rt.typeinfo.ti_Acdouble;
6878 +
6879 +private import typeinfo.ti_cdouble;
6880 +
6881 +// cdouble[]
6882 +
6883 +class TypeInfo_Ar : TypeInfo
6884 +{
6885 + override string toString() { return "cdouble[]"; }
6886 +
6887 + override hash_t getHash(in void* p)
6888 + { cdouble[] s = *cast(cdouble[]*)p;
6889 + size_t len = s.length;
6890 + cdouble *str = s.ptr;
6891 + hash_t hash = 0;
6892 +
6893 + while (len)
6894 + {
6895 + hash *= 9;
6896 + hash += (cast(uint *)str)[0];
6897 + hash += (cast(uint *)str)[1];
6898 + hash += (cast(uint *)str)[2];
6899 + hash += (cast(uint *)str)[3];
6900 + str++;
6901 + len--;
6902 + }
6903 +
6904 + return hash;
6905 + }
6906 +
6907 + override equals_t equals(in void* p1, in void* p2)
6908 + {
6909 + cdouble[] s1 = *cast(cdouble[]*)p1;
6910 + cdouble[] s2 = *cast(cdouble[]*)p2;
6911 + size_t len = s1.length;
6912 +
6913 + if (len != s2.length)
6914 + return false;
6915 + for (size_t u = 0; u < len; u++)
6916 + {
6917 + if (!TypeInfo_r._equals(s1[u], s2[u]))
6918 + return false;
6919 + }
6920 + return true;
6921 + }
6922 +
6923 + override int compare(in void* p1, in void* p2)
6924 + {
6925 + cdouble[] s1 = *cast(cdouble[]*)p1;
6926 + cdouble[] s2 = *cast(cdouble[]*)p2;
6927 + size_t len = s1.length;
6928 +
6929 + if (s2.length < len)
6930 + len = s2.length;
6931 + for (size_t u = 0; u < len; u++)
6932 + {
6933 + int c = TypeInfo_r._compare(s1[u], s2[u]);
6934 + if (c)
6935 + return c;
6936 + }
6937 + if (s1.length < s2.length)
6938 + return -1;
6939 + else if (s1.length > s2.length)
6940 + return 1;
6941 + return 0;
6942 + }
6943 +
6944 + override size_t tsize()
6945 + {
6946 + return (cdouble[]).sizeof;
6947 + }
6948 +
6949 + override uint flags()
6950 + {
6951 + return 1;
6952 + }
6953 +
6954 + override TypeInfo next()
6955 + {
6956 + return typeid(cdouble);
6957 + }
6958 +}
6959 Index: src/compiler/ldc/typeinfo/ti_uint.d
6960 ===================================================================
6961 --- src/compiler/ldc/typeinfo/ti_uint.d (revision 0)
6962 +++ src/compiler/ldc/typeinfo/ti_uint.d (revision 0)
6963 @@ -0,0 +1,42 @@
6964 +
6965 +// uint
6966 +
6967 +module rt.typeinfo.ti_uint;
6968 +
6969 +class TypeInfo_k : TypeInfo
6970 +{
6971 + override string toString() { return "uint"; }
6972 +
6973 + override hash_t getHash(in void* p)
6974 + {
6975 + return *cast(uint *)p;
6976 + }
6977 +
6978 + override equals_t equals(in void* p1, in void* p2)
6979 + {
6980 + return *cast(uint *)p1 == *cast(uint *)p2;
6981 + }
6982 +
6983 + override int compare(in void* p1, in void* p2)
6984 + {
6985 + if (*cast(uint*) p1 < *cast(uint*) p2)
6986 + return -1;
6987 + else if (*cast(uint*) p1 > *cast(uint*) p2)
6988 + return 1;
6989 + return 0;
6990 + }
6991 +
6992 + override size_t tsize()
6993 + {
6994 + return uint.sizeof;
6995 + }
6996 +
6997 + override void swap(void *p1, void *p2)
6998 + {
6999 + int t;
7000 +
7001 + t = *cast(uint *)p1;
7002 + *cast(uint *)p1 = *cast(uint *)p2;
7003 + *cast(uint *)p2 = t;
7004 + }
7005 +}
7006 Index: src/compiler/ldc/typeinfo/ti_AC.d
7007 ===================================================================
7008 --- src/compiler/ldc/typeinfo/ti_AC.d (revision 0)
7009 +++ src/compiler/ldc/typeinfo/ti_AC.d (revision 0)
7010 @@ -0,0 +1,95 @@
7011 +module rt.typeinfo.ti_AC;
7012 +
7013 +// Object[]
7014 +
7015 +class TypeInfo_AC : TypeInfo
7016 +{
7017 + override hash_t getHash(in void* p)
7018 + { Object[] s = *cast(Object[]*)p;
7019 + hash_t hash = 0;
7020 +
7021 + foreach (Object o; s)
7022 + {
7023 + if (o)
7024 + hash += o.toHash();
7025 + }
7026 + return hash;
7027 + }
7028 +
7029 + override equals_t equals(in void* p1, in void* p2)
7030 + {
7031 + Object[] s1 = *cast(Object[]*)p1;
7032 + Object[] s2 = *cast(Object[]*)p2;
7033 +
7034 + if (s1.length == s2.length)
7035 + {
7036 + for (size_t u = 0; u < s1.length; u++)
7037 + { Object o1 = s1[u];
7038 + Object o2 = s2[u];
7039 +
7040 + // Do not pass null's to Object.opEquals()
7041 + if (o1 is o2 ||
7042 + (!(o1 is null) && !(o2 is null) && o1.opEquals(o2)))
7043 + continue;
7044 + return false;
7045 + }
7046 + return true;
7047 + }
7048 + return false;
7049 + }
7050 +
7051 + override int compare(in void* p1, in void* p2)
7052 + {
7053 + Object[] s1 = *cast(Object[]*)p1;
7054 + Object[] s2 = *cast(Object[]*)p2;
7055 + ptrdiff_t c;
7056 +
7057 + c = cast(ptrdiff_t)s1.length - cast(ptrdiff_t)s2.length;
7058 + if (c == 0)
7059 + {
7060 + for (size_t u = 0; u < s1.length; u++)
7061 + { Object o1 = s1[u];
7062 + Object o2 = s2[u];
7063 +
7064 + if (o1 is o2)
7065 + continue;
7066 +
7067 + // Regard null references as always being "less than"
7068 + if (o1)
7069 + {
7070 + if (!o2)
7071 + { c = 1;
7072 + break;
7073 + }
7074 + c = o1.opCmp(o2);
7075 + if (c)
7076 + break;
7077 + }
7078 + else
7079 + { c = -1;
7080 + break;
7081 + }
7082 + }
7083 + }
7084 + if (c < 0)
7085 + c = -1;
7086 + else if (c > 0)
7087 + c = 1;
7088 + return c;
7089 + }
7090 +
7091 + override size_t tsize()
7092 + {
7093 + return (Object[]).sizeof;
7094 + }
7095 +
7096 + override uint flags()
7097 + {
7098 + return 1;
7099 + }
7100 +
7101 + override TypeInfo next()
7102 + {
7103 + return typeid(Object);
7104 + }
7105 +}
7106 Index: src/compiler/ldc/typeinfo/ti_ulong.d
7107 ===================================================================
7108 --- src/compiler/ldc/typeinfo/ti_ulong.d (revision 0)
7109 +++ src/compiler/ldc/typeinfo/ti_ulong.d (revision 0)
7110 @@ -0,0 +1,42 @@
7111 +
7112 +// ulong
7113 +
7114 +module rt.typeinfo.ti_ulong;
7115 +
7116 +class TypeInfo_m : TypeInfo
7117 +{
7118 + override string toString() { return "ulong"; }
7119 +
7120 + override hash_t getHash(in void* p)
7121 + {
7122 + return *cast(uint *)p + (cast(uint *)p)[1];
7123 + }
7124 +
7125 + override equals_t equals(in void* p1, in void* p2)
7126 + {
7127 + return *cast(ulong *)p1 == *cast(ulong *)p2;
7128 + }
7129 +
7130 + override int compare(in void* p1, in void* p2)
7131 + {
7132 + if (*cast(ulong *)p1 < *cast(ulong *)p2)
7133 + return -1;
7134 + else if (*cast(ulong *)p1 > *cast(ulong *)p2)
7135 + return 1;
7136 + return 0;
7137 + }
7138 +
7139 + override size_t tsize()
7140 + {
7141 + return ulong.sizeof;
7142 + }
7143 +
7144 + override void swap(void *p1, void *p2)
7145 + {
7146 + ulong t;
7147 +
7148 + t = *cast(ulong *)p1;
7149 + *cast(ulong *)p1 = *cast(ulong *)p2;
7150 + *cast(ulong *)p2 = t;
7151 + }
7152 +}
7153 Index: src/compiler/ldc/typeinfo/ti_creal.d
7154 ===================================================================
7155 --- src/compiler/ldc/typeinfo/ti_creal.d (revision 0)
7156 +++ src/compiler/ldc/typeinfo/ti_creal.d (revision 0)
7157 @@ -0,0 +1,67 @@
7158 +
7159 +// creal
7160 +
7161 +module rt.typeinfo.ti_creal;
7162 +
7163 +class TypeInfo_c : TypeInfo
7164 +{
7165 + override string toString() { return "creal"; }
7166 +
7167 + override hash_t getHash(in void* p)
7168 + {
7169 + return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
7170 + (cast(uint *)p)[2] + (cast(uint *)p)[3] +
7171 + (cast(uint *)p)[4];
7172 + }
7173 +
7174 + static equals_t _equals(creal f1, creal f2)
7175 + {
7176 + return f1 == f2;
7177 + }
7178 +
7179 + static int _compare(creal f1, creal f2)
7180 + { int result;
7181 +
7182 + if (f1.re < f2.re)
7183 + result = -1;
7184 + else if (f1.re > f2.re)
7185 + result = 1;
7186 + else if (f1.im < f2.im)
7187 + result = -1;
7188 + else if (f1.im > f2.im)
7189 + result = 1;
7190 + else
7191 + result = 0;
7192 + return result;
7193 + }
7194 +
7195 + override equals_t equals(in void* p1, in void* p2)
7196 + {
7197 + return _equals(*cast(creal *)p1, *cast(creal *)p2);
7198 + }
7199 +
7200 + override int compare(in void* p1, in void* p2)
7201 + {
7202 + return _compare(*cast(creal *)p1, *cast(creal *)p2);
7203 + }
7204 +
7205 + override size_t tsize()
7206 + {
7207 + return creal.sizeof;
7208 + }
7209 +
7210 + override void swap(void *p1, void *p2)
7211 + {
7212 + creal t;
7213 +
7214 + t = *cast(creal *)p1;
7215 + *cast(creal *)p1 = *cast(creal *)p2;
7216 + *cast(creal *)p2 = t;
7217 + }
7218 +
7219 + override void[] init()
7220 + { static creal r;
7221 +
7222 + return (cast(creal *)&r)[0 .. 1];
7223 + }
7224 +}
7225 Index: src/compiler/ldc/typeinfo/ti_ubyte.d
7226 ===================================================================
7227 --- src/compiler/ldc/typeinfo/ti_ubyte.d (revision 0)
7228 +++ src/compiler/ldc/typeinfo/ti_ubyte.d (revision 0)
7229 @@ -0,0 +1,43 @@
7230 +
7231 +// ubyte
7232 +
7233 +module rt.typeinfo.ti_ubyte;
7234 +
7235 +class TypeInfo_h : TypeInfo
7236 +{
7237 + override string toString() { return "ubyte"; }
7238 +
7239 + override hash_t getHash(in void* p)
7240 + {
7241 + return *cast(ubyte *)p;
7242 + }
7243 +
7244 + override equals_t equals(in void* p1, in void* p2)
7245 + {
7246 + return *cast(ubyte *)p1 == *cast(ubyte *)p2;
7247 + }
7248 +
7249 + override int compare(in void* p1, in void* p2)
7250 + {
7251 + return *cast(ubyte *)p1 - *cast(ubyte *)p2;
7252 + }
7253 +
7254 + override size_t tsize()
7255 + {
7256 + return ubyte.sizeof;
7257 + }
7258 +
7259 + override void swap(void *p1, void *p2)
7260 + {
7261 + ubyte t;
7262 +
7263 + t = *cast(ubyte *)p1;
7264 + *cast(ubyte *)p1 = *cast(ubyte *)p2;
7265 + *cast(ubyte *)p2 = t;
7266 + }
7267 +}
7268 +
7269 +class TypeInfo_b : TypeInfo_h
7270 +{
7271 + override string toString() { return "bool"; }
7272 +}
7273 Index: src/compiler/ldc/typeinfo/ti_Aint.d
7274 ===================================================================
7275 --- src/compiler/ldc/typeinfo/ti_Aint.d (revision 0)
7276 +++ src/compiler/ldc/typeinfo/ti_Aint.d (revision 0)
7277 @@ -0,0 +1,129 @@
7278 +
7279 +module rt.typeinfo.ti_Aint;
7280 +
7281 +private import core.stdc.string;
7282 +
7283 +// int[]
7284 +
7285 +class TypeInfo_Ai : TypeInfo
7286 +{
7287 + override string toString() { return "int[]"; }
7288 +
7289 + override hash_t getHash(in void* p)
7290 + { int[] s = *cast(int[]*)p;
7291 + auto len = s.length;
7292 + auto str = s.ptr;
7293 + hash_t hash = 0;
7294 +
7295 + while (len)
7296 + {
7297 + hash *= 9;
7298 + hash += *cast(uint *)str;
7299 + str++;
7300 + len--;
7301 + }
7302 +
7303 + return hash;
7304 + }
7305 +
7306 + override equals_t equals(in void* p1, in void* p2)
7307 + {
7308 + int[] s1 = *cast(int[]*)p1;
7309 + int[] s2 = *cast(int[]*)p2;
7310 +
7311 + return s1.length == s2.length &&
7312 + memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0;
7313 + }
7314 +
7315 + override int compare(in void* p1, in void* p2)
7316 + {
7317 + int[] s1 = *cast(int[]*)p1;
7318 + int[] s2 = *cast(int[]*)p2;
7319 + size_t len = s1.length;
7320 +
7321 + if (s2.length < len)
7322 + len = s2.length;
7323 + for (size_t u = 0; u < len; u++)
7324 + {
7325 + int result = s1[u] - s2[u];
7326 + if (result)
7327 + return result;
7328 + }
7329 + if (s1.length < s2.length)
7330 + return -1;
7331 + else if (s1.length > s2.length)
7332 + return 1;
7333 + return 0;
7334 + }
7335 +
7336 + override size_t tsize()
7337 + {
7338 + return (int[]).sizeof;
7339 + }
7340 +
7341 + override uint flags()
7342 + {
7343 + return 1;
7344 + }
7345 +
7346 + override TypeInfo next()
7347 + {
7348 + return typeid(int);
7349 + }
7350 +}
7351 +
7352 +unittest
7353 +{
7354 + int[][] a = [[5,3,8,7], [2,5,3,8,7]];
7355 + a.sort;
7356 + assert(a == [[2,5,3,8,7], [5,3,8,7]]);
7357 +
7358 + a = [[5,3,8,7], [5,3,8]];
7359 + a.sort;
7360 + assert(a == [[5,3,8], [5,3,8,7]]);
7361 +}
7362 +
7363 +// uint[]
7364 +
7365 +class TypeInfo_Ak : TypeInfo_Ai
7366 +{
7367 + override string toString() { return "uint[]"; }
7368 +
7369 + override int compare(in void* p1, in void* p2)
7370 + {
7371 + uint[] s1 = *cast(uint[]*)p1;
7372 + uint[] s2 = *cast(uint[]*)p2;
7373 + size_t len = s1.length;
7374 +
7375 + if (s2.length < len)
7376 + len = s2.length;
7377 + for (size_t u = 0; u < len; u++)
7378 + {
7379 + int result = s1[u] - s2[u];
7380 + if (result)
7381 + return result;
7382 + }
7383 + if (s1.length < s2.length)
7384 + return -1;
7385 + else if (s1.length > s2.length)
7386 + return 1;
7387 + return 0;
7388 + }
7389 +
7390 + override TypeInfo next()
7391 + {
7392 + return typeid(uint);
7393 + }
7394 +}
7395 +
7396 +// dchar[]
7397 +
7398 +class TypeInfo_Aw : TypeInfo_Ak
7399 +{
7400 + override string toString() { return "dchar[]"; }
7401 +
7402 + override TypeInfo next()
7403 + {
7404 + return typeid(dchar);
7405 + }
7406 +}
7407 Index: src/compiler/ldc/typeinfo/ti_ireal.d
7408 ===================================================================
7409 --- src/compiler/ldc/typeinfo/ti_ireal.d (revision 0)
7410 +++ src/compiler/ldc/typeinfo/ti_ireal.d (revision 0)
7411 @@ -0,0 +1,11 @@
7412 +
7413 +// ireal
7414 +
7415 +module rt.typeinfo.ti_ireal;
7416 +
7417 +private import typeinfo.ti_real;
7418 +
7419 +class TypeInfo_j : TypeInfo_e
7420 +{
7421 + override string toString() { return "ireal"; }
7422 +}
7423 Index: src/compiler/ldc/typeinfo/ti_long.d
7424 ===================================================================
7425 --- src/compiler/ldc/typeinfo/ti_long.d (revision 0)
7426 +++ src/compiler/ldc/typeinfo/ti_long.d (revision 0)
7427 @@ -0,0 +1,42 @@
7428 +
7429 +// long
7430 +
7431 +module rt.typeinfo.ti_long;
7432 +
7433 +class TypeInfo_l : TypeInfo
7434 +{
7435 + override string toString() { return "long"; }
7436 +
7437 + override hash_t getHash(in void* p)
7438 + {
7439 + return *cast(uint *)p + (cast(uint *)p)[1];
7440 + }
7441 +
7442 + override equals_t equals(in void* p1, in void* p2)
7443 + {
7444 + return *cast(long *)p1 == *cast(long *)p2;
7445 + }
7446 +
7447 + override int compare(in void* p1, in void* p2)
7448 + {
7449 + if (*cast(long *)p1 < *cast(long *)p2)
7450 + return -1;
7451 + else if (*cast(long *)p1 > *cast(long *)p2)
7452 + return 1;
7453 + return 0;
7454 + }
7455 +
7456 + override size_t tsize()
7457 + {
7458 + return long.sizeof;
7459 + }
7460 +
7461 + override void swap(void *p1, void *p2)
7462 + {
7463 + long t;
7464 +
7465 + t = *cast(long *)p1;
7466 + *cast(long *)p1 = *cast(long *)p2;
7467 + *cast(long *)p2 = t;
7468 + }
7469 +}
7470 Index: src/compiler/ldc/typeinfo/ti_short.d
7471 ===================================================================
7472 --- src/compiler/ldc/typeinfo/ti_short.d (revision 0)
7473 +++ src/compiler/ldc/typeinfo/ti_short.d (revision 0)
7474 @@ -0,0 +1,38 @@
7475 +
7476 +// short
7477 +
7478 +module rt.typeinfo.ti_short;
7479 +
7480 +class TypeInfo_s : TypeInfo
7481 +{
7482 + override string toString() { return "short"; }
7483 +
7484 + override hash_t getHash(in void* p)
7485 + {
7486 + return *cast(short *)p;
7487 + }
7488 +
7489 + override equals_t equals(in void* p1, in void* p2)
7490 + {
7491 + return *cast(short *)p1 == *cast(short *)p2;
7492 + }
7493 +
7494 + override int compare(in void* p1, in void* p2)
7495 + {
7496 + return *cast(short *)p1 - *cast(short *)p2;
7497 + }
7498 +
7499 + override size_t tsize()
7500 + {
7501 + return short.sizeof;
7502 + }
7503 +
7504 + override void swap(void *p1, void *p2)
7505 + {
7506 + short t;
7507 +
7508 + t = *cast(short *)p1;
7509 + *cast(short *)p1 = *cast(short *)p2;
7510 + *cast(short *)p2 = t;
7511 + }
7512 +}
7513 Index: src/compiler/ldc/typeinfo/ti_Along.d
7514 ===================================================================
7515 --- src/compiler/ldc/typeinfo/ti_Along.d (revision 0)
7516 +++ src/compiler/ldc/typeinfo/ti_Along.d (revision 0)
7517 @@ -0,0 +1,109 @@
7518 +
7519 +module rt.typeinfo.ti_Along;
7520 +
7521 +private import core.stdc.string;
7522 +
7523 +// long[]
7524 +
7525 +class TypeInfo_Al : TypeInfo
7526 +{
7527 + override string toString() { return "long[]"; }
7528 +
7529 + override hash_t getHash(in void* p)
7530 + { long[] s = *cast(long[]*)p;
7531 + size_t len = s.length;
7532 + auto str = s.ptr;
7533 + hash_t hash = 0;
7534 +
7535 + while (len)
7536 + {
7537 + hash *= 9;
7538 + hash += *cast(uint *)str + *(cast(uint *)str + 1);
7539 + str++;
7540 + len--;
7541 + }
7542 +
7543 + return hash;
7544 + }
7545 +
7546 + override equals_t equals(in void* p1, in void* p2)
7547 + {
7548 + long[] s1 = *cast(long[]*)p1;
7549 + long[] s2 = *cast(long[]*)p2;
7550 +
7551 + return s1.length == s2.length &&
7552 + memcmp(cast(void *)s1, cast(void *)s2, s1.length * long.sizeof) == 0;
7553 + }
7554 +
7555 + override int compare(in void* p1, in void* p2)
7556 + {
7557 + long[] s1 = *cast(long[]*)p1;
7558 + long[] s2 = *cast(long[]*)p2;
7559 + size_t len = s1.length;
7560 +
7561 + if (s2.length < len)
7562 + len = s2.length;
7563 + for (size_t u = 0; u < len; u++)
7564 + {
7565 + if (s1[u] < s2[u])
7566 + return -1;
7567 + else if (s1[u] > s2[u])
7568 + return 1;
7569 + }
7570 + if (s1.length < s2.length)
7571 + return -1;
7572 + else if (s1.length > s2.length)
7573 + return 1;
7574 + return 0;
7575 + }
7576 +
7577 + override size_t tsize()
7578 + {
7579 + return (long[]).sizeof;
7580 + }
7581 +
7582 + override uint flags()
7583 + {
7584 + return 1;
7585 + }
7586 +
7587 + override TypeInfo next()
7588 + {
7589 + return typeid(long);
7590 + }
7591 +}
7592 +
7593 +
7594 +// ulong[]
7595 +
7596 +class TypeInfo_Am : TypeInfo_Al
7597 +{
7598 + override string toString() { return "ulong[]"; }
7599 +
7600 + override int compare(in void* p1, in void* p2)
7601 + {
7602 + ulong[] s1 = *cast(ulong[]*)p1;
7603 + ulong[] s2 = *cast(ulong[]*)p2;
7604 + size_t len = s1.length;
7605 +
7606 + if (s2.length < len)
7607 + len = s2.length;
7608 + for (size_t u = 0; u < len; u++)
7609 + {
7610 + if (s1[u] < s2[u])
7611 + return -1;
7612 + else if (s1[u] > s2[u])
7613 + return 1;
7614 + }
7615 + if (s1.length < s2.length)
7616 + return -1;
7617 + else if (s1.length > s2.length)
7618 + return 1;
7619 + return 0;
7620 + }
7621 +
7622 + override TypeInfo next()
7623 + {
7624 + return typeid(ulong);
7625 + }
7626 +}
7627 Index: src/compiler/ldc/typeinfo/ti_byte.d
7628 ===================================================================
7629 --- src/compiler/ldc/typeinfo/ti_byte.d (revision 0)
7630 +++ src/compiler/ldc/typeinfo/ti_byte.d (revision 0)
7631 @@ -0,0 +1,38 @@
7632 +
7633 +// byte
7634 +
7635 +module rt.typeinfo.ti_byte;
7636 +
7637 +class TypeInfo_g : TypeInfo
7638 +{
7639 + override string toString() { return "byte"; }
7640 +
7641 + override hash_t getHash(in void* p)
7642 + {
7643 + return *cast(byte *)p;
7644 + }
7645 +
7646 + override equals_t equals(in void* p1, in void* p2)
7647 + {
7648 + return *cast(byte *)p1 == *cast(byte *)p2;
7649 + }
7650 +
7651 + override int compare(in void* p1, in void* p2)
7652 + {
7653 + return *cast(byte *)p1 - *cast(byte *)p2;
7654 + }
7655 +
7656 + override size_t tsize()
7657 + {
7658 + return byte.sizeof;
7659 + }
7660 +
7661 + override void swap(void *p1, void *p2)
7662 + {
7663 + byte t;
7664 +
7665 + t = *cast(byte *)p1;
7666 + *cast(byte *)p1 = *cast(byte *)p2;
7667 + *cast(byte *)p2 = t;
7668 + }
7669 +}
7670 Index: src/compiler/ldc/typeinfo/ti_float.d
7671 ===================================================================
7672 --- src/compiler/ldc/typeinfo/ti_float.d (revision 0)
7673 +++ src/compiler/ldc/typeinfo/ti_float.d (revision 0)
7674 @@ -0,0 +1,64 @@
7675 +
7676 +// float
7677 +
7678 +module rt.typeinfo.ti_float;
7679 +
7680 +class TypeInfo_f : TypeInfo
7681 +{
7682 + override string toString() { return "float"; }
7683 +
7684 + override hash_t getHash(in void* p)
7685 + {
7686 + return *cast(uint *)p;
7687 + }
7688 +
7689 + static equals_t _equals(float f1, float f2)
7690 + {
7691 + return f1 == f2 ||
7692 + (f1 !<>= f1 && f2 !<>= f2);
7693 + }
7694 +
7695 + static int _compare(float d1, float d2)
7696 + {
7697 + if (d1 !<>= d2) // if either are NaN
7698 + {
7699 + if (d1 !<>= d1)
7700 + { if (d2 !<>= d2)
7701 + return 0;
7702 + return -1;
7703 + }
7704 + return 1;
7705 + }
7706 + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
7707 + }
7708 +
7709 + override equals_t equals(in void* p1, in void* p2)
7710 + {
7711 + return _equals(*cast(float *)p1, *cast(float *)p2);
7712 + }
7713 +
7714 + override int compare(in void* p1, in void* p2)
7715 + {
7716 + return _compare(*cast(float *)p1, *cast(float *)p2);
7717 + }
7718 +
7719 + override size_t tsize()
7720 + {
7721 + return float.sizeof;
7722 + }
7723 +
7724 + override void swap(void *p1, void *p2)
7725 + {
7726 + float t;
7727 +
7728 + t = *cast(float *)p1;
7729 + *cast(float *)p1 = *cast(float *)p2;
7730 + *cast(float *)p2 = t;
7731 + }
7732 +
7733 + override void[] init()
7734 + { static float r;
7735 +
7736 + return (cast(float *)&r)[0 .. 1];
7737 + }
7738 +}
7739 Index: src/compiler/ldc/typeinfo/ti_cfloat.d
7740 ===================================================================
7741 --- src/compiler/ldc/typeinfo/ti_cfloat.d (revision 0)
7742 +++ src/compiler/ldc/typeinfo/ti_cfloat.d (revision 0)
7743 @@ -0,0 +1,65 @@
7744 +
7745 +// cfloat
7746 +
7747 +module rt.typeinfo.ti_cfloat;
7748 +
7749 +class TypeInfo_q : TypeInfo
7750 +{
7751 + override string toString() { return "cfloat"; }
7752 +
7753 + override hash_t getHash(in void* p)
7754 + {
7755 + return (cast(uint *)p)[0] + (cast(uint *)p)[1];
7756 + }
7757 +
7758 + static equals_t _equals(cfloat f1, cfloat f2)
7759 + {
7760 + return f1 == f2;
7761 + }
7762 +
7763 + static int _compare(cfloat f1, cfloat f2)
7764 + { int result;
7765 +
7766 + if (f1.re < f2.re)
7767 + result = -1;
7768 + else if (f1.re > f2.re)
7769 + result = 1;
7770 + else if (f1.im < f2.im)
7771 + result = -1;
7772 + else if (f1.im > f2.im)
7773 + result = 1;
7774 + else
7775 + result = 0;
7776 + return result;
7777 + }
7778 +
7779 + override equals_t equals(in void* p1, in void* p2)
7780 + {
7781 + return _equals(*cast(cfloat *)p1, *cast(cfloat *)p2);
7782 + }
7783 +
7784 + override int compare(in void* p1, in void* p2)
7785 + {
7786 + return _compare(*cast(cfloat *)p1, *cast(cfloat *)p2);
7787 + }
7788 +
7789 + override size_t tsize()
7790 + {
7791 + return cfloat.sizeof;
7792 + }
7793 +
7794 + override void swap(void *p1, void *p2)
7795 + {
7796 + cfloat t;
7797 +
7798 + t = *cast(cfloat *)p1;
7799 + *cast(cfloat *)p1 = *cast(cfloat *)p2;
7800 + *cast(cfloat *)p2 = t;
7801 + }
7802 +
7803 + override void[] init()
7804 + { static cfloat r;
7805 +
7806 + return (cast(cfloat *)&r)[0 .. 1];
7807 + }
7808 +}
7809 Index: src/compiler/ldc/typeinfo/ti_Acfloat.d
7810 ===================================================================
7811 --- src/compiler/ldc/typeinfo/ti_Acfloat.d (revision 0)
7812 +++ src/compiler/ldc/typeinfo/ti_Acfloat.d (revision 0)
7813 @@ -0,0 +1,103 @@
7814 +/*
7815 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
7816 + * Written by Walter Bright
7817 + *
7818 + * This software is provided 'as-is', without any express or implied
7819 + * warranty. In no event will the authors be held liable for any damages
7820 + * arising from the use of this software.
7821 + *
7822 + * Permission is granted to anyone to use this software for any purpose,
7823 + * including commercial applications, and to alter it and redistribute it
7824 + * freely, in both source and binary form, subject to the following
7825 + * restrictions:
7826 + *
7827 + * o The origin of this software must not be misrepresented; you must not
7828 + * claim that you wrote the original software. If you use this software
7829 + * in a product, an acknowledgment in the product documentation would be
7830 + * appreciated but is not required.
7831 + * o Altered source versions must be plainly marked as such, and must not
7832 + * be misrepresented as being the original software.
7833 + * o This notice may not be removed or altered from any source
7834 + * distribution.
7835 + */
7836 +
7837 +module rt.typeinfo.ti_Acfloat;
7838 +
7839 +private import typeinfo.ti_cfloat;
7840 +
7841 +// cfloat[]
7842 +
7843 +class TypeInfo_Aq : TypeInfo
7844 +{
7845 + override string toString() { return "cfloat[]"; }
7846 +
7847 + override hash_t getHash(in void* p)
7848 + { cfloat[] s = *cast(cfloat[]*)p;
7849 + size_t len = s.length;
7850 + cfloat *str = s.ptr;
7851 + hash_t hash = 0;
7852 +
7853 + while (len)
7854 + {
7855 + hash *= 9;
7856 + hash += (cast(uint *)str)[0];
7857 + hash += (cast(uint *)str)[1];
7858 + str++;
7859 + len--;
7860 + }
7861 +
7862 + return hash;
7863 + }
7864 +
7865 + override equals_t equals(in void* p1, in void* p2)
7866 + {
7867 + cfloat[] s1 = *cast(cfloat[]*)p1;
7868 + cfloat[] s2 = *cast(cfloat[]*)p2;
7869 + size_t len = s1.length;
7870 +
7871 + if (len != s2.length)
7872 + return false;
7873 + for (size_t u = 0; u < len; u++)
7874 + {
7875 + if (!TypeInfo_q._equals(s1[u], s2[u]))
7876 + return false;
7877 + }
7878 + return true;
7879 + }
7880 +
7881 + override int compare(in void* p1, in void* p2)
7882 + {
7883 + cfloat[] s1 = *cast(cfloat[]*)p1;
7884 + cfloat[] s2 = *cast(cfloat[]*)p2;
7885 + size_t len = s1.length;
7886 +
7887 + if (s2.length < len)
7888 + len = s2.length;
7889 + for (size_t u = 0; u < len; u++)
7890 + {
7891 + int c = TypeInfo_q._compare(s1[u], s2[u]);
7892 + if (c)
7893 + return c;
7894 + }
7895 + if (s1.length < s2.length)
7896 + return -1;
7897 + else if (s1.length > s2.length)
7898 + return 1;
7899 + return 0;
7900 + }
7901 +
7902 + override size_t tsize()
7903 + {
7904 + return (cfloat[]).sizeof;
7905 + }
7906 +
7907 + override uint flags()
7908 + {
7909 + return 1;
7910 + }
7911 +
7912 + override TypeInfo next()
7913 + {
7914 + return typeid(cfloat);
7915 + }
7916 +}
7917 Index: src/compiler/ldc/typeinfo/ti_cdouble.d
7918 ===================================================================
7919 --- src/compiler/ldc/typeinfo/ti_cdouble.d (revision 0)
7920 +++ src/compiler/ldc/typeinfo/ti_cdouble.d (revision 0)
7921 @@ -0,0 +1,66 @@
7922 +
7923 +// cdouble
7924 +
7925 +module rt.typeinfo.ti_cdouble;
7926 +
7927 +class TypeInfo_r : TypeInfo
7928 +{
7929 + override string toString() { return "cdouble"; }
7930 +
7931 + override hash_t getHash(in void* p)
7932 + {
7933 + return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
7934 + (cast(uint *)p)[2] + (cast(uint *)p)[3];
7935 + }
7936 +
7937 + static equals_t _equals(cdouble f1, cdouble f2)
7938 + {
7939 + return f1 == f2;
7940 + }
7941 +
7942 + static int _compare(cdouble f1, cdouble f2)
7943 + { int result;
7944 +
7945 + if (f1.re < f2.re)
7946 + result = -1;
7947 + else if (f1.re > f2.re)
7948 + result = 1;
7949 + else if (f1.im < f2.im)
7950 + result = -1;
7951 + else if (f1.im > f2.im)
7952 + result = 1;
7953 + else
7954 + result = 0;
7955 + return result;
7956 + }
7957 +
7958 + override equals_t equals(in void* p1, in void* p2)
7959 + {
7960 + return _equals(*cast(cdouble *)p1, *cast(cdouble *)p2);
7961 + }
7962 +
7963 + override int compare(in void* p1, in void* p2)
7964 + {
7965 + return _compare(*cast(cdouble *)p1, *cast(cdouble *)p2);
7966 + }
7967 +
7968 + override size_t tsize()
7969 + {
7970 + return cdouble.sizeof;
7971 + }
7972 +
7973 + override void swap(void *p1, void *p2)
7974 + {
7975 + cdouble t;
7976 +
7977 + t = *cast(cdouble *)p1;
7978 + *cast(cdouble *)p1 = *cast(cdouble *)p2;
7979 + *cast(cdouble *)p2 = t;
7980 + }
7981 +
7982 + override void[] init()
7983 + { static cdouble r;
7984 +
7985 + return (cast(cdouble *)&r)[0 .. 1];
7986 + }
7987 +}
7988 Index: src/compiler/ldc/typeinfo/ti_ifloat.d
7989 ===================================================================
7990 --- src/compiler/ldc/typeinfo/ti_ifloat.d (revision 0)
7991 +++ src/compiler/ldc/typeinfo/ti_ifloat.d (revision 0)
7992 @@ -0,0 +1,11 @@
7993 +
7994 +// ifloat
7995 +
7996 +module rt.typeinfo.ti_ifloat;
7997 +
7998 +private import typeinfo.ti_float;
7999 +
8000 +class TypeInfo_o : TypeInfo_f
8001 +{
8002 + override string toString() { return "ifloat"; }
8003 +}
8004 Index: src/compiler/ldc/typeinfo/ti_dchar.d
8005 ===================================================================
8006 --- src/compiler/ldc/typeinfo/ti_dchar.d (revision 0)
8007 +++ src/compiler/ldc/typeinfo/ti_dchar.d (revision 0)
8008 @@ -0,0 +1,44 @@
8009 +
8010 +// dchar
8011 +
8012 +module rt.typeinfo.ti_dchar;
8013 +
8014 +class TypeInfo_w : TypeInfo
8015 +{
8016 + override string toString() { return "dchar"; }
8017 +
8018 + override hash_t getHash(in void* p)
8019 + {
8020 + return *cast(dchar *)p;
8021 + }
8022 +
8023 + override equals_t equals(in void* p1, in void* p2)
8024 + {
8025 + return *cast(dchar *)p1 == *cast(dchar *)p2;
8026 + }
8027 +
8028 + override int compare(in void* p1, in void* p2)
8029 + {
8030 + return *cast(dchar *)p1 - *cast(dchar *)p2;
8031 + }
8032 +
8033 + override size_t tsize()
8034 + {
8035 + return dchar.sizeof;
8036 + }
8037 +
8038 + override void swap(void *p1, void *p2)
8039 + {
8040 + dchar t;
8041 +
8042 + t = *cast(dchar *)p1;
8043 + *cast(dchar *)p1 = *cast(dchar *)p2;
8044 + *cast(dchar *)p2 = t;
8045 + }
8046 +
8047 + override void[] init()
8048 + { static dchar c;
8049 +
8050 + return (cast(dchar *)&c)[0 .. 1];
8051 + }
8052 +}
8053 Index: src/compiler/ldc/typeinfo/ti_C.d
8054 ===================================================================
8055 --- src/compiler/ldc/typeinfo/ti_C.d (revision 0)
8056 +++ src/compiler/ldc/typeinfo/ti_C.d (revision 0)
8057 @@ -0,0 +1,74 @@
8058 +/*
8059 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
8060 + * Written by Walter Bright
8061 + *
8062 + * This software is provided 'as-is', without any express or implied
8063 + * warranty. In no event will the authors be held liable for any damages
8064 + * arising from the use of this software.
8065 + *
8066 + * Permission is granted to anyone to use this software for any purpose,
8067 + * including commercial applications, and to alter it and redistribute it
8068 + * freely, in both source and binary form, subject to the following
8069 + * restrictions:
8070 + *
8071 + * o The origin of this software must not be misrepresented; you must not
8072 + * claim that you wrote the original software. If you use this software
8073 + * in a product, an acknowledgment in the product documentation would be
8074 + * appreciated but is not required.
8075 + * o Altered source versions must be plainly marked as such, and must not
8076 + * be misrepresented as being the original software.
8077 + * o This notice may not be removed or altered from any source
8078 + * distribution.
8079 + */
8080 +
8081 +module rt.typeinfo.ti_C;
8082 +
8083 +// Object
8084 +
8085 +class TypeInfo_C : TypeInfo
8086 +{
8087 + override hash_t getHash(in void* p)
8088 + {
8089 + Object o = *cast(Object*)p;
8090 + return o ? o.toHash() : 0;
8091 + }
8092 +
8093 + override equals_t equals(in void* p1, in void* p2)
8094 + {
8095 + Object o1 = *cast(Object*)p1;
8096 + Object o2 = *cast(Object*)p2;
8097 +
8098 + return o1 == o2;
8099 + }
8100 +
8101 + override int compare(in void* p1, in void* p2)
8102 + {
8103 + Object o1 = *cast(Object*)p1;
8104 + Object o2 = *cast(Object*)p2;
8105 + int c = 0;
8106 +
8107 + // Regard null references as always being "less than"
8108 + if (!(o1 is o2))
8109 + {
8110 + if (o1)
8111 + { if (!o2)
8112 + c = 1;
8113 + else
8114 + c = o1.opCmp(o2);
8115 + }
8116 + else
8117 + c = -1;
8118 + }
8119 + return c;
8120 + }
8121 +
8122 + override size_t tsize()
8123 + {
8124 + return Object.sizeof;
8125 + }
8126 +
8127 + override uint flags()
8128 + {
8129 + return 1;
8130 + }
8131 +}
8132 Index: src/compiler/ldc/typeinfo/ti_real.d
8133 ===================================================================
8134 --- src/compiler/ldc/typeinfo/ti_real.d (revision 0)
8135 +++ src/compiler/ldc/typeinfo/ti_real.d (revision 0)
8136 @@ -0,0 +1,64 @@
8137 +
8138 +// real
8139 +
8140 +module rt.typeinfo.ti_real;
8141 +
8142 +class TypeInfo_e : TypeInfo
8143 +{
8144 + override string toString() { return "real"; }
8145 +
8146 + override hash_t getHash(in void* p)
8147 + {
8148 + return (cast(uint *)p)[0] + (cast(uint *)p)[1] + (cast(ushort *)p)[4];
8149 + }
8150 +
8151 + static equals_t _equals(real f1, real f2)
8152 + {
8153 + return f1 == f2 ||
8154 + (f1 !<>= f1 && f2 !<>= f2);
8155 + }
8156 +
8157 + static int _compare(real d1, real d2)
8158 + {
8159 + if (d1 !<>= d2) // if either are NaN
8160 + {
8161 + if (d1 !<>= d1)
8162 + { if (d2 !<>= d2)
8163 + return 0;
8164 + return -1;
8165 + }
8166 + return 1;
8167 + }
8168 + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
8169 + }
8170 +
8171 + override equals_t equals(in void* p1, in void* p2)
8172 + {
8173 + return _equals(*cast(real *)p1, *cast(real *)p2);
8174 + }
8175 +
8176 + override int compare(in void* p1, in void* p2)
8177 + {
8178 + return _compare(*cast(real *)p1, *cast(real *)p2);
8179 + }
8180 +
8181 + override size_t tsize()
8182 + {
8183 + return real.sizeof;
8184 + }
8185 +
8186 + override void swap(void *p1, void *p2)
8187 + {
8188 + real t;
8189 +
8190 + t = *cast(real *)p1;
8191 + *cast(real *)p1 = *cast(real *)p2;
8192 + *cast(real *)p2 = t;
8193 + }
8194 +
8195 + override void[] init()
8196 + { static real r;
8197 +
8198 + return (cast(real *)&r)[0 .. 1];
8199 + }
8200 +}
8201 Index: src/compiler/ldc/typeinfo/ti_idouble.d
8202 ===================================================================
8203 --- src/compiler/ldc/typeinfo/ti_idouble.d (revision 0)
8204 +++ src/compiler/ldc/typeinfo/ti_idouble.d (revision 0)
8205 @@ -0,0 +1,11 @@
8206 +
8207 +// idouble
8208 +
8209 +module rt.typeinfo.ti_idouble;
8210 +
8211 +private import typeinfo.ti_double;
8212 +
8213 +class TypeInfo_p : TypeInfo_d
8214 +{
8215 + override string toString() { return "idouble"; }
8216 +}
8217 Index: src/compiler/ldc/typeinfo/ti_Areal.d
8218 ===================================================================
8219 --- src/compiler/ldc/typeinfo/ti_Areal.d (revision 0)
8220 +++ src/compiler/ldc/typeinfo/ti_Areal.d (revision 0)
8221 @@ -0,0 +1,116 @@
8222 +/*
8223 + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
8224 + * Written by Walter Bright
8225 + *
8226 + * This software is provided 'as-is', without any express or implied
8227 + * warranty. In no event will the authors be held liable for any damages
8228 + * arising from the use of this software.
8229 + *
8230 + * Permission is granted to anyone to use this software for any purpose,
8231 + * including commercial applications, and to alter it and redistribute it
8232 + * freely, in both source and binary form, subject to the following
8233 + * restrictions:
8234 + *
8235 + * o The origin of this software must not be misrepresented; you must not
8236 + * claim that you wrote the original software. If you use this software
8237 + * in a product, an acknowledgment in the product documentation would be
8238 + * appreciated but is not required.
8239 + * o Altered source versions must be plainly marked as such, and must not
8240 + * be misrepresented as being the original software.
8241 + * o This notice may not be removed or altered from any source
8242 + * distribution.
8243 + */
8244 +
8245 +module rt.typeinfo.ti_Areal;
8246 +
8247 +private import typeinfo.ti_real;
8248 +
8249 +// real[]
8250 +
8251 +class TypeInfo_Ae : TypeInfo
8252 +{
8253 + override string toString() { return "real[]"; }
8254 +
8255 + override hash_t getHash(in void* p)
8256 + { real[] s = *cast(real[]*)p;
8257 + size_t len = s.length;
8258 + auto str = s.ptr;
8259 + hash_t hash = 0;
8260 +
8261 + while (len)
8262 + {
8263 + hash *= 9;
8264 + hash += (cast(uint *)str)[0];
8265 + hash += (cast(uint *)str)[1];
8266 + hash += (cast(ushort *)str)[4];
8267 + str++;
8268 + len--;
8269 + }
8270 +
8271 + return hash;
8272 + }
8273 +
8274 + override equals_t equals(in void* p1, in void* p2)
8275 + {
8276 + real[] s1 = *cast(real[]*)p1;
8277 + real[] s2 = *cast(real[]*)p2;
8278 + size_t len = s1.length;
8279 +
8280 + if (len != s2.length)
8281 + return false;
8282 + for (size_t u = 0; u < len; u++)
8283 + {
8284 + if (!TypeInfo_e._equals(s1[u], s2[u]))
8285 + return false;
8286 + }
8287 + return true;
8288 + }
8289 +
8290 + override int compare(in void* p1, in void* p2)
8291 + {
8292 + real[] s1 = *cast(real[]*)p1;
8293 + real[] s2 = *cast(real[]*)p2;
8294 + size_t len = s1.length;
8295 +
8296 + if (s2.length < len)
8297 + len = s2.length;
8298 + for (size_t u = 0; u < len; u++)
8299 + {
8300 + int c = TypeInfo_e._compare(s1[u], s2[u]);
8301 + if (c)
8302 + return c;
8303 + }
8304 + if (s1.length < s2.length)
8305 + return -1;
8306 + else if (s1.length > s2.length)
8307 + return 1;
8308 + return 0;
8309 + }
8310 +
8311 + override size_t tsize()
8312 + {
8313 + return (real[]).sizeof;
8314 + }
8315 +
8316 + override uint flags()
8317 + {
8318 + return 1;
8319 + }
8320 +
8321 + override TypeInfo next()
8322 + {
8323 + return typeid(real);
8324 + }
8325 +}
8326 +
8327 +// ireal[]
8328 +
8329 +class TypeInfo_Aj : TypeInfo_Ae
8330 +{
8331 + override string toString() { return "ireal[]"; }
8332 +
8333 + override TypeInfo next()
8334 + {
8335 + return typeid(ireal);
8336 + }
8337 +}
8338 Index: src/compiler/ldc/typeinfo/ti_ushort.d
8339 ===================================================================
8340 --- src/compiler/ldc/typeinfo/ti_ushort.d (revision 0)
8341 +++ src/compiler/ldc/typeinfo/ti_ushort.d (revision 0)
8342 @@ -0,0 +1,38 @@
8343 +
8344 +// ushort
8345 +
8346 +module rt.typeinfo.ti_ushort;
8347 +
8348 +class TypeInfo_t : TypeInfo
8349 +{
8350 + override string toString() { return "ushort"; }
8351 +
8352 + override hash_t getHash(in void* p)
8353 + {
8354 + return *cast(ushort *)p;
8355 + }
8356 +
8357 + override equals_t equals(in void* p1, in void* p2)
8358 + {
8359 + return *cast(ushort *)p1 == *cast(ushort *)p2;
8360 + }
8361 +
8362 + override int compare(in void* p1, in void* p2)
8363 + {
8364 + return *cast(ushort *)p1 - *cast(ushort *)p2;
8365 + }
8366 +
8367 + override size_t tsize()
8368 + {
8369 + return ushort.sizeof;
8370 + }
8371 +
8372 + override void swap(void *p1, void *p2)
8373 + {
8374 + ushort t;
8375 +
8376 + t = *cast(ushort *)p1;
8377 + *cast(ushort *)p1 = *cast(ushort *)p2;
8378 + *cast(ushort *)p2 = t;
8379 + }
8380 +}
8381 Index: src/compiler/ldc/typeinfo/ti_Ag.d
8382 ===================================================================
8383 --- src/compiler/ldc/typeinfo/ti_Ag.d (revision 0)
8384 +++ src/compiler/ldc/typeinfo/ti_Ag.d (revision 0)
8385 @@ -0,0 +1,204 @@
8386 +
8387 +module rt.typeinfo.ti_Ag;
8388 +
8389 +private import util.string;
8390 +private import core.stdc.string;
8391 +
8392 +// byte[]
8393 +
8394 +class TypeInfo_Ag : TypeInfo
8395 +{
8396 + override string toString() { return "byte[]"; }
8397 +
8398 + override hash_t getHash(in void* p)
8399 + { byte[] s = *cast(byte[]*)p;
8400 + size_t len = s.length;
8401 + byte *str = s.ptr;
8402 + hash_t hash = 0;
8403 +
8404 + while (1)
8405 + {
8406 + switch (len)
8407 + {
8408 + case 0:
8409 + return hash;
8410 +
8411 + case 1:
8412 + hash *= 9;
8413 + hash += *cast(ubyte *)str;
8414 + return hash;
8415 +
8416 + case 2:
8417 + hash *= 9;
8418 + hash += *cast(ushort *)str;
8419 + return hash;
8420 +
8421 + case 3:
8422 + hash *= 9;
8423 + hash += (*cast(ushort *)str << 8) +
8424 + (cast(ubyte *)str)[2];
8425 + return hash;
8426 +
8427 + default:
8428 + hash *= 9;
8429 + hash += *cast(uint *)str;
8430 + str += 4;
8431 + len -= 4;
8432 + break;
8433 + }
8434 + }
8435 +
8436 + return hash;
8437 + }
8438 +
8439 + override equals_t equals(in void* p1, in void* p2)
8440 + {
8441 + byte[] s1 = *cast(byte[]*)p1;
8442 + byte[] s2 = *cast(byte[]*)p2;
8443 +
8444 + return s1.length == s2.length &&
8445 + memcmp(cast(byte *)s1, cast(byte *)s2, s1.length) == 0;
8446 + }
8447 +
8448 + override int compare(in void* p1, in void* p2)
8449 + {
8450 + byte[] s1 = *cast(byte[]*)p1;
8451 + byte[] s2 = *cast(byte[]*)p2;
8452 + size_t len = s1.length;
8453 +
8454 + if (s2.length < len)
8455 + len = s2.length;
8456 + for (size_t u = 0; u < len; u++)
8457 + {
8458 + int result = s1[u] - s2[u];
8459 + if (result)
8460 + return result;
8461 + }
8462 + if (s1.length < s2.length)
8463 + return -1;
8464 + else if (s1.length > s2.length)
8465 + return 1;
8466 + return 0;
8467 + }
8468 +
8469 + override size_t tsize()
8470 + {
8471 + return (byte[]).sizeof;
8472 + }
8473 +
8474 + override uint flags()
8475 + {
8476 + return 1;
8477 + }
8478 +
8479 + override TypeInfo next()
8480 + {
8481 + return typeid(byte);
8482 + }
8483 +}
8484 +
8485 +
8486 +// ubyte[]
8487 +
8488 +class TypeInfo_Ah : TypeInfo_Ag
8489 +{
8490 + override string toString() { return "ubyte[]"; }
8491 +
8492 + override int compare(in void* p1, in void* p2)
8493 + {
8494 + char[] s1 = *cast(char[]*)p1;
8495 + char[] s2 = *cast(char[]*)p2;
8496 +
8497 + return dstrcmp(s1, s2);
8498 + }
8499 +
8500 + override TypeInfo next()
8501 + {
8502 + return typeid(ubyte);
8503 + }
8504 +}
8505 +
8506 +// void[]
8507 +
8508 +class TypeInfo_Av : TypeInfo_Ah
8509 +{
8510 + override string toString() { return "void[]"; }
8511 +
8512 + override TypeInfo next()
8513 + {
8514 + return typeid(void);
8515 + }
8516 +}
8517 +
8518 +// bool[]
8519 +
8520 +class TypeInfo_Ab : TypeInfo_Ah
8521 +{
8522 + override string toString() { return "bool[]"; }
8523 +
8524 + override TypeInfo next()
8525 + {
8526 + return typeid(bool);
8527 + }
8528 +}
8529 +
8530 +// char[]
8531 +
8532 +class TypeInfo_Aa : TypeInfo_Ag
8533 +{
8534 + override string toString() { return "char[]"; }
8535 +
8536 + override hash_t getHash(in void* p)
8537 + { char[] s = *cast(char[]*)p;
8538 + hash_t hash = 0;
8539 +
8540 +version (all)
8541 +{
8542 + foreach (char c; s)
8543 + hash = hash * 11 + c;
8544 +}
8545 +else
8546 +{
8547 + size_t len = s.length;
8548 + char *str = s;
8549 +
8550 + while (1)
8551 + {
8552 + switch (len)
8553 + {
8554 + case 0:
8555 + return hash;
8556 +
8557 + case 1:
8558 + hash *= 9;
8559 + hash += *cast(ubyte *)str;
8560 + return hash;
8561 +
8562 + case 2:
8563 + hash *= 9;
8564 + hash += *cast(ushort *)str;
8565 + return hash;
8566 +
8567 + case 3:
8568 + hash *= 9;
8569 + hash += (*cast(ushort *)str << 8) +
8570 + (cast(ubyte *)str)[2];
8571 + return hash;
8572 +
8573 + default:
8574 + hash *= 9;
8575 + hash += *cast(uint *)str;
8576 + str += 4;
8577 + len -= 4;
8578 + break;
8579 + }
8580 + }
8581 +}
8582 + return hash;
8583 + }
8584 +
8585 + override TypeInfo next()
8586 + {
8587 + return typeid(char);
8588 + }
8589 +}
8590 Index: src/compiler/ldc/typeinfo/ti_Acreal.d
8591 ===================================================================
8592 --- src/compiler/ldc/typeinfo/ti_Acreal.d (revision 0)
8593 +++ src/compiler/ldc/typeinfo/ti_Acreal.d (revision 0)
8594 @@ -0,0 +1,106 @@
8595 +/*
8596 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
8597 + * Written by Walter Bright
8598 + *
8599 + * This software is provided 'as-is', without any express or implied
8600 + * warranty. In no event will the authors be held liable for any damages
8601 + * arising from the use of this software.
8602 + *
8603 + * Permission is granted to anyone to use this software for any purpose,
8604 + * including commercial applications, and to alter it and redistribute it
8605 + * freely, in both source and binary form, subject to the following
8606 + * restrictions:
8607 + *
8608 + * o The origin of this software must not be misrepresented; you must not
8609 + * claim that you wrote the original software. If you use this software
8610 + * in a product, an acknowledgment in the product documentation would be
8611 + * appreciated but is not required.
8612 + * o Altered source versions must be plainly marked as such, and must not
8613 + * be misrepresented as being the original software.
8614 + * o This notice may not be removed or altered from any source
8615 + * distribution.
8616 + */
8617 +
8618 +module rt.typeinfo.ti_Acreal;
8619 +
8620 +private import typeinfo.ti_creal;
8621 +
8622 +// creal[]
8623 +
8624 +class TypeInfo_Ac : TypeInfo
8625 +{
8626 + override string toString() { return "creal[]"; }
8627 +
8628 + override hash_t getHash(in void* p)
8629 + { creal[] s = *cast(creal[]*)p;
8630 + size_t len = s.length;
8631 + creal *str = s.ptr;
8632 + hash_t hash = 0;
8633 +
8634 + while (len)
8635 + {
8636 + hash *= 9;
8637 + hash += (cast(uint *)str)[0];
8638 + hash += (cast(uint *)str)[1];
8639 + hash += (cast(uint *)str)[2];
8640 + hash += (cast(uint *)str)[3];
8641 + hash += (cast(uint *)str)[4];
8642 + str++;
8643 + len--;
8644 + }
8645 +
8646 + return hash;
8647 + }
8648 +
8649 + override equals_t equals(in void* p1, in void* p2)
8650 + {
8651 + creal[] s1 = *cast(creal[]*)p1;
8652 + creal[] s2 = *cast(creal[]*)p2;
8653 + size_t len = s1.length;
8654 +
8655 + if (len != s2.length)
8656 + return 0;
8657 + for (size_t u = 0; u < len; u++)
8658 + {
8659 + if (!TypeInfo_c._equals(s1[u], s2[u]))
8660 + return false;
8661 + }
8662 + return true;
8663 + }
8664 +
8665 + override int compare(in void* p1, in void* p2)
8666 + {
8667 + creal[] s1 = *cast(creal[]*)p1;
8668 + creal[] s2 = *cast(creal[]*)p2;
8669 + size_t len = s1.length;
8670 +
8671 + if (s2.length < len)
8672 + len = s2.length;
8673 + for (size_t u = 0; u < len; u++)
8674 + {
8675 + int c = TypeInfo_c._compare(s1[u], s2[u]);
8676 + if (c)
8677 + return c;
8678 + }
8679 + if (s1.length < s2.length)
8680 + return -1;
8681 + else if (s1.length > s2.length)
8682 + return 1;
8683 + return 0;
8684 + }
8685 +
8686 + override size_t tsize()
8687 + {
8688 + return (creal[]).sizeof;
8689 + }
8690 +
8691 + override uint flags()
8692 + {
8693 + return 1;
8694 + }
8695 +
8696 + override TypeInfo next()
8697 + {
8698 + return typeid(creal);
8699 + }
8700 +}
8701 Index: src/compiler/ldc/typeinfo/ti_int.d
8702 ===================================================================
8703 --- src/compiler/ldc/typeinfo/ti_int.d (revision 0)
8704 +++ src/compiler/ldc/typeinfo/ti_int.d (revision 0)
8705 @@ -0,0 +1,42 @@
8706 +
8707 +// int
8708 +
8709 +module rt.typeinfo.ti_int;
8710 +
8711 +class TypeInfo_i : TypeInfo
8712 +{
8713 + override string toString() { return "int"; }
8714 +
8715 + override hash_t getHash(in void* p)
8716 + {
8717 + return *cast(uint *)p;
8718 + }
8719 +
8720 + override equals_t equals(in void* p1, in void* p2)
8721 + {
8722 + return *cast(uint *)p1 == *cast(uint *)p2;
8723 + }
8724 +
8725 + override int compare(in void* p1, in void* p2)
8726 + {
8727 + if (*cast(int*) p1 < *cast(int*) p2)
8728 + return -1;
8729 + else if (*cast(int*) p1 > *cast(int*) p2)
8730 + return 1;
8731 + return 0;
8732 + }
8733 +
8734 + override size_t tsize()
8735 + {
8736 + return int.sizeof;
8737 + }
8738 +
8739 + override void swap(void *p1, void *p2)
8740 + {
8741 + int t;
8742 +
8743 + t = *cast(int *)p1;
8744 + *cast(int *)p1 = *cast(int *)p2;
8745 + *cast(int *)p2 = t;
8746 + }
8747 +}
8748 Index: src/compiler/ldc/typeinfo/ti_Ashort.d
8749 ===================================================================
8750 --- src/compiler/ldc/typeinfo/ti_Ashort.d (revision 0)
8751 +++ src/compiler/ldc/typeinfo/ti_Ashort.d (revision 0)
8752 @@ -0,0 +1,132 @@
8753 +
8754 +module rt.typeinfo.ti_Ashort;
8755 +
8756 +private import core.stdc.string;
8757 +
8758 +// short[]
8759 +
8760 +class TypeInfo_As : TypeInfo
8761 +{
8762 + override string toString() { return "short[]"; }
8763 +
8764 + override hash_t getHash(in void* p)
8765 + { short[] s = *cast(short[]*)p;
8766 + size_t len = s.length;
8767 + short *str = s.ptr;
8768 + hash_t hash = 0;
8769 +
8770 + while (1)
8771 + {
8772 + switch (len)
8773 + {
8774 + case 0:
8775 + return hash;
8776 +
8777 + case 1:
8778 + hash *= 9;
8779 + hash += *cast(ushort *)str;
8780 + return hash;
8781 +
8782 + default:
8783 + hash *= 9;
8784 + hash += *cast(uint *)str;
8785 + str += 2;
8786 + len -= 2;
8787 + break;
8788 + }
8789 + }
8790 +
8791 + return hash;
8792 + }
8793 +
8794 + override equals_t equals(in void* p1, in void* p2)
8795 + {
8796 + short[] s1 = *cast(short[]*)p1;
8797 + short[] s2 = *cast(short[]*)p2;
8798 +
8799 + return s1.length == s2.length &&
8800 + memcmp(cast(void *)s1, cast(void *)s2, s1.length * short.sizeof) == 0;
8801 + }
8802 +
8803 + override int compare(in void* p1, in void* p2)
8804 + {
8805 + short[] s1 = *cast(short[]*)p1;
8806 + short[] s2 = *cast(short[]*)p2;
8807 + size_t len = s1.length;
8808 +
8809 + if (s2.length < len)
8810 + len = s2.length;
8811 + for (size_t u = 0; u < len; u++)
8812 + {
8813 + int result = s1[u] - s2[u];
8814 + if (result)
8815 + return result;
8816 + }
8817 + if (s1.length < s2.length)
8818 + return -1;
8819 + else if (s1.length > s2.length)
8820 + return 1;
8821 + return 0;
8822 + }
8823 +
8824 + override size_t tsize()
8825 + {
8826 + return (short[]).sizeof;
8827 + }
8828 +
8829 + override uint flags()
8830 + {
8831 + return 1;
8832 + }
8833 +
8834 + override TypeInfo next()
8835 + {
8836 + return typeid(short);
8837 + }
8838 +}
8839 +
8840 +
8841 +// ushort[]
8842 +
8843 +class TypeInfo_At : TypeInfo_As
8844 +{
8845 + override string toString() { return "ushort[]"; }
8846 +
8847 + override int compare(in void* p1, in void* p2)
8848 + {
8849 + ushort[] s1 = *cast(ushort[]*)p1;
8850 + ushort[] s2 = *cast(ushort[]*)p2;
8851 + size_t len = s1.length;
8852 +
8853 + if (s2.length < len)
8854 + len = s2.length;
8855 + for (size_t u = 0; u < len; u++)
8856 + {
8857 + int result = s1[u] - s2[u];
8858 + if (result)
8859 + return result;
8860 + }
8861 + if (s1.length < s2.length)
8862 + return -1;
8863 + else if (s1.length > s2.length)
8864 + return 1;
8865 + return 0;
8866 + }
8867 +
8868 + override TypeInfo next()
8869 + {
8870 + return typeid(ushort);
8871 + }
8872 +}
8873 +
8874 +// wchar[]
8875 +
8876 +class TypeInfo_Au : TypeInfo_At
8877 +{
8878 + override string toString() { return "wchar[]"; }
8879 +
8880 + override TypeInfo next()
8881 + {
8882 + return typeid(wchar);
8883 + }
8884 +}
8885 Index: src/compiler/ldc/ldc/vararg.d
8886 ===================================================================
8887 --- src/compiler/ldc/ldc/vararg.d (revision 0)
8888 +++ src/compiler/ldc/ldc/vararg.d (revision 0)
8889 @@ -0,0 +1,43 @@
8890 +/*
8891 + * This module holds the implementation of special vararg templates for D style var args.
8892 + *
8893 + * Provides the functions tango.core.Vararg expects to be present!
8894 + */
8895 +
8896 +module ldc.Vararg;
8897 +
8898 +// Check for the right compiler
8899 +version(LDC)
8900 +{
8901 + // OK
8902 +}
8903 +else
8904 +{
8905 + static assert(false, "This module is only valid for LDC");
8906 +}
8907 +
8908 +alias void* va_list;
8909 +
8910 +void va_start(T) ( out va_list ap, inout T parmn )
8911 +{
8912 + // not needed !
8913 +}
8914 +
8915 +T va_arg(T)(ref va_list vp)
8916 +{
8917 + T* arg = cast(T*) vp;
8918 + // ldc always aligns to size_t.sizeof in vararg lists
8919 + vp = cast(va_list) ( cast(void*) vp + ( ( T.sizeof + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) ) );
8920 + return *arg;
8921 +}
8922 +
8923 +void va_end( va_list ap )
8924 +{
8925 + // not needed !
8926 +}
8927 +
8928 +void va_copy( out va_list dst, va_list src )
8929 +{
8930 + // seems pretty useless !
8931 + dst = src;
8932 +}
8933 Index: src/compiler/ldc/ldc/bitmanip.d
8934 ===================================================================
8935 --- src/compiler/ldc/ldc/bitmanip.d (revision 0)
8936 +++ src/compiler/ldc/ldc/bitmanip.d (revision 0)
8937 @@ -0,0 +1,81 @@
8938 +/*
8939 + * D phobos intrinsics for LDC
8940 + *
8941 + * From GDC ... public domain!
8942 + */
8943 +module ldc.bitmanip;
8944 +
8945 +// Check for the right compiler
8946 +version(LDC)
8947 +{
8948 + // OK
8949 +}
8950 +else
8951 +{
8952 + static assert(false, "This module is only valid for LDC");
8953 +}
8954 +
8955 +int bsf(uint v)
8956 +{
8957 + uint m = 1;
8958 + uint i;
8959 + for (i = 0; i < 32; i++,m<<=1) {
8960 + if (v&m)
8961 + return i;
8962 + }
8963 + return i; // supposed to be undefined
8964 +}
8965 +
8966 +int bsr(uint v)
8967 +{
8968 + uint m = 0x80000000;
8969 + uint i;
8970 + for (i = 32; i ; i--,m>>>=1) {
8971 + if (v&m)
8972 + return i-1;
8973 + }
8974 + return i; // supposed to be undefined
8975 +}
8976 +
8977 +int bt(uint *p, uint bitnum)
8978 +{
8979 + return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
8980 +}
8981 +
8982 +int btc(uint *p, uint bitnum)
8983 +{
8984 + uint * q = p + (bitnum / (uint.sizeof*8));
8985 + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
8986 + int result = *q & mask;
8987 + *q ^= mask;
8988 + return result ? -1 : 0;
8989 +}
8990 +
8991 +int btr(uint *p, uint bitnum)
8992 +{
8993 + uint * q = p + (bitnum / (uint.sizeof*8));
8994 + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
8995 + int result = *q & mask;
8996 + *q &= ~mask;
8997 + return result ? -1 : 0;
8998 +}
8999 +
9000 +int bts(uint *p, uint bitnum)
9001 +{
9002 + uint * q = p + (bitnum / (uint.sizeof*8));
9003 + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
9004 + int result = *q & mask;
9005 + *q |= mask;
9006 + return result ? -1 : 0;
9007 +}
9008 +
9009 +pragma(intrinsic, "llvm.bswap.i32")
9010 + uint bswap(uint val);
9011 +
9012 +ubyte inp(uint p) { throw new Exception("inp intrinsic not yet implemented"); }
9013 +ushort inpw(uint p) { throw new Exception("inpw intrinsic not yet implemented"); }
9014 +uint inpl(uint p) { throw new Exception("inpl intrinsic not yet implemented"); }
9015 +
9016 +ubyte outp(uint p, ubyte v) { throw new Exception("outp intrinsic not yet implemented"); }
9017 +ushort outpw(uint p, ushort v) { throw new Exception("outpw intrinsic not yet implemented"); }
9018 +uint outpl(uint p, uint v) { throw new Exception("outpl intrinsic not yet implemented"); }
9019 Index: src/compiler/ldc/aaA.d
9020 ===================================================================
9021 --- src/compiler/ldc/aaA.d (revision 0)
9022 +++ src/compiler/ldc/aaA.d (revision 0)
9023 @@ -0,0 +1,837 @@
9024 +//_ aaA.d
9025 +
9026 +/**
9027 + * Part of the D programming language runtime library.
9028 + * Implementation of associative arrays.
9029 + */
9030 +
9031 +/*
9032 + * Copyright (C) 2000-2008 by Digital Mars, www.digitalmars.com
9033 + * Written by Walter Bright
9034 + *
9035 + * This software is provided 'as-is', without any express or implied
9036 + * warranty. In no event will the authors be held liable for any damages
9037 + * arising from the use of this software.
9038 + *
9039 + * Permission is granted to anyone to use this software for any purpose,
9040 + * including commercial applications, and to alter it and redistribute it
9041 + * freely, subject to the following restrictions:
9042 + *
9043 + * o The origin of this software must not be misrepresented; you must not
9044 + * claim that you wrote the original software. If you use this software
9045 + * in a product, an acknowledgment in the product documentation would be
9046 + * appreciated but is not required.
9047 + * o Altered source versions must be plainly marked as such, and must not
9048 + * be misrepresented as being the original software.
9049 + * o This notice may not be removed or altered from any source
9050 + * distribution.
9051 + */
9052 +
9053 +/*
9054 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
9055 + * Modified by Tomas Lindquist Olsen <tomas@famolsen.dk> for use with LDC.
9056 + */
9057 +
9058 +private
9059 +{
9060 + version( D_Version2 )
9061 + {
9062 + import core.stdc.stdarg;
9063 + import core.stdc.string;
9064 + }
9065 + else
9066 + {
9067 + import tango.stdc.stdarg;
9068 + import tango.stdc.string;
9069 + }
9070 +
9071 + enum BlkAttr : uint
9072 + {
9073 + FINALIZE = 0b0000_0001,
9074 + NO_SCAN = 0b0000_0010,
9075 + NO_MOVE = 0b0000_0100,
9076 + ALL_BITS = 0b1111_1111
9077 + }
9078 +
9079 + extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
9080 + extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
9081 + extern (C) void gc_free( void* p );
9082 +}
9083 +
9084 +// Auto-rehash and pre-allocate - Dave Fladebo
9085 +
9086 +static size_t[] prime_list = [
9087 + 97UL, 389UL,
9088 + 1_543UL, 6_151UL,
9089 + 24_593UL, 98_317UL,
9090 + 393_241UL, 1_572_869UL,
9091 + 6_291_469UL, 25_165_843UL,
9092 + 100_663_319UL, 402_653_189UL,
9093 + 1_610_612_741UL, 4_294_967_291UL,
9094 +// 8_589_934_513UL, 17_179_869_143UL
9095 +];
9096 +
9097 +struct aaA
9098 +{
9099 + aaA *left;
9100 + aaA *right;
9101 + hash_t hash;
9102 + /* key */
9103 + /* value */
9104 +}
9105 +
9106 +struct BB
9107 +{
9108 + aaA*[] b;
9109 + size_t nodes; // total number of aaA nodes
9110 + TypeInfo keyti; // TODO: replace this with TypeInfo_AssociativeArray when available in _aaGet()
9111 +}
9112 +
9113 +/* This is the type actually seen by the programmer, although
9114 + * it is completely opaque.
9115 + */
9116 +
9117 +// LDC doesn't pass structs in registers so no need to wrap it ...
9118 +alias BB* AA;
9119 +
9120 +/**********************************
9121 + * Align to next pointer boundary, so that
9122 + * GC won't be faced with misaligned pointers
9123 + * in value.
9124 + */
9125 +
9126 +size_t aligntsize(size_t tsize)
9127 +{
9128 + return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
9129 +}
9130 +
9131 +extern (C):
9132 +
9133 +/*************************************************
9134 + * Invariant for aa.
9135 + */
9136 +
9137 +/+
9138 +void _aaInvAh(aaA*[] aa)
9139 +{
9140 + for (size_t i = 0; i < aa.length; i++)
9141 + {
9142 + if (aa[i])
9143 + _aaInvAh_x(aa[i]);
9144 + }
9145 +}
9146 +
9147 +private int _aaCmpAh_x(aaA *e1, aaA *e2)
9148 +{ int c;
9149 +
9150 + c = e1.hash - e2.hash;
9151 + if (c == 0)
9152 + {
9153 + c = e1.key.length - e2.key.length;
9154 + if (c == 0)
9155 + c = memcmp((char *)e1.key, (char *)e2.key, e1.key.length);
9156 + }
9157 + return c;
9158 +}
9159 +
9160 +private void _aaInvAh_x(aaA *e)
9161 +{
9162 + hash_t key_hash;
9163 + aaA *e1;
9164 + aaA *e2;
9165 +
9166 + key_hash = getHash(e.key);
9167 + assert(key_hash == e.hash);
9168 +
9169 + while (1)
9170 + { int c;
9171 +
9172 + e1 = e.left;
9173 + if (e1)
9174 + {
9175 + _aaInvAh_x(e1); // ordinary recursion
9176 + do
9177 + {
9178 + c = _aaCmpAh_x(e1, e);
9179 + assert(c < 0);
9180 + e1 = e1.right;
9181 + } while (e1 != null);
9182 + }
9183 +
9184 + e2 = e.right;
9185 + if (e2)
9186 + {
9187 + do
9188 + {
9189 + c = _aaCmpAh_x(e, e2);
9190 + assert(c < 0);
9191 + e2 = e2.left;
9192 + } while (e2 != null);
9193 + e = e.right; // tail recursion
9194 + }
9195 + else
9196 + break;
9197 + }
9198 +}
9199 ++/
9200 +
9201 +/****************************************************
9202 + * Determine number of entries in associative array.
9203 + */
9204 +
9205 +size_t _aaLen(AA aa)
9206 +in
9207 +{
9208 + //printf("_aaLen()+\n");
9209 + //_aaInv(aa);
9210 +}
9211 +out (result)
9212 +{
9213 + size_t len = 0;
9214 +
9215 + void _aaLen_x(aaA* ex)
9216 + {
9217 + auto e = ex;
9218 + len++;
9219 +
9220 + while (1)
9221 + {
9222 + if (e.right)
9223 + _aaLen_x(e.right);
9224 + e = e.left;
9225 + if (!e)
9226 + break;
9227 + len++;
9228 + }
9229 + }
9230 +
9231 + if (aa)
9232 + {
9233 + foreach (e; aa.b)
9234 + {
9235 + if (e)
9236 + _aaLen_x(e);
9237 + }
9238 + }
9239 + assert(len == result);
9240 +
9241 + //printf("_aaLen()-\n");
9242 +}
9243 +body
9244 +{
9245 + return aa ? aa.nodes : 0;
9246 +}
9247 +
9248 +
9249 +/*************************************************
9250 + * Get pointer to value in associative array indexed by key.
9251 + * Add entry for key if it is not already there.
9252 + */
9253 +
9254 +void* _aaGet(AA* aa_arg, TypeInfo keyti, size_t valuesize, void* pkey)
9255 +in
9256 +{
9257 + assert(aa_arg);
9258 +}
9259 +out (result)
9260 +{
9261 + assert(result);
9262 + assert(*aa_arg);
9263 + assert((*aa_arg).b.length);
9264 + //assert(_aaInAh(*aa, key));
9265 +}
9266 +body
9267 +{
9268 + //auto pkey = cast(void *)(&valuesize + 1);
9269 + size_t i;
9270 + aaA *e;
9271 + auto keysize = aligntsize(keyti.tsize());
9272 +
9273 + if (!*aa_arg)
9274 + *aa_arg = new BB();
9275 + auto aa = *aa_arg;
9276 + aa.keyti = keyti;
9277 +
9278 + if (!aa.b.length)
9279 + {
9280 + alias aaA *pa;
9281 + auto len = prime_list[0];
9282 +
9283 + aa.b = new pa[len];
9284 + }
9285 +
9286 + auto key_hash = keyti.getHash(pkey);
9287 + //printf("hash = %d\n", key_hash);
9288 + i = key_hash % aa.b.length;
9289 + auto pe = &aa.b[i];
9290 + while ((e = *pe) !is null)
9291 + {
9292 + if (key_hash == e.hash)
9293 + {
9294 + auto c = keyti.compare(pkey, e + 1);
9295 + if (c == 0)
9296 + goto Lret;
9297 + pe = (c < 0) ? &e.left : &e.right;
9298 + }
9299 + else
9300 + pe = (key_hash < e.hash) ? &e.left : &e.right;
9301 + }
9302 +
9303 + // Not found, create new elem
9304 + //printf("create new one\n");
9305 + size_t size = aaA.sizeof + keysize + valuesize;
9306 + e = cast(aaA *) gc_calloc(size);
9307 + memcpy(e + 1, pkey, keysize);
9308 + e.hash = key_hash;
9309 + *pe = e;
9310 +
9311 + auto nodes = ++aa.nodes;
9312 + //printf("length = %d, nodes = %d\n", (*aa).length, nodes);
9313 + if (nodes > aa.b.length * 4)
9314 + {
9315 + _aaRehash(aa_arg,keyti);
9316 + }
9317 +
9318 +Lret:
9319 + return cast(void *)(e + 1) + keysize;
9320 +}
9321 +
9322 +
9323 +/*************************************************
9324 + * Get pointer to value in associative array indexed by key.
9325 + * Returns null if it is not already there.
9326 + */
9327 +
9328 +void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void *pkey)
9329 +{
9330 + //printf("_aaGetRvalue(valuesize = %u)\n", valuesize);
9331 + if (!aa)
9332 + return null;
9333 +
9334 + //auto pkey = cast(void *)(&valuesize + 1);
9335 + auto keysize = aligntsize(keyti.tsize());
9336 + auto len = aa.b.length;
9337 +
9338 + if (len)
9339 + {
9340 + auto key_hash = keyti.getHash(pkey);
9341 + //printf("hash = %d\n", key_hash);
9342 + size_t i = key_hash % len;
9343 + auto e = aa.b[i];
9344 + while (e !is null)
9345 + {
9346 + if (key_hash == e.hash)
9347 + {
9348 + auto c = keyti.compare(pkey, e + 1);
9349 + if (c == 0)
9350 + return cast(void *)(e + 1) + keysize;
9351 + e = (c < 0) ? e.left : e.right;
9352 + }
9353 + else
9354 + e = (key_hash < e.hash) ? e.left : e.right;
9355 + }
9356 + }
9357 + return null; // not found, caller will throw exception
9358 +}
9359 +
9360 +
9361 +/*************************************************
9362 + * Determine if key is in aa.
9363 + * Returns:
9364 + * null not in aa
9365 + * !=null in aa, return pointer to value
9366 + */
9367 +
9368 +void* _aaIn(AA aa, TypeInfo keyti, void *pkey)
9369 +in
9370 +{
9371 +}
9372 +out (result)
9373 +{
9374 + //assert(result == 0 || result == 1);
9375 +}
9376 +body
9377 +{
9378 + if (aa)
9379 + {
9380 + //auto pkey = cast(void *)(&keyti + 1);
9381 +
9382 + //printf("_aaIn(), .length = %d, .ptr = %x\n", aa.length, cast(uint)aa.ptr);
9383 + auto len = aa.b.length;
9384 +
9385 + if (len)
9386 + {
9387 + auto key_hash = keyti.getHash(pkey);
9388 + //printf("hash = %d\n", key_hash);
9389 + size_t i = key_hash % len;
9390 + auto e = aa.b[i];
9391 + while (e !is null)
9392 + {
9393 + if (key_hash == e.hash)
9394 + {
9395 + auto c = keyti.compare(pkey, e + 1);
9396 + if (c == 0)
9397 + return cast(void *)(e + 1) + aligntsize(keyti.tsize());
9398 + e = (c < 0) ? e.left : e.right;
9399 + }
9400 + else
9401 + e = (key_hash < e.hash) ? e.left : e.right;
9402 + }
9403 + }
9404 + }
9405 +
9406 + // Not found
9407 + return null;
9408 +}
9409 +
9410 +/*************************************************
9411 + * Delete key entry in aa[].
9412 + * If key is not in aa[], do nothing.
9413 + */
9414 +
9415 +void _aaDel(AA aa, TypeInfo keyti, void *pkey)
9416 +{
9417 + //auto pkey = cast(void *)(&keyti + 1);
9418 + aaA *e;
9419 +
9420 + if (aa && aa.b.length)
9421 + {
9422 + auto key_hash = keyti.getHash(pkey);
9423 + //printf("hash = %d\n", key_hash);
9424 + size_t i = key_hash % aa.b.length;
9425 + auto pe = &aa.b[i];
9426 + while ((e = *pe) !is null) // null means not found
9427 + {
9428 + if (key_hash == e.hash)
9429 + {
9430 + auto c = keyti.compare(pkey, e + 1);
9431 + if (c == 0)
9432 + {
9433 + if (!e.left && !e.right)
9434 + {
9435 + *pe = null;
9436 + }
9437 + else if (e.left && !e.right)
9438 + {
9439 + *pe = e.left;
9440 + e.left = null;
9441 + }
9442 + else if (!e.left && e.right)
9443 + {
9444 + *pe = e.right;
9445 + e.right = null;
9446 + }
9447 + else
9448 + {
9449 + *pe = e.left;
9450 + e.left = null;
9451 + do
9452 + pe = &(*pe).right;
9453 + while (*pe);
9454 + *pe = e.right;
9455 + e.right = null;
9456 + }
9457 +
9458 + aa.nodes--;
9459 + gc_free(e);
9460 +
9461 + break;
9462 + }
9463 + pe = (c < 0) ? &e.left : &e.right;
9464 + }
9465 + else
9466 + pe = (key_hash < e.hash) ? &e.left : &e.right;
9467 + }
9468 + }
9469 +}
9470 +
9471 +
9472 +/********************************************
9473 + * Produce array of values from aa.
9474 + * The actual type is painted on the return value by the frontend
9475 + * This means the returned length should be the number of elements
9476 + */
9477 +
9478 +void[] _aaValues(AA aa, size_t keysize, size_t valuesize)
9479 +in
9480 +{
9481 + assert(keysize == aligntsize(keysize));
9482 +}
9483 +body
9484 +{
9485 + size_t resi;
9486 + void[] a;
9487 +
9488 + void _aaValues_x(aaA* e)
9489 + {
9490 + do
9491 + {
9492 + memcpy(a.ptr + resi * valuesize,
9493 + cast(byte*)e + aaA.sizeof + keysize,
9494 + valuesize);
9495 + resi++;
9496 + if (e.left)
9497 + { if (!e.right)
9498 + { e = e.left;
9499 + continue;
9500 + }
9501 + _aaValues_x(e.left);
9502 + }
9503 + e = e.right;
9504 + } while (e !is null);
9505 + }
9506 +
9507 + if (aa)
9508 + {
9509 + auto len = _aaLen(aa);
9510 + auto ptr = cast(byte*) gc_malloc(len * valuesize,
9511 + valuesize < (void*).sizeof ? BlkAttr.NO_SCAN : 0);
9512 + a = ptr[0 .. len];
9513 + resi = 0;
9514 + foreach (e; aa.b)
9515 + {
9516 + if (e)
9517 + _aaValues_x(e);
9518 + }
9519 + assert(resi == a.length);
9520 + }
9521 + return a;
9522 +}
9523 +
9524 +
9525 +/********************************************
9526 + * Rehash an array.
9527 + */
9528 +
9529 +void* _aaRehash(AA* paa, TypeInfo keyti)
9530 +in
9531 +{
9532 + //_aaInvAh(paa);
9533 +}
9534 +out (result)
9535 +{
9536 + //_aaInvAh(result);
9537 +}
9538 +body
9539 +{
9540 + BB newb;
9541 +
9542 + void _aaRehash_x(aaA* olde)
9543 + {
9544 + while (1)
9545 + {
9546 + auto left = olde.left;
9547 + auto right = olde.right;
9548 + olde.left = null;
9549 + olde.right = null;
9550 +
9551 + aaA *e;
9552 +
9553 + //printf("rehash %p\n", olde);
9554 + auto key_hash = olde.hash;
9555 + size_t i = key_hash % newb.b.length;
9556 + auto pe = &newb.b[i];
9557 + while ((e = *pe) !is null)
9558 + {
9559 + //printf("\te = %p, e.left = %p, e.right = %p\n", e, e.left, e.right);
9560 + assert(e.left != e);
9561 + assert(e.right != e);
9562 + if (key_hash == e.hash)
9563 + {
9564 + auto c = keyti.compare(olde + 1, e + 1);
9565 + assert(c != 0);
9566 + pe = (c < 0) ? &e.left : &e.right;
9567 + }
9568 + else
9569 + pe = (key_hash < e.hash) ? &e.left : &e.right;
9570 + }
9571 + *pe = olde;
9572 +
9573 + if (right)
9574 + {
9575 + if (!left)
9576 + { olde = right;
9577 + continue;
9578 + }
9579 + _aaRehash_x(right);
9580 + }
9581 + if (!left)
9582 + break;
9583 + olde = left;
9584 + }
9585 + }
9586 +
9587 + //printf("Rehash\n");
9588 + if (*paa)
9589 + {
9590 + auto aa = *paa;
9591 + auto len = _aaLen(aa);
9592 + if (len)
9593 + { size_t i;
9594 +
9595 + for (i = 0; i < prime_list.length - 1; i++)
9596 + {
9597 + if (len <= prime_list[i])
9598 + break;
9599 + }
9600 + len = prime_list[i];
9601 + newb.b = new aaA*[len];
9602 + newb.keyti = keyti;
9603 +
9604 + foreach (e; aa.b)
9605 + {
9606 + if (e)
9607 + _aaRehash_x(e);
9608 + }
9609 +
9610 + newb.nodes = (*aa).nodes;
9611 + }
9612 +
9613 + **paa = newb;
9614 + }
9615 + return *paa;
9616 +}
9617 +
9618 +
9619 +/********************************************
9620 + * Produce array of N byte keys from aa.
9621 + * The actual type is painted on the return value by the frontend
9622 + * This means the returned length should be the number of elements
9623 + */
9624 +
9625 +void[] _aaKeys(AA aa, size_t keysize)
9626 +{
9627 + byte[] res;
9628 + size_t resi;
9629 +
9630 + void _aaKeys_x(aaA* e)
9631 + {
9632 + do
9633 + {
9634 + memcpy(&res[resi * keysize], cast(byte*)(e + 1), keysize);
9635 + resi++;
9636 + if (e.left)
9637 + { if (!e.right)
9638 + { e = e.left;
9639 + continue;
9640 + }
9641 + _aaKeys_x(e.left);
9642 + }
9643 + e = e.right;
9644 + } while (e !is null);
9645 + }
9646 +
9647 + auto len = _aaLen(aa);
9648 + if (!len)
9649 + return null;
9650 + res = (cast(byte*) gc_malloc(len * keysize,
9651 + !(aa.keyti.flags() & 1) ? BlkAttr.NO_SCAN : 0)) [0 .. len * keysize];
9652 + resi = 0;
9653 + foreach (e; aa.b)
9654 + {
9655 + if (e)
9656 + _aaKeys_x(e);
9657 + }
9658 + assert(resi == len);
9659 +
9660 + return res.ptr[0 .. len];
9661 +}
9662 +
9663 +
9664 +/**********************************************
9665 + * 'apply' for associative arrays - to support foreach
9666 + */
9667 +
9668 +// dg is D, but _aaApply() is C
9669 +extern (D) typedef int delegate(void *) dg_t;
9670 +
9671 +int _aaApply(AA aa, size_t keysize, dg_t dg)
9672 +in
9673 +{
9674 + assert(aligntsize(keysize) == keysize);
9675 +}
9676 +body
9677 +{ int result;
9678 +
9679 + //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
9680 +
9681 + int treewalker(aaA* e)
9682 + { int result;
9683 +
9684 + do
9685 + {
9686 + //printf("treewalker(e = %p, dg = x%llx)\n", e, dg);
9687 + result = dg(cast(void *)(e + 1) + keysize);
9688 + if (result)
9689 + break;
9690 + if (e.right)
9691 + { if (!e.left)
9692 + {
9693 + e = e.right;
9694 + continue;
9695 + }
9696 + result = treewalker(e.right);
9697 + if (result)
9698 + break;
9699 + }
9700 + e = e.left;
9701 + } while (e);
9702 +
9703 + return result;
9704 + }
9705 +
9706 + if (aa)
9707 + {
9708 + foreach (e; aa.b)
9709 + {
9710 + if (e)
9711 + {
9712 + result = treewalker(e);
9713 + if (result)
9714 + break;
9715 + }
9716 + }
9717 + }
9718 + return result;
9719 +}
9720 +
9721 +// dg is D, but _aaApply2() is C
9722 +extern (D) typedef int delegate(void *, void *) dg2_t;
9723 +
9724 +int _aaApply2(AA aa, size_t keysize, dg2_t dg)
9725 +in
9726 +{
9727 + assert(aligntsize(keysize) == keysize);
9728 +}
9729 +body
9730 +{ int result;
9731 +
9732 + //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
9733 +
9734 + int treewalker(aaA* e)
9735 + { int result;
9736 +
9737 + do
9738 + {
9739 + //printf("treewalker(e = %p, dg = x%llx)\n", e, dg);
9740 + result = dg(cast(void *)(e + 1), cast(void *)(e + 1) + keysize);
9741 + if (result)
9742 + break;
9743 + if (e.right)
9744 + { if (!e.left)
9745 + {
9746 + e = e.right;
9747 + continue;
9748 + }
9749 + result = treewalker(e.right);
9750 + if (result)
9751 + break;
9752 + }
9753 + e = e.left;
9754 + } while (e);
9755 +
9756 + return result;
9757 + }
9758 +
9759 + if (aa)
9760 + {
9761 + foreach (e; aa.b)
9762 + {
9763 + if (e)
9764 + {
9765 + result = treewalker(e);
9766 + if (result)
9767 + break;
9768 + }
9769 + }
9770 + }
9771 + return result;
9772 +}
9773 +
9774 +
9775 +/***********************************
9776 + * Construct an associative array of type ti from
9777 + * length pairs of key/value pairs.
9778 + */
9779 +
9780 +/+
9781 +
9782 +extern (C)
9783 +BB* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
9784 +{
9785 + auto valuesize = ti.next.tsize(); // value size
9786 + auto keyti = ti.key;
9787 + auto keysize = keyti.tsize(); // key size
9788 + BB* result;
9789 +
9790 + //printf("_d_assocarrayliteralT(keysize = %d, valuesize = %d, length = %d)\n", keysize, valuesize, length);
9791 + //printf("tivalue = %.*s\n", ti.next.classinfo.name);
9792 + if (length == 0 || valuesize == 0 || keysize == 0)
9793 + {
9794 + ;
9795 + }
9796 + else
9797 + {
9798 + va_list q;
9799 + va_start!(size_t)(q, length);
9800 +
9801 + result = new BB();
9802 + size_t i;
9803 +
9804 + for (i = 0; i < prime_list.length - 1; i++)
9805 + {
9806 + if (length <= prime_list[i])
9807 + break;
9808 + }
9809 + auto len = prime_list[i];
9810 + result.b = new aaA*[len];
9811 +
9812 + size_t keystacksize = (keysize + int.sizeof - 1) & ~(int.sizeof - 1);
9813 + size_t valuestacksize = (valuesize + int.sizeof - 1) & ~(int.sizeof - 1);
9814 +
9815 + size_t keytsize = aligntsize(keysize);
9816 +
9817 + for (size_t j = 0; j < length; j++)
9818 + { void* pkey = q;
9819 + q += keystacksize;
9820 + void* pvalue = q;
9821 + q += valuestacksize;
9822 + aaA* e;
9823 +
9824 + auto key_hash = keyti.getHash(pkey);
9825 + //printf("hash = %d\n", key_hash);
9826 + i = key_hash % len;
9827 + auto pe = &result.b[i];
9828 + while (1)
9829 + {
9830 + e = *pe;
9831 + if (!e)
9832 + {
9833 + // Not found, create new elem
9834 + //printf("create new one\n");
9835 + e = cast(aaA *) cast(void*) new void[aaA.sizeof + keytsize + valuesize];
9836 + memcpy(e + 1, pkey, keysize);
9837 + e.hash = key_hash;
9838 + *pe = e;
9839 + result.nodes++;
9840 + break;
9841 + }
9842 + if (key_hash == e.hash)
9843 + {
9844 + auto c = keyti.compare(pkey, e + 1);
9845 + if (c == 0)
9846 + break;
9847 + pe = (c < 0) ? &e.left : &e.right;
9848 + }
9849 + else
9850 + pe = (key_hash < e.hash) ? &e.left : &e.right;
9851 + }
9852 + memcpy(cast(void *)(e + 1) + keytsize, pvalue, valuesize);
9853 + }
9854 +
9855 + va_end(q);
9856 + }
9857 + return result;
9858 +}
9859 +
9860 ++/
9861 Index: src/compiler/ldc/aApply.d
9862 ===================================================================
9863 --- src/compiler/ldc/aApply.d (revision 0)
9864 +++ src/compiler/ldc/aApply.d (revision 0)
9865 @@ -0,0 +1,414 @@
9866 +/**
9867 + * Part of the D programming language runtime library.
9868 + */
9869 +
9870 +/*
9871 + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
9872 + * Written by Walter Bright
9873 + *
9874 + * This software is provided 'as-is', without any express or implied
9875 + * warranty. In no event will the authors be held liable for any damages
9876 + * arising from the use of this software.
9877 + *
9878 + * Permission is granted to anyone to use this software for any purpose,
9879 + * including commercial applications, and to alter it and redistribute it
9880 + * freely, in both source and binary form, subject to the following
9881 + * restrictions:
9882 + *
9883 + * o The origin of this software must not be misrepresented; you must not
9884 + * claim that you wrote the original software. If you use this software
9885 + * in a product, an acknowledgment in the product documentation would be
9886 + * appreciated but is not required.
9887 + * o Altered source versions must be plainly marked as such, and must not
9888 + * be misrepresented as being the original software.
9889 + * o This notice may not be removed or altered from any source
9890 + * distribution.
9891 + */
9892 +
9893 +/*
9894 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
9895 + */
9896 +
9897 +/* This code handles decoding UTF strings for foreach loops.
9898 + * There are 6 combinations of conversions between char, wchar,
9899 + * and dchar, and 2 of each of those.
9900 + */
9901 +
9902 +private import util.utf;
9903 +
9904 +//debug = apply;
9905 +debug(apply)
9906 +{
9907 + extern(C) int printf(char*, ...);
9908 +}
9909 +
9910 +/**********************************************
9911 + */
9912 +
9913 +// dg is D, but _aApplycd() is C
9914 +extern (D) typedef int delegate(void *) dg_t;
9915 +
9916 +extern (C) int _aApplycd1(char[] aa, dg_t dg)
9917 +{ int result;
9918 + size_t i;
9919 + size_t len = aa.length;
9920 +
9921 + debug(apply) printf("_aApplycd1(), len = %d\n", len);
9922 + for (i = 0; i < len; )
9923 + { dchar d;
9924 +
9925 + d = aa[i];
9926 + if (d & 0x80)
9927 + d = decode(aa, i);
9928 + else
9929 + i++;
9930 + result = dg(cast(void *)&d);
9931 + if (result)
9932 + break;
9933 + }
9934 + return result;
9935 +}
9936 +
9937 +extern (C) int _aApplywd1(wchar[] aa, dg_t dg)
9938 +{ int result;
9939 + size_t i;
9940 + size_t len = aa.length;
9941 +
9942 + debug(apply) printf("_aApplywd1(), len = %d\n", len);
9943 + for (i = 0; i < len; )
9944 + { dchar d;
9945 +
9946 + d = aa[i];
9947 + if (d & ~0x7F)
9948 + d = decode(aa, i);
9949 + else
9950 + i++;
9951 + result = dg(cast(void *)&d);
9952 + if (result)
9953 + break;
9954 + }
9955 + return result;
9956 +}
9957 +
9958 +extern (C) int _aApplycw1(char[] aa, dg_t dg)
9959 +{ int result;
9960 + size_t i;
9961 + size_t len = aa.length;
9962 +
9963 + debug(apply) printf("_aApplycw1(), len = %d\n", len);
9964 + for (i = 0; i < len; )
9965 + { dchar d;
9966 + wchar w;
9967 +
9968 + w = aa[i];
9969 + if (w & 0x80)
9970 + { d = decode(aa, i);
9971 + if (d <= 0xFFFF)
9972 + w = cast(wchar) d;
9973 + else
9974 + {
9975 + w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
9976 + result = dg(cast(void *)&w);
9977 + if (result)
9978 + break;
9979 + w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
9980 + }
9981 + }
9982 + else
9983 + i++;
9984 + result = dg(cast(void *)&w);
9985 + if (result)
9986 + break;
9987 + }
9988 + return result;
9989 +}
9990 +
9991 +extern (C) int _aApplywc1(wchar[] aa, dg_t dg)
9992 +{ int result;
9993 + size_t i;
9994 + size_t len = aa.length;
9995 +
9996 + debug(apply) printf("_aApplywc1(), len = %d\n", len);
9997 + for (i = 0; i < len; )
9998 + { dchar d;
9999 + wchar w;
10000 + char c;
10001 +
10002 + w = aa[i];
10003 + if (w & ~0x7F)
10004 + {
10005 + char[4] buf;
10006 +
10007 + d = decode(aa, i);
10008 + auto b = toUTF8(buf, d);
10009 + foreach (char c2; b)
10010 + {
10011 + result = dg(cast(void *)&c2);
10012 + if (result)
10013 + return result;
10014 + }
10015 + continue;
10016 + }
10017 + else
10018 + { c = cast(char)w;
10019 + i++;
10020 + }
10021 + result = dg(cast(void *)&c);
10022 + if (result)
10023 + break;
10024 + }
10025 + return result;
10026 +}
10027 +
10028 +extern (C) int _aApplydc1(dchar[] aa, dg_t dg)
10029 +{ int result;
10030 +
10031 + debug(apply) printf("_aApplydc1(), len = %d\n", aa.length);
10032 + foreach (dchar d; aa)
10033 + {
10034 + char c;
10035 +
10036 + if (d & ~0x7F)
10037 + {
10038 + char[4] buf;
10039 +
10040 + auto b = toUTF8(buf, d);
10041 + foreach (char c2; b)
10042 + {
10043 + result = dg(cast(void *)&c2);
10044 + if (result)
10045 + return result;
10046 + }
10047 + continue;
10048 + }
10049 + else
10050 + {
10051 + c = cast(char)d;
10052 + }
10053 + result = dg(cast(void *)&c);
10054 + if (result)
10055 + break;
10056 + }
10057 + return result;
10058 +}
10059 +
10060 +extern (C) int _aApplydw1(dchar[] aa, dg_t dg)
10061 +{ int result;
10062 +
10063 + debug(apply) printf("_aApplydw1(), len = %d\n", aa.length);
10064 + foreach (dchar d; aa)
10065 + {
10066 + wchar w;
10067 +
10068 + if (d <= 0xFFFF)
10069 + w = cast(wchar) d;
10070 + else
10071 + {
10072 + w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
10073 + result = dg(cast(void *)&w);
10074 + if (result)
10075 + break;
10076 + w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
10077 + }
10078 + result = dg(cast(void *)&w);
10079 + if (result)
10080 + break;
10081 + }
10082 + return result;
10083 +}
10084 +
10085 +
10086 +/****************************************************************************/
10087 +
10088 +// dg is D, but _aApplycd2() is C
10089 +extern (D) typedef int delegate(void *, void *) dg2_t;
10090 +
10091 +extern (C) int _aApplycd2(char[] aa, dg2_t dg)
10092 +{ int result;
10093 + size_t i;
10094 + size_t n;
10095 + size_t len = aa.length;
10096 +
10097 + debug(apply) printf("_aApplycd2(), len = %d\n", len);
10098 + for (i = 0; i < len; i += n)
10099 + { dchar d;
10100 +
10101 + d = aa[i];
10102 + if (d & 0x80)
10103 + {
10104 + n = i;
10105 + d = decode(aa, n);
10106 + n -= i;
10107 + }
10108 + else
10109 + n = 1;
10110 + result = dg(&i, cast(void *)&d);
10111 + if (result)
10112 + break;
10113 + }
10114 + return result;
10115 +}
10116 +
10117 +extern (C) int _aApplywd2(wchar[] aa, dg2_t dg)
10118 +{ int result;
10119 + size_t i;
10120 + size_t n;
10121 + size_t len = aa.length;
10122 +
10123 + debug(apply) printf("_aApplywd2(), len = %d\n", len);
10124 + for (i = 0; i < len; i += n)
10125 + { dchar d;
10126 +
10127 + d = aa[i];
10128 + if (d & ~0x7F)
10129 + {
10130 + n = i;
10131 + d = decode(aa, n);
10132 + n -= i;
10133 + }
10134 + else
10135 + n = 1;
10136 + result = dg(&i, cast(void *)&d);
10137 + if (result)
10138 + break;
10139 + }
10140 + return result;
10141 +}
10142 +
10143 +extern (C) int _aApplycw2(char[] aa, dg2_t dg)
10144 +{ int result;
10145 + size_t i;
10146 + size_t n;
10147 + size_t len = aa.length;
10148 +
10149 + debug(apply) printf("_aApplycw2(), len = %d\n", len);
10150 + for (i = 0; i < len; i += n)
10151 + { dchar d;
10152 + wchar w;
10153 +
10154 + w = aa[i];
10155 + if (w & 0x80)
10156 + { n = i;
10157 + d = decode(aa, n);
10158 + n -= i;
10159 + if (d <= 0xFFFF)
10160 + w = cast(wchar) d;
10161 + else
10162 + {
10163 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
10164 + result = dg(&i, cast(void *)&w);
10165 + if (result)
10166 + break;
10167 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
10168 + }
10169 + }
10170 + else
10171 + n = 1;
10172 + result = dg(&i, cast(void *)&w);
10173 + if (result)
10174 + break;
10175 + }
10176 + return result;
10177 +}
10178 +
10179 +extern (C) int _aApplywc2(wchar[] aa, dg2_t dg)
10180 +{ int result;
10181 + size_t i;
10182 + size_t n;
10183 + size_t len = aa.length;
10184 +
10185 + debug(apply) printf("_aApplywc2(), len = %d\n", len);
10186 + for (i = 0; i < len; i += n)
10187 + { dchar d;
10188 + wchar w;
10189 + char c;
10190 +
10191 + w = aa[i];
10192 + if (w & ~0x7F)
10193 + {
10194 + char[4] buf;
10195 +
10196 + n = i;
10197 + d = decode(aa, n);
10198 + n -= i;
10199 + auto b = toUTF8(buf, d);
10200 + foreach (char c2; b)
10201 + {
10202 + result = dg(&i, cast(void *)&c2);
10203 + if (result)
10204 + return result;
10205 + }
10206 + continue;
10207 + }
10208 + else
10209 + { c = cast(char)w;
10210 + n = 1;
10211 + }
10212 + result = dg(&i, cast(void *)&c);
10213 + if (result)
10214 + break;
10215 + }
10216 + return result;
10217 +}
10218 +
10219 +extern (C) int _aApplydc2(dchar[] aa, dg2_t dg)
10220 +{ int result;
10221 + size_t i;
10222 + size_t len = aa.length;
10223 +
10224 + debug(apply) printf("_aApplydc2(), len = %d\n", len);
10225 + for (i = 0; i < len; i++)
10226 + { dchar d;
10227 + char c;
10228 +
10229 + d = aa[i];
10230 + debug(apply) printf("d = %u\n", d);
10231 + if (d & ~0x7F)
10232 + {
10233 + char[4] buf;
10234 +
10235 + auto b = toUTF8(buf, d);
10236 + foreach (char c2; b)
10237 + {
10238 + debug(apply) printf("c2 = %d\n", c2);
10239 + result = dg(&i, cast(void *)&c2);
10240 + if (result)
10241 + return result;
10242 + }
10243 + continue;
10244 + }
10245 + else
10246 + { c = cast(char)d;
10247 + }
10248 + result = dg(&i, cast(void *)&c);
10249 + if (result)
10250 + break;
10251 + }
10252 + return result;
10253 +}
10254 +
10255 +extern (C) int _aApplydw2(dchar[] aa, dg2_t dg)
10256 +{ int result;
10257 +
10258 + debug(apply) printf("_aApplydw2(), len = %d\n", aa.length);
10259 + foreach (size_t i, dchar d; aa)
10260 + {
10261 + wchar w;
10262 + auto j = i;
10263 +
10264 + if (d <= 0xFFFF)
10265 + w = cast(wchar) d;
10266 + else
10267 + {
10268 + w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
10269 + result = dg(&j, cast(void *)&w);
10270 + if (result)
10271 + break;
10272 + w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
10273 + }
10274 + result = dg(&j, cast(void *)&w);
10275 + if (result)
10276 + break;
10277 + }
10278 + return result;
10279 +}
10280 Index: src/compiler/ldc/monitor.c
10281 ===================================================================
10282 --- src/compiler/ldc/monitor.c (revision 0)
10283 +++ src/compiler/ldc/monitor.c (revision 0)
10284 @@ -0,0 +1,212 @@
10285 +// D programming language runtime library
10286 +// Public Domain
10287 +// written by Walter Bright, Digital Mars
10288 +// www.digitalmars.com
10289 +
10290 +// This is written in C because nobody has written a pthreads interface
10291 +// to D yet.
10292 +
10293 +
10294 +#include <stdio.h>
10295 +#include <stdlib.h>
10296 +#include <assert.h>
10297 +
10298 +#if _WIN32
10299 +#elif linux || __APPLE__
10300 +#define USE_PTHREADS 1
10301 +#else
10302 +#endif
10303 +
10304 +#if _WIN32
10305 +#include <windows.h>
10306 +#endif
10307 +
10308 +#if USE_PTHREADS
10309 +#include <pthread.h>
10310 +#endif
10311 +
10312 +#include "mars.h"
10313 +
10314 +// This is what the monitor reference in Object points to
10315 +typedef struct Monitor
10316 +{
10317 + void* impl; // for user-level monitors
10318 + Array devt; // for internal monitors
10319 +
10320 +#if _WIN32
10321 + CRITICAL_SECTION mon;
10322 +#endif
10323 +
10324 +#if USE_PTHREADS
10325 + pthread_mutex_t mon;
10326 +#endif
10327 +} Monitor;
10328 +
10329 +#define MONPTR(h) (&((Monitor *)(h)->monitor)->mon)
10330 +
10331 +static volatile int inited;
10332 +
10333 +/* =============================== Win32 ============================ */
10334 +
10335 +#if _WIN32
10336 +
10337 +static CRITICAL_SECTION _monitor_critsec;
10338 +
10339 +void _STI_monitor_staticctor()
10340 +{
10341 + if (!inited)
10342 + { InitializeCriticalSection(&_monitor_critsec);
10343 + inited = 1;
10344 + }
10345 +}
10346 +
10347 +void _STD_monitor_staticdtor()
10348 +{
10349 + if (inited)
10350 + { inited = 0;
10351 + DeleteCriticalSection(&_monitor_critsec);
10352 + }
10353 +}
10354 +
10355 +void _d_monitor_create(Object *h)
10356 +{
10357 + /*
10358 + * NOTE: Assume this is only called when h->monitor is null prior to the
10359 + * call. However, please note that another thread may call this function
10360 + * at the same time, so we can not assert this here. Instead, try and
10361 + * create a lock, and if one already exists then forget about it.
10362 + */
10363 +
10364 + //printf("+_d_monitor_create(%p)\n", h);
10365 + assert(h);
10366 + Monitor *cs = NULL;
10367 + EnterCriticalSection(&_monitor_critsec);
10368 + if (!h->monitor)
10369 + {
10370 + cs = (Monitor *)calloc(sizeof(Monitor), 1);
10371 + assert(cs);
10372 + InitializeCriticalSection(&cs->mon);
10373 + h->monitor = (void *)cs;
10374 + cs = NULL;
10375 + }
10376 + LeaveCriticalSection(&_monitor_critsec);
10377 + if (cs)
10378 + free(cs);
10379 + //printf("-_d_monitor_create(%p)\n", h);
10380 +}
10381 +
10382 +void _d_monitor_destroy(Object *h)
10383 +{
10384 + //printf("+_d_monitor_destroy(%p)\n", h);
10385 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10386 + DeleteCriticalSection(MONPTR(h));
10387 + free((void *)h->monitor);
10388 + h->monitor = NULL;
10389 + //printf("-_d_monitor_destroy(%p)\n", h);
10390 +}
10391 +
10392 +int _d_monitor_lock(Object *h)
10393 +{
10394 + //printf("+_d_monitor_acquire(%p)\n", h);
10395 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10396 + EnterCriticalSection(MONPTR(h));
10397 + //printf("-_d_monitor_acquire(%p)\n", h);
10398 +}
10399 +
10400 +void _d_monitor_unlock(Object *h)
10401 +{
10402 + //printf("+_d_monitor_release(%p)\n", h);
10403 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10404 + LeaveCriticalSection(MONPTR(h));
10405 + //printf("-_d_monitor_release(%p)\n", h);
10406 +}
10407 +
10408 +#endif
10409 +
10410 +/* =============================== linux ============================ */
10411 +
10412 +#if USE_PTHREADS
10413 +
10414 +#if !linux
10415 +#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
10416 +#endif
10417 +
10418 +// Includes attribute fixes from David Friedman's GDC port
10419 +
10420 +static pthread_mutex_t _monitor_critsec;
10421 +static pthread_mutexattr_t _monitors_attr;
10422 +
10423 +void _STI_monitor_staticctor()
10424 +{
10425 + if (!inited)
10426 + {
10427 + pthread_mutexattr_init(&_monitors_attr);
10428 + pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP);
10429 + pthread_mutex_init(&_monitor_critsec, 0);
10430 + inited = 1;
10431 + }
10432 +}
10433 +
10434 +void _STD_monitor_staticdtor()
10435 +{
10436 + if (inited)
10437 + { inited = 0;
10438 + pthread_mutex_destroy(&_monitor_critsec);
10439 + pthread_mutexattr_destroy(&_monitors_attr);
10440 + }
10441 +}
10442 +
10443 +void _d_monitor_create(Object *h)
10444 +{
10445 + /*
10446 + * NOTE: Assume this is only called when h->monitor is null prior to the
10447 + * call. However, please note that another thread may call this function
10448 + * at the same time, so we can not assert this here. Instead, try and
10449 + * create a lock, and if one already exists then forget about it.
10450 + */
10451 +
10452 + //printf("+_d_monitor_create(%p)\n", h);
10453 + assert(h);
10454 + Monitor *cs = NULL;
10455 + pthread_mutex_lock(&_monitor_critsec);
10456 + if (!h->monitor)
10457 + {
10458 + cs = (Monitor *)calloc(sizeof(Monitor), 1);
10459 + assert(cs);
10460 + pthread_mutex_init(&cs->mon, & _monitors_attr);
10461 + h->monitor = (void *)cs;
10462 + cs = NULL;
10463 + }
10464 + pthread_mutex_unlock(&_monitor_critsec);
10465 + if (cs)
10466 + free(cs);
10467 + //printf("-_d_monitor_create(%p)\n", h);
10468 +}
10469 +
10470 +void _d_monitor_destroy(Object *h)
10471 +{
10472 + //printf("+_d_monitor_destroy(%p)\n", h);
10473 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10474 + pthread_mutex_destroy(MONPTR(h));
10475 + free((void *)h->monitor);
10476 + h->monitor = NULL;
10477 + //printf("-_d_monitor_destroy(%p)\n", h);
10478 +}
10479 +
10480 +int _d_monitor_lock(Object *h)
10481 +{
10482 + //printf("+_d_monitor_acquire(%p)\n", h);
10483 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10484 + pthread_mutex_lock(MONPTR(h));
10485 + //printf("-_d_monitor_acquire(%p)\n", h);
10486 +}
10487 +
10488 +void _d_monitor_unlock(Object *h)
10489 +{
10490 + //printf("+_d_monitor_release(%p)\n", h);
10491 + assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
10492 + pthread_mutex_unlock(MONPTR(h));
10493 + //printf("-_d_monitor_release(%p)\n", h);
10494 +}
10495 +
10496 +#endif
10497 Index: src/compiler/ldc/ldc.mak
10498 ===================================================================
10499 --- src/compiler/ldc/ldc.mak (revision 0)
10500 +++ src/compiler/ldc/ldc.mak (revision 0)
10501 @@ -0,0 +1,166 @@
10502 +# Makefile to build the compiler runtime D library for Linux
10503 +# Designed to work with GNU make
10504 +# Targets:
10505 +# make
10506 +# Same as make all
10507 +# make lib
10508 +# Build the compiler runtime library
10509 +# make doc
10510 +# Generate documentation
10511 +# make clean
10512 +# Delete unneeded files created by build process
10513 +
10514 +LIB_TARGET=libdruntime-rt-ldc.a
10515 +LIB_MASK=libdruntime-rt-ldc*.a
10516 +
10517 +CP=cp -f
10518 +RM=rm -f
10519 +MD=mkdir -p
10520 +
10521 +#CFLAGS=-O $(ADD_CFLAGS)
10522 +CFLAGS=-g $(ADD_CFLAGS)
10523 +
10524 +#DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
10525 +DFLAGS=-g -w $(ADD_DFLAGS)
10526 +
10527 +#TFLAGS=-O -inline -w $(ADD_DFLAGS)
10528 +TFLAGS=-g -w $(ADD_DFLAGS)
10529 +
10530 +DOCFLAGS=-version=DDoc
10531 +
10532 +CC=gcc
10533 +LC=$(AR) -qsv
10534 +DC=ldc2
10535 +
10536 +LIB_DEST=../../../lib
10537 +IMPORT_DEST=../../../import/
10538 +
10539 +.SUFFIXES: .s .S .c .cpp .d .html .o
10540 +
10541 +.s.o:
10542 + $(CC) -c $(CFLAGS) $< -o$@
10543 +
10544 +.S.o:
10545 + $(CC) -c $(CFLAGS) $< -o$@
10546 +
10547 +.c.o:
10548 + $(CC) -c $(CFLAGS) $< -o$@
10549 +
10550 +.cpp.o:
10551 + g++ -c $(CFLAGS) $< -o$@
10552 +
10553 +.d.o:
10554 + $(DC) -c $(DFLAGS) $< -of$@
10555 +
10556 +.d.html:
10557 + $(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
10558 +
10559 +targets : lib doc
10560 +all : lib doc
10561 +lib : ldc.lib
10562 +doc : ldc.doc
10563 +
10564 +######################################################
10565 +
10566 +OBJ_BASE= \
10567 + aaA.o \
10568 + aApply.o \
10569 + aApplyR.o \
10570 + adi.o \
10571 + arrayInit.o \
10572 + cast.o \
10573 + critical.o \
10574 + eh.o \
10575 + dmain2.o \
10576 + invariant.o \
10577 + lifetime.o \
10578 + memory.o \
10579 + monitor.o \
10580 + genobj.o \
10581 + qsort2.o \
10582 + switch.o
10583 +
10584 +OBJ_UTIL= \
10585 + util/console.o \
10586 + util/ctype.o \
10587 + util/string.o \
10588 + util/utf.o \
10589 + ldc/bitmanip.o \
10590 + ldc/vararg.o
10591 +
10592 +OBJ_TI= \
10593 + typeinfo/ti_AC.o \
10594 + typeinfo/ti_Acdouble.o \
10595 + typeinfo/ti_Acfloat.o \
10596 + typeinfo/ti_Acreal.o \
10597 + typeinfo/ti_Adouble.o \
10598 + typeinfo/ti_Afloat.o \
10599 + typeinfo/ti_Ag.o \
10600 + typeinfo/ti_Aint.o \
10601 + typeinfo/ti_Along.o \
10602 + typeinfo/ti_Areal.o \
10603 + typeinfo/ti_Ashort.o \
10604 + typeinfo/ti_byte.o \
10605 + typeinfo/ti_C.o \
10606 + typeinfo/ti_cdouble.o \
10607 + typeinfo/ti_cfloat.o \
10608 + typeinfo/ti_char.o \
10609 + typeinfo/ti_creal.o \
10610 + typeinfo/ti_dchar.o \
10611 + typeinfo/ti_delegate.o \
10612 + typeinfo/ti_double.o \
10613 + typeinfo/ti_float.o \
10614 + typeinfo/ti_idouble.o \
10615 + typeinfo/ti_ifloat.o \
10616 + typeinfo/ti_int.o \
10617 + typeinfo/ti_ireal.o \
10618 + typeinfo/ti_long.o \
10619 + typeinfo/ti_ptr.o \
10620 + typeinfo/ti_real.o \
10621 + typeinfo/ti_short.o \
10622 + typeinfo/ti_ubyte.o \
10623 + typeinfo/ti_uint.o \
10624 + typeinfo/ti_ulong.o \
10625 + typeinfo/ti_ushort.o \
10626 + typeinfo/ti_void.o \
10627 + typeinfo/ti_wchar.o
10628 +
10629 +ALL_OBJS= \
10630 + $(OBJ_BASE) \
10631 + $(OBJ_UTIL) \
10632 + $(OBJ_TI)
10633 +
10634 +######################################################
10635 +
10636 +ALL_DOCS=
10637 +
10638 +######################################################
10639 +
10640 +ldc.lib : $(LIB_TARGET)
10641 +
10642 +$(LIB_TARGET) : $(ALL_OBJS)
10643 + $(RM) $@
10644 + $(LC) $@ $(ALL_OBJS)
10645 +
10646 +ldc.doc : $(ALL_DOCS)
10647 + echo No documentation available.
10648 +
10649 +################### LDC SPECIALS #####################
10650 +
10651 +ldc/bitmanip.o : ldc/bitmanip.d
10652 + $(DC) -c $(DFLAGS) -d -Hf$(IMPORT_DEST)/$*.di ldc/bitmanip.d -of$@
10653 +
10654 +ldc/vararg.o : ldc/vararg.d
10655 + $(DC) -c $(DFLAGS) -d -Hf$(IMPORT_DEST)/$*.di ldc/vararg.d -of$@
10656 +
10657 +######################################################
10658 +
10659 +clean :
10660 + find . -name "*.di" | xargs $(RM)
10661 + $(RM) $(ALL_OBJS)
10662 + $(RM) $(ALL_DOCS)
10663 + $(RM) $(LIB_MASK)
10664 +
10665 +install :
10666 + $(MD) $(LIB_DEST)
10667 + $(CP) $(LIB_MASK) $(LIB_DEST)/.
10668 Index: src/compiler/ldc/critical.c
10669 ===================================================================
10670 --- src/compiler/ldc/critical.c (revision 0)
10671 +++ src/compiler/ldc/critical.c (revision 0)
10672 @@ -0,0 +1,164 @@
10673 +/*
10674 + * Placed into the Public Domain
10675 + * written by Walter Bright, Digital Mars
10676 + * www.digitalmars.com
10677 + */
10678 +
10679 +/* ================================= Win32 ============================ */
10680 +
10681 +#if _WIN32
10682 +
10683 +#include <windows.h>
10684 +
10685 +/******************************************
10686 + * Enter/exit critical section.
10687 + */
10688 +
10689 +/* We don't initialize critical sections unless we actually need them.
10690 + * So keep a linked list of the ones we do use, and in the static destructor
10691 + * code, walk the list and release them.
10692 + */
10693 +
10694 +typedef struct D_CRITICAL_SECTION
10695 +{
10696 + struct D_CRITICAL_SECTION *next;
10697 + CRITICAL_SECTION cs;
10698 +} D_CRITICAL_SECTION;
10699 +
10700 +static D_CRITICAL_SECTION *dcs_list;
10701 +static D_CRITICAL_SECTION critical_section;
10702 +static volatile int inited;
10703 +
10704 +void _d_criticalenter(D_CRITICAL_SECTION *dcs)
10705 +{
10706 + if (!dcs->next)
10707 + {
10708 + EnterCriticalSection(&critical_section.cs);
10709 + if (!dcs->next) // if, in the meantime, another thread didn't set it
10710 + {
10711 + dcs->next = dcs_list;
10712 + dcs_list = dcs;
10713 + InitializeCriticalSection(&dcs->cs);
10714 + }
10715 + LeaveCriticalSection(&critical_section.cs);
10716 + }
10717 + EnterCriticalSection(&dcs->cs);
10718 +}
10719 +
10720 +void _d_criticalexit(D_CRITICAL_SECTION *dcs)
10721 +{
10722 + LeaveCriticalSection(&dcs->cs);
10723 +}
10724 +
10725 +void _STI_critical_init()
10726 +{
10727 + if (!inited)
10728 + { InitializeCriticalSection(&critical_section.cs);
10729 + dcs_list = &critical_section;
10730 + inited = 1;
10731 + }
10732 +}
10733 +
10734 +void _STD_critical_term()
10735 +{
10736 + if (inited)
10737 + { inited = 0;
10738 + while (dcs_list)
10739 + {
10740 + DeleteCriticalSection(&dcs_list->cs);
10741 + dcs_list = dcs_list->next;
10742 + }
10743 + }
10744 +}
10745 +
10746 +#endif
10747 +
10748 +/* ================================= linux ============================ */
10749 +
10750 +#if linux || __APPLE__ || __FreeBSD__
10751 +
10752 +#include <stdio.h>
10753 +#include <stdlib.h>
10754 +#include <pthread.h>
10755 +
10756 +#if !linux
10757 +#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
10758 +#endif
10759 +
10760 +/******************************************
10761 + * Enter/exit critical section.
10762 + */
10763 +
10764 +/* We don't initialize critical sections unless we actually need them.
10765 + * So keep a linked list of the ones we do use, and in the static destructor
10766 + * code, walk the list and release them.
10767 + */
10768 +
10769 +typedef struct D_CRITICAL_SECTION
10770 +{
10771 + struct D_CRITICAL_SECTION *next;
10772 + pthread_mutex_t cs;
10773 +} D_CRITICAL_SECTION;
10774 +
10775 +static D_CRITICAL_SECTION *dcs_list;
10776 +static D_CRITICAL_SECTION critical_section;
10777 +static pthread_mutexattr_t _criticals_attr;
10778 +
10779 +void _STI_critical_init(void);
10780 +void _STD_critical_term(void);
10781 +
10782 +void _d_criticalenter(D_CRITICAL_SECTION *dcs)
10783 +{
10784 + if (!dcs_list)
10785 + { _STI_critical_init();
10786 + atexit(_STD_critical_term);
10787 + }
10788 + //printf("_d_criticalenter(dcs = x%x)\n", dcs);
10789 + if (!dcs->next)
10790 + {
10791 + pthread_mutex_lock(&critical_section.cs);
10792 + if (!dcs->next) // if, in the meantime, another thread didn't set it
10793 + {
10794 + dcs->next = dcs_list;
10795 + dcs_list = dcs;
10796 + pthread_mutex_init(&dcs->cs, &_criticals_attr);
10797 + }
10798 + pthread_mutex_unlock(&critical_section.cs);
10799 + }
10800 + pthread_mutex_lock(&dcs->cs);
10801 +}
10802 +
10803 +void _d_criticalexit(D_CRITICAL_SECTION *dcs)
10804 +{
10805 + //printf("_d_criticalexit(dcs = x%x)\n", dcs);
10806 + pthread_mutex_unlock(&dcs->cs);
10807 +}
10808 +
10809 +void _STI_critical_init()
10810 +{
10811 + if (!dcs_list)
10812 + { //printf("_STI_critical_init()\n");
10813 + pthread_mutexattr_init(&_criticals_attr);
10814 + pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP);
10815 +
10816 + // The global critical section doesn't need to be recursive
10817 + pthread_mutex_init(&critical_section.cs, 0);
10818 + dcs_list = &critical_section;
10819 + }
10820 +}
10821 +
10822 +void _STD_critical_term()
10823 +{
10824 + if (dcs_list)
10825 + { //printf("_STI_critical_term()\n");
10826 + while (dcs_list)
10827 + {
10828 + //printf("\tlooping... %x\n", dcs_list);
10829 + pthread_mutex_destroy(&dcs_list->cs);
10830 + dcs_list = dcs_list->next;
10831 + }
10832 + }
10833 +}
10834 +
10835 +#endif
10836 +
10837 Index: src/compiler/ldc/qsort2.d
10838 ===================================================================
10839 --- src/compiler/ldc/qsort2.d (revision 0)
10840 +++ src/compiler/ldc/qsort2.d (revision 0)
10841 @@ -0,0 +1,67 @@
10842 +
10843 +/*
10844 + * Placed into Public Domain
10845 + * written by Walter Bright
10846 + * www.digitalmars.com
10847 + *
10848 + * This is a public domain version of qsort.d.
10849 + * All it does is call C's qsort(), but runs a little slower since
10850 + * it needs to synchronize a global variable.
10851 + */
10852 +
10853 +/*
10854 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
10855 + */
10856 +
10857 +//debug=qsort;
10858 +
10859 +version( D_Version2 )
10860 +private import stdlib = core.stdc.stdlib;
10861 +else
10862 +private import stdlib = tango.stdc.stdlib;
10863 +
10864 +private TypeInfo tiglobal;
10865 +
10866 +extern (C) int cmp(in void* p1, in void* p2)
10867 +{
10868 + return tiglobal.compare(p1, p2);
10869 +}
10870 +
10871 +extern (C) void[] _adSort(void[] a, TypeInfo ti)
10872 +{
10873 + synchronized
10874 + {
10875 + tiglobal = ti;
10876 + stdlib.qsort(a.ptr, a.length, cast(size_t)ti.tsize(), &cmp);
10877 + }
10878 + return a;
10879 +}
10880 +
10881 +
10882 +
10883 +unittest
10884 +{
10885 + debug(qsort) printf("array.sort.unittest()\n");
10886 +
10887 + int a[] = new int[10];
10888 +
10889 + a[0] = 23;
10890 + a[1] = 1;
10891 + a[2] = 64;
10892 + a[3] = 5;
10893 + a[4] = 6;
10894 + a[5] = 5;
10895 + a[6] = 17;
10896 + a[7] = 3;
10897 + a[8] = 0;
10898 + a[9] = -1;
10899 +
10900 + a.sort;
10901 +
10902 + for (int i = 0; i < a.length - 1; i++)
10903 + {
10904 + //printf("i = %d", i);
10905 + //printf(" %d %d\n", a[i], a[i + 1]);
10906 + assert(a[i] <= a[i + 1]);
10907 + }
10908 +}
10909 Index: src/compiler/ldc/cast.d
10910 ===================================================================
10911 --- src/compiler/ldc/cast.d (revision 0)
10912 +++ src/compiler/ldc/cast.d (revision 0)
10913 @@ -0,0 +1,196 @@
10914 +/*
10915 + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
10916 + * Written by Walter Bright
10917 + *
10918 + * This software is provided 'as-is', without any express or implied
10919 + * warranty. In no event will the authors be held liable for any damages
10920 + * arising from the use of this software.
10921 + *
10922 + * Permission is granted to anyone to use this software for any purpose,
10923 + * including commercial applications, and to alter it and redistribute it
10924 + * freely, in both source and binary form, subject to the following
10925 + * restrictions:
10926 + *
10927 + * o The origin of this software must not be misrepresented; you must not
10928 + * claim that you wrote the original software. If you use this software
10929 + * in a product, an acknowledgment in the product documentation would be
10930 + * appreciated but is not required.
10931 + * o Altered source versions must be plainly marked as such, and must not
10932 + * be misrepresented as being the original software.
10933 + * o This notice may not be removed or altered from any source
10934 + * distribution.
10935 + */
10936 +
10937 +/*
10938 + * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
10939 + */
10940 +
10941 +extern (C):
10942 +
10943 +//debug = PRINTF;
10944 +debug(PRINTF) int printf(char*, ...);
10945 +
10946 +/******************************************
10947 + * Given a pointer:
10948 + * If it is an Object, return that Object.
10949 + * If it is an interface, return the Object implementing the interface.
10950 + * If it is null, return null.
10951 + * Else, undefined crash
10952 + */
10953 +
10954 +Object _d_toObject(void* p)
10955 +{ Object o;
10956 + debug(PRINTF) printf("toObject(%p)\n", p);
10957 + if (p)
10958 + {
10959 + o = cast(Object)p;
10960 + debug(PRINTF) printf("o = %p\n", o);
10961 + debug(PRINTF) printf("o.vtbl = %p\n", *cast(void**)p);
10962 + ClassInfo oc = o.classinfo;
10963 + debug(PRINTF) printf("oc = %p\n", oc);
10964 + Interface *pi = **cast(Interface ***)p;
10965 + debug(PRINTF) printf("pi = %p\n", pi);
10966 +
10967 + /* Interface.offset lines up with ClassInfo.name.ptr,
10968 + * so we rely on pointers never being less than 64K,
10969 + * and interface vtable offsets never being greater.
10970 + */
10971 + if (pi.offset < 0x10000)
10972 + {
10973 + debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
10974 + o = cast(Object)(p - pi.offset);
10975 + }
10976 + }
10977 + debug(PRINTF) printf("toObject = %p\n", o);
10978 + return o;
10979 +}
10980 +
10981 +
10982 +/*************************************
10983 + * Attempts to cast Object o to class c.
10984 + * Returns o if successful, null if not.
10985 + */
10986 +
10987 +Object _d_interface_cast(void* p, ClassInfo c)
10988 +{ Object o;
10989 +
10990 + debug(PRINTF) printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name.length, c.name.ptr);
10991 + if (p)
10992 + {
10993 + Interface *pi = **cast(Interface ***)p;
10994 +
10995 + debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
10996 + o = cast(Object)(p - pi.offset);
10997 + return _d_dynamic_cast(o, c);
10998 + }
10999 + debug(PRINTF) printf("_d_interface_cast = %p\n", o);
11000 + return o;
11001 +}
11002 +
11003 +Object _d_dynamic_cast(Object o, ClassInfo c)
11004 +{ ClassInfo oc;
11005 + size_t offset = 0;
11006 +
11007 + debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr);
11008 +
11009 + if (o)
11010 + {
11011 + oc = o.classinfo;
11012 + if (_d_isbaseof2(oc, c, offset))
11013 + {
11014 + debug(PRINTF) printf("\toffset = %d\n", offset);
11015 + o = cast(Object)(cast(void*)o + offset);
11016 + }
11017 + else
11018 + o = null;
11019 + }
11020 + //printf("\tresult = %p\n", o);
11021 + debug(PRINTF) printf("_d_dynamic_cast = %p\n", o);
11022 + return o;
11023 +}
11024 +
11025 +int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
11026 +{ int i;
11027 +
11028 + debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset);
11029 +
11030 + if (oc is c)
11031 + return 1;
11032 + do
11033 + {
11034 + debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length);
11035 + if (oc.base is c)
11036 + return 1;
11037 + for (i = 0; i < oc.interfaces.length; i++)
11038 + {
11039 + ClassInfo ic;
11040 +
11041 + ic = oc.interfaces[i].classinfo;
11042 + debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr);
11043 + if (ic is c)
11044 + { offset = cast(size_t)oc.interfaces[i].offset;
11045 + return 1;
11046 + }
11047 + }
11048 + for (i = 0; i < oc.interfaces.length; i++)
11049 + {
11050 + ClassInfo ic;
11051 +
11052 + ic = oc.interfaces[i].classinfo;
11053 + if (_d_isbaseof2(ic, c, offset))
11054 + { offset = cast(size_t)oc.interfaces[i].offset;
11055 + return 1;
11056 + }
11057 + }
11058 + oc = oc.base;
11059 + } while (oc);
11060 + return 0;
11061 +}
11062 +
11063 +int _d_isbaseof(ClassInfo oc, ClassInfo c)
11064 +{ int i;
11065 +
11066 + if (oc is c)
11067 + return 1;
11068 + do
11069 + {
11070 + if (oc.base is c)
11071 + return 1;
11072 + for (i = 0; i < oc.interfaces.length; i++)
11073 + {
11074 + ClassInfo ic;
11075 +
11076 + ic = oc.interfaces[i].classinfo;
11077 + if (ic is c || _d_isbaseof(ic, c))
11078 + return 1;
11079 + }
11080 + oc = oc.base;
11081 + } while (oc);
11082 + return 0;
11083 +}
11084 +
11085 +/*********************************
11086 + * Find the vtbl[] associated with Interface ic.
11087 + */
11088 +
11089 +void *_d_interface_vtbl(ClassInfo ic, Object o)
11090 +{ int i;
11091 + ClassInfo oc;
11092 +
11093 + //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic);
11094 +
11095 + assert(o);
11096 +
11097 + oc = o.classinfo;
11098 + for (i = 0; i < oc.interfaces.length; i++)
11099 + {
11100 + ClassInfo oic;
11101 +
11102 + oic = oc.interfaces[i].classinfo;
11103 + if (oic is ic)
11104 + {
11105 + return cast(void *)oc.interfaces[i].vtbl;
11106 + }
11107 + }
11108 + assert(0);
11109 +}
11110 Index: src/compiler/ldc/util/utf.d
11111 ===================================================================
11112 --- src/compiler/ldc/util/utf.d (revision 0)
11113 +++ src/compiler/ldc/util/utf.d (revision 0)
11114 @@ -0,0 +1,917 @@
11115 +// Written in the D programming language
11116 +
11117 +/*
11118 + * Copyright (C) 2003-2004 by Digital Mars, www.digitalmars.com
11119 + * Written by Walter Bright
11120 + *
11121 + * This software is provided 'as-is', without any express or implied
11122 + * warranty. In no event will the authors be held liable for any damages
11123 + * arising from the use of this software.
11124 + *
11125 + * Permission is granted to anyone to use this software for any purpose,
11126 + * including commercial applications, and to alter it and redistribute it
11127 + * freely, subject to the following restrictions:
11128 + *
11129 + * o The origin of this software must not be misrepresented; you must not
11130 + * claim that you wrote the original software. If you use this software
11131 + * in a product, an acknowledgment in the product documentation would be
11132 + * appreciated but is not required.
11133 + * o Altered source versions must be plainly marked as such, and must not
11134 + * be misrepresented as being the original software.
11135 + * o This notice may not be removed or altered from any source
11136 + * distribution.
11137 + */
11138 +
11139 +/********************************************
11140 + * Encode and decode UTF-8, UTF-16 and UTF-32 strings.
11141 + *
11142 + * For Win32 systems, the C wchar_t type is UTF-16 and corresponds to the D
11143 + * wchar type.
11144 + * For linux systems, the C wchar_t type is UTF-32 and corresponds to
11145 + * the D utf.dchar type.
11146 + *
11147 + * UTF character support is restricted to (\u0000 &lt;= character &lt;= \U0010FFFF).
11148 + *
11149 + * See_Also:
11150 + * $(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia)<br>
11151 + * $(LINK http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8)<br>
11152 + * $(LINK http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335)
11153 + * Macros:
11154 + * WIKI = Phobos/StdUtf
11155 + */
11156 +
11157 +module rt.util.utf;
11158 +
11159 +
11160 +extern (C) void onUnicodeError( string msg, size_t idx );
11161 +
11162 +/*******************************
11163 + * Test if c is a valid UTF-32 character.
11164 + *
11165 + * \uFFFE and \uFFFF are considered valid by this function,
11166 + * as they are permitted for internal use by an application,
11167 + * but they are not allowed for interchange by the Unicode standard.
11168 + *
11169 + * Returns: true if it is, false if not.
11170 + */
11171 +
11172 +bool isValidDchar(dchar c)
11173 +{
11174 + /* Note: FFFE and FFFF are specifically permitted by the
11175 + * Unicode standard for application internal use, but are not
11176 + * allowed for interchange.
11177 + * (thanks to Arcane Jill)
11178 + */
11179 +
11180 + return c < 0xD800 ||
11181 + (c > 0xDFFF && c <= 0x10FFFF /*&& c != 0xFFFE && c != 0xFFFF*/);
11182 +}
11183 +
11184 +unittest
11185 +{
11186 + debug(utf) printf("utf.isValidDchar.unittest\n");
11187 + assert(isValidDchar(cast(dchar)'a') == true);
11188 + assert(isValidDchar(cast(dchar)0x1FFFFF) == false);
11189 +}
11190 +
11191 +
11192 +
11193 +auto UTF8stride =
11194 +[
11195 + cast(ubyte)
11196 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11197 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11198 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11199 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11200 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11201 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11202 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11203 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
11204 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11205 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11206 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11207 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11208 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
11209 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
11210 + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
11211 + 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF,
11212 +];
11213 +
11214 +/**
11215 + * stride() returns the length of a UTF-8 sequence starting at index i
11216 + * in string s.
11217 + * Returns:
11218 + * The number of bytes in the UTF-8 sequence or
11219 + * 0xFF meaning s[i] is not the start of of UTF-8 sequence.
11220 + */
11221 +uint stride(in char[] s, size_t i)
11222 +{
11223 + return UTF8stride[s[i]];
11224 +}
11225 +
11226 +/**
11227 + * stride() returns the length of a UTF-16 sequence starting at index i
11228 + * in string s.
11229 + */
11230 +uint stride(in wchar[] s, size_t i)
11231 +{ uint u = s[i];
11232 + return 1 + (u >= 0xD800 && u <= 0xDBFF);
11233 +}
11234 +
11235 +/**
11236 + * stride() returns the length of a UTF-32 sequence starting at index i
11237 + * in string s.
11238 + * Returns: The return value will always be 1.
11239 + */
11240 +uint stride(in dchar[] s, size_t i)
11241 +{
11242 + return 1;
11243 +}
11244 +
11245 +/*******************************************
11246 + * Given an index i into an array of characters s[],
11247 + * and assuming that index i is at the start of a UTF character,
11248 + * determine the number of UCS characters up to that index i.
11249 + */
11250 +
11251 +size_t toUCSindex(in char[] s, size_t i)
11252 +{
11253 + size_t n;
11254 + size_t j;
11255 +
11256 + for (j = 0; j < i; )
11257 + {
11258 + j += stride(s, j);
11259 + n++;
11260 + }
11261 + if (j > i)
11262 + {
11263 + onUnicodeError("invalid UTF-8 sequence", j);
11264 + }
11265 + return n;
11266 +}
11267 +
11268 +/** ditto */
11269 +size_t toUCSindex(in wchar[] s, size_t i)
11270 +{
11271 + size_t n;
11272 + size_t j;
11273 +
11274 + for (j = 0; j < i; )
11275 + {
11276 + j += stride(s, j);
11277 + n++;
11278 + }
11279 + if (j > i)
11280 + {
11281 + onUnicodeError("invalid UTF-16 sequence", j);
11282 + }
11283 + return n;
11284 +}
11285 +
11286 +/** ditto */
11287 +size_t toUCSindex(in dchar[] s, size_t i)
11288 +{
11289 + return i;
11290 +}
11291 +
11292 +/******************************************
11293 + * Given a UCS index n into an array of characters s[], return the UTF index.
11294 + */
11295 +
11296 +size_t toUTFindex(in char[] s, size_t n)
11297 +{
11298 + size_t i;
11299 +
11300 + while (n--)
11301 + {
11302 + uint j = UTF8stride[s[i]];
11303 + if (j == 0xFF)
11304 + onUnicodeError("invalid UTF-8 sequence", i);
11305 + i += j;
11306 + }
11307 + return i;
11308 +}
11309 +
11310 +/** ditto */
11311 +size_t toUTFindex(in wchar[] s, size_t n)
11312 +{
11313 + size_t i;
11314 +
11315 + while (n--)
11316 + { wchar u = s[i];
11317 +
11318 + i += 1 + (u >= 0xD800 && u <= 0xDBFF);
11319 + }
11320 + return i;
11321 +}
11322 +
11323 +/** ditto */
11324 +size_t toUTFindex(in dchar[] s, size_t n)
11325 +{
11326 + return n;
11327 +}
11328 +
11329 +/* =================== Decode ======================= */
11330 +
11331 +/***************
11332 + * Decodes and returns character starting at s[idx]. idx is advanced past the
11333 + * decoded character. If the character is not well formed, a UtfException is
11334 + * thrown and idx remains unchanged.
11335 + */
11336 +dchar decode(in char[] s, inout size_t idx)
11337 + in
11338 + {
11339 + assert(idx >= 0 && idx < s.length);
11340 + }
11341 + out (result)
11342 + {
11343 + assert(isValidDchar(result));
11344 + }
11345 + body
11346 + {
11347 + size_t len = s.length;
11348 + dchar V;
11349 + size_t i = idx;
11350 + char u = s[i];
11351 +
11352 + if (u & 0x80)
11353 + { uint n;
11354 + char u2;
11355 +
11356 + /* The following encodings are valid, except for the 5 and 6 byte
11357 + * combinations:
11358 + * 0xxxxxxx
11359 + * 110xxxxx 10xxxxxx
11360 + * 1110xxxx 10xxxxxx 10xxxxxx
11361 + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
11362 + * 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
11363 + * 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
11364 + */
11365 + for (n = 1; ; n++)
11366 + {
11367 + if (n > 4)
11368 + goto Lerr; // only do the first 4 of 6 encodings
11369 + if (((u << n) & 0x80) == 0)
11370 + {
11371 + if (n == 1)
11372 + goto Lerr;
11373 + break;
11374 + }
11375 + }
11376 +
11377 + // Pick off (7 - n) significant bits of B from first byte of octet
11378 + V = cast(dchar)(u & ((1 << (7 - n)) - 1));
11379 +
11380 + if (i + (n - 1) >= len)
11381 + goto Lerr; // off end of string
11382 +
11383 + /* The following combinations are overlong, and illegal:
11384 + * 1100000x (10xxxxxx)
11385 + * 11100000 100xxxxx (10xxxxxx)
11386 + * 11110000 1000xxxx (10xxxxxx 10xxxxxx)
11387 + * 11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)
11388 + * 11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)
11389 + */
11390 + u2 = s[i + 1];
11391 + if ((u & 0xFE) == 0xC0 ||
11392 + (u == 0xE0 && (u2 & 0xE0) == 0x80) ||
11393 + (u == 0xF0 && (u2 & 0xF0) == 0x80) ||
11394 + (u == 0xF8 && (u2 & 0xF8) == 0x80) ||
11395 + (u == 0xFC && (u2 & 0xFC) == 0x80))
11396 + goto Lerr; // overlong combination
11397 +
11398 + for (uint j = 1; j != n; j++)
11399 + {
11400 + u = s[i + j];
11401 + if ((u & 0xC0) != 0x80)
11402 + goto Lerr; // trailing bytes are 10xxxxxx
11403 + V = (V << 6) | (u & 0x3F);
11404 + }
11405 + if (!isValidDchar(V))
11406 + goto Lerr;
11407 + i += n;
11408 + }
11409 + else
11410 + {
11411 + V = cast(dchar) u;
11412 + i++;
11413 + }
11414 +
11415 + idx = i;
11416 + return V;
11417 +
11418 + Lerr:
11419 + onUnicodeError("invalid UTF-8 sequence", i);
11420 + return V; // dummy return
11421 + }
11422 +
11423 +unittest
11424 +{ size_t i;
11425 + dchar c;
11426 +
11427 + debug(utf) printf("utf.decode.unittest\n");
11428 +
11429 + static s1 = "abcd"c;
11430 + i = 0;
11431 + c = decode(s1, i);
11432 + assert(c == cast(dchar)'a');
11433 + assert(i == 1);
11434 + c = decode(s1, i);
11435 + assert(c == cast(dchar)'b');
11436 + assert(i == 2);
11437 +
11438 + static s2 = "\xC2\xA9"c;
11439 + i = 0;
11440 + c = decode(s2, i);
11441 + assert(c == cast(dchar)'\u00A9');
11442 + assert(i == 2);
11443 +
11444 + static s3 = "\xE2\x89\xA0"c;
11445 + i = 0;
11446 + c = decode(s3, i);
11447 + assert(c == cast(dchar)'\u2260');
11448 + assert(i == 3);
11449 +
11450 + static s4 =
11451 + [ "\xE2\x89"c, // too short
11452 + "\xC0\x8A",
11453 + "\xE0\x80\x8A",
11454 + "\xF0\x80\x80\x8A",
11455 + "\xF8\x80\x80\x80\x8A",
11456 + "\xFC\x80\x80\x80\x80\x8A",
11457 + ];
11458 +
11459 + for (int j = 0; j < s4.length; j++)
11460 + {
11461 + try
11462 + {
11463 + i = 0;
11464 + c = decode(s4[j], i);
11465 + assert(0);
11466 + }
11467 + catch (Object o)
11468 + {
11469 + i = 23;
11470 + }
11471 + assert(i == 23);
11472 + }
11473 +}
11474 +
11475 +/** ditto */
11476 +
11477 +dchar decode(in wchar[] s, inout size_t idx)
11478 + in
11479 + {
11480 + assert(idx >= 0 && idx < s.length);
11481 + }
11482 + out (result)
11483 + {
11484 + assert(isValidDchar(result));
11485 + }
11486 + body
11487 + {
11488 + string msg;
11489 + dchar V;
11490 + size_t i = idx;
11491 + uint u = s[i];
11492 +
11493 + if (u & ~0x7F)
11494 + { if (u >= 0xD800 && u <= 0xDBFF)
11495 + { uint u2;
11496 +
11497 + if (i + 1 == s.length)
11498 + { msg = "surrogate UTF-16 high value past end of string";
11499 + goto Lerr;
11500 + }
11501 + u2 = s[i + 1];
11502 + if (u2 < 0xDC00 || u2 > 0xDFFF)
11503 + { msg = "surrogate UTF-16 low value out of range";
11504 + goto Lerr;
11505 + }
11506 + u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);
11507 + i += 2;
11508 + }
11509 + else if (u >= 0xDC00 && u <= 0xDFFF)
11510 + { msg = "unpaired surrogate UTF-16 value";
11511 + goto Lerr;
11512 + }
11513 + else if (u == 0xFFFE || u == 0xFFFF)
11514 + { msg = "illegal UTF-16 value";
11515 + goto Lerr;
11516 + }
11517 + else
11518 + i++;
11519 + }
11520 + else
11521 + {
11522 + i++;
11523 + }
11524 +
11525 + idx = i;
11526 + return cast(dchar)u;
11527 +
11528 + Lerr:
11529 + onUnicodeError(msg, i);
11530 + return cast(dchar)u; // dummy return
11531 + }
11532 +
11533 +/** ditto */
11534 +
11535 +dchar decode(in dchar[] s, inout size_t idx)
11536 + in
11537 + {
11538 + assert(idx >= 0 && idx < s.length);
11539 + }
11540 + body
11541 + {
11542 + size_t i = idx;
11543 + dchar c = s[i];
11544 +
11545 + if (!isValidDchar(c))
11546 + goto Lerr;
11547 + idx = i + 1;
11548 + return c;
11549 +
11550 + Lerr:
11551 + onUnicodeError("invalid UTF-32 value", i);
11552 + return c; // dummy return
11553 + }
11554 +
11555 +
11556 +/* =================== Encode ======================= */
11557 +
11558 +/*******************************
11559 + * Encodes character c and appends it to array s[].
11560 + */
11561 +void encode(inout char[] s, dchar c)
11562 + in
11563 + {
11564 + assert(isValidDchar(c));
11565 + }
11566 + body
11567 + {
11568 + char[] r = s;
11569 +
11570 + if (c <= 0x7F)
11571 + {
11572 + r ~= cast(char) c;
11573 + }
11574 + else
11575 + {
11576 + char[4] buf;
11577 + uint L;
11578 +
11579 + if (c <= 0x7FF)
11580 + {
11581 + buf[0] = cast(char)(0xC0 | (c >> 6));
11582 + buf[1] = cast(char)(0x80 | (c & 0x3F));
11583 + L = 2;
11584 + }
11585 + else if (c <= 0xFFFF)
11586 + {
11587 + buf[0] = cast(char)(0xE0 | (c >> 12));
11588 + buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
11589 + buf[2] = cast(char)(0x80 | (c & 0x3F));
11590 + L = 3;
11591 + }
11592 + else if (c <= 0x10FFFF)
11593 + {
11594 + buf[0] = cast(char)(0xF0 | (c >> 18));
11595 + buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
11596 + buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
11597 + buf[3] = cast(char)(0x80 | (c & 0x3F));
11598 + L = 4;
11599 + }
11600 + else
11601 + {
11602 + assert(0);
11603 + }
11604 + r ~= buf[0 .. L];
11605 + }
11606 + s = r;
11607 + }
11608 +
11609 +unittest
11610 +{
11611 + debug(utf) printf("utf.encode.unittest\n");
11612 +
11613 + char[] s = "abcd".dup;
11614 + encode(s, cast(dchar)'a');
11615 + assert(s.length == 5);
11616 + assert(s == "abcda");
11617 +
11618 + encode(s, cast(dchar)'\u00A9');
11619 + assert(s.length == 7);
11620 + assert(s == "abcda\xC2\xA9");
11621 + //assert(s == "abcda\u00A9"); // BUG: fix compiler
11622 +
11623 + encode(s, cast(dchar)'\u2260');
11624 + assert(s.length == 10);
11625 + assert(s == "abcda\xC2\xA9\xE2\x89\xA0");
11626 +}
11627 +
11628 +/** ditto */
11629 +
11630 +void encode(inout wchar[] s, dchar c)
11631 + in
11632 + {
11633 + assert(isValidDchar(c));
11634 + }
11635 + body
11636 + {
11637 + wchar[] r = s;
11638 +
11639 + if (c <= 0xFFFF)
11640 + {
11641 + r ~= cast(wchar) c;
11642 + }
11643 + else
11644 + {
11645 + wchar[2] buf;
11646 +
11647 + buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
11648 + buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);
11649 + r ~= buf;
11650 + }
11651 + s = r;
11652 + }
11653 +
11654 +/** ditto */
11655 +void encode(inout dchar[] s, dchar c)
11656 + in
11657 + {
11658 + assert(isValidDchar(c));
11659 + }
11660 + body
11661 + {
11662 + s ~= c;
11663 + }
11664 +
11665 +/**
11666 +Returns the code length of $(D c) in the encoding using $(D C) as a
11667 +code point. The code is returned in character count, not in bytes.
11668 + */
11669 +
11670 +ubyte codeLength(C)(dchar c)
11671 +{
11672 +
11673 + static if (C.sizeof == 1)
11674 + {
11675 + return
11676 + c <= 0x7F ? 1
11677 + : c <= 0x7FF ? 2
11678 + : c <= 0xFFFF ? 3
11679 + : c <= 0x10FFFF ? 4
11680 + : (assert(false), 6);
11681 +}
11682 +
11683 + else static if (C.sizeof == 2)
11684 +{
11685 + return c <= 0xFFFF ? 1 : 2;
11686 + }
11687 + else
11688 + {
11689 + static assert(C.sizeof == 4);
11690 + return 1;
11691 + }
11692 +}
11693 +
11694 +/* =================== Validation ======================= */
11695 +
11696 +/***********************************
11697 +Checks to see if string is well formed or not. $(D S) can be an array
11698 + of $(D char), $(D wchar), or $(D dchar). Throws a $(D UtfException)
11699 + if it is not. Use to check all untrusted input for correctness.
11700 + */
11701 +void validate(S)(in S s)
11702 +{
11703 + auto len = s.length;
11704 + for (size_t i = 0; i < len; )
11705 + {
11706 + decode(s, i);
11707 + }
11708 +}
11709 +
11710 +/* =================== Conversion to UTF8 ======================= */
11711 +
11712 +char[] toUTF8(char[4] buf, dchar c)
11713 + in
11714 + {
11715 + assert(isValidDchar(c));
11716 + }
11717 + body
11718 + {
11719 + if (c <= 0x7F)
11720 + {
11721 + buf[0] = cast(char) c;
11722 + return buf[0 .. 1];
11723 + }
11724 + else if (c <= 0x7FF)
11725 + {
11726 + buf[0] = cast(char)(0xC0 | (c >> 6));
11727 + buf[1] = cast(char)(0x80 | (c & 0x3F));
11728 + return buf[0 .. 2];
11729 + }
11730 + else if (c <= 0xFFFF)
11731 + {
11732 + buf[0] = cast(char)(0xE0 | (c >> 12));
11733 + buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
11734 + buf[2] = cast(char)(0x80 | (c & 0x3F));
11735 + return buf[0 .. 3];
11736 + }
11737 + else if (c <= 0x10FFFF)
11738 + {
11739 + buf[0] = cast(char)(0xF0 | (c >> 18));
11740 + buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
11741 + buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
11742 + buf[3] = cast(char)(0x80 | (c & 0x3F));
11743 + return buf[0 .. 4];
11744 + }
11745 + assert(0);
11746 + }
11747 +
11748 +/*******************
11749 + * Encodes string s into UTF-8 and returns the encoded string.
11750 + */
11751 +string toUTF8(string s)
11752 + in
11753 + {
11754 + validate(s);
11755 + }
11756 + body
11757 + {
11758 + return s;
11759 + }
11760 +
11761 +/** ditto */
11762 +string toUTF8(in wchar[] s)
11763 +{
11764 + char[] r;
11765 + size_t i;
11766 + size_t slen = s.length;
11767 +
11768 + r.length = slen;
11769 +
11770 + for (i = 0; i < slen; i++)
11771 + { wchar c = s[i];
11772 +
11773 + if (c <= 0x7F)
11774 + r[i] = cast(char)c; // fast path for ascii
11775 + else
11776 + {
11777 + r.length = i;
11778 + foreach (dchar c; s[i .. slen])
11779 + {
11780 + encode(r, c);
11781 + }
11782 + break;
11783 + }
11784 + }
11785 + return cast(string)r;
11786 +}
11787 +
11788 +/** ditto */
11789 +string toUTF8(in dchar[] s)
11790 +{
11791 + char[] r;
11792 + size_t i;
11793 + size_t slen = s.length;
11794 +
11795 + r.length = slen;
11796 +
11797 + for (i = 0; i < slen; i++)
11798 + { dchar c = s[i];
11799 +
11800 + if (c <= 0x7F)
11801 + r[i] = cast(char)c; // fast path for ascii
11802 + else
11803 + {
11804 + r.length = i;
11805 + foreach (dchar d; s[i .. slen])
11806 + {
11807 + encode(r, d);
11808 + }
11809 + break;
11810 + }
11811 + }
11812 + return cast(string)r;
11813 +}
11814 +
11815 +/* =================== Conversion to UTF16 ======================= */
11816 +
11817 +wchar[] toUTF16(wchar[2] buf, dchar c)
11818 + in
11819 + {
11820 + assert(isValidDchar(c));
11821 + }
11822 + body
11823 + {
11824 + if (c <= 0xFFFF)
11825 + {
11826 + buf[0] = cast(wchar) c;
11827 + return buf[0 .. 1];
11828 + }
11829 + else
11830 + {
11831 + buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
11832 + buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);
11833 + return buf[0 .. 2];
11834 + }
11835 + }
11836 +
11837 +/****************
11838 + * Encodes string s into UTF-16 and returns the encoded string.
11839 + * toUTF16z() is suitable for calling the 'W' functions in the Win32 API that take
11840 + * an LPWSTR or LPCWSTR argument.
11841 + */
11842 +wstring toUTF16(in char[] s)
11843 +{
11844 + wchar[] r;
11845 + size_t slen = s.length;
11846 +
11847 + r.length = slen;
11848 + r.length = 0;
11849 + for (size_t i = 0; i < slen; )
11850 + {
11851 + dchar c = s[i];
11852 + if (c <= 0x7F)
11853 + {
11854 + i++;
11855 + r ~= cast(wchar)c;
11856 + }
11857 + else
11858 + {
11859 + c = decode(s, i);
11860 + encode(r, c);
11861 + }
11862 + }
11863 + return cast(wstring)r;
11864 +}
11865 +
11866 +alias const(wchar)* wptr;
11867 +/** ditto */
11868 +wptr toUTF16z(in char[] s)
11869 +{
11870 + wchar[] r;
11871 + size_t slen = s.length;
11872 +
11873 + r.length = slen + 1;
11874 + r.length = 0;
11875 + for (size_t i = 0; i < slen; )
11876 + {
11877 + dchar c = s[i];
11878 + if (c <= 0x7F)
11879 + {
11880 + i++;
11881 + r ~= cast(wchar)c;
11882 + }
11883 + else
11884 + {
11885 + c = decode(s, i);
11886 + encode(r, c);
11887 + }
11888 + }
11889 + r ~= "\000";
11890 + return r.ptr;
11891 +}
11892 +
11893 +/** ditto */
11894 +wstring toUTF16(wstring s)
11895 + in
11896 + {
11897 + validate(s);
11898 + }
11899 + body
11900 + {
11901 + return s;
11902 + }
11903 +
11904 +/** ditto */
11905 +wstring toUTF16(in dchar[] s)
11906 +{
11907 + wchar[] r;
11908 + size_t slen = s.length;
11909 +
11910 + r.length = slen;
11911 + r.length = 0;
11912 + for (size_t i = 0; i < slen; i++)
11913 + {
11914 + encode(r, s[i]);
11915 + }
11916 + return cast(wstring)r;
11917 +}
11918 +
11919 +/* =================== Conversion to UTF32 ======================= */
11920 +
11921 +/*****
11922 + * Encodes string s into UTF-32 and returns the encoded string.
11923 + */
11924 +dstring toUTF32(in char[] s)
11925 +{
11926 + dchar[] r;
11927 + size_t slen = s.length;
11928 + size_t j = 0;
11929 +
11930 + r.length = slen; // r[] will never be longer than s[]
11931 + for (size_t i = 0; i < slen; )
11932 + {
11933 + dchar c = s[i];
11934 + if (c >= 0x80)
11935 + c = decode(s, i);
11936 + else
11937 + i++; // c is ascii, no need for decode
11938 + r[j++] = c;
11939 + }
11940 + return cast(dstring)r[0 .. j];
11941 +}
11942 +
11943 +/** ditto */
11944 +dstring toUTF32(in wchar[] s)
11945 +{
11946 + dchar[] r;
11947 + size_t slen = s.length;
11948 + size_t j = 0;
11949 +
11950 + r.length = slen; // r[] will never be longer than s[]
11951 + for (size_t i = 0; i < slen; )
11952 + {
11953 + dchar c = s[i];
11954 + if (c >= 0x80)
11955 + c = decode(s, i);
11956 + else
11957 + i++; // c is ascii, no need for decode
11958 + r[j++] = c;
11959 + }
11960 + return cast(dstring)r[0 .. j];
11961 +}
11962 +
11963 +/** ditto */
11964 +dstring toUTF32(dstring s)
11965 + in
11966 + {
11967 + validate(s);
11968 + }
11969 + body
11970 + {
11971 + return s;
11972 + }
11973 +
11974 +/* ================================ tests ================================== */
11975 +
11976 +unittest
11977 +{
11978 + debug(utf) printf("utf.toUTF.unittest\n");
11979 +
11980 + auto c = "hello"c;
11981 + auto w = toUTF16(c);
11982 + assert(w == "hello");
11983 + auto d = toUTF32(c);
11984 + assert(d == "hello");
11985 +
11986 + c = toUTF8(w);
11987 + assert(c == "hello");
11988 + d = toUTF32(w);
11989 + assert(d == "hello");
11990 +
11991 + c = toUTF8(d);
11992 + assert(c == "hello");
11993 + w = toUTF16(d);
11994 + assert(w == "hello");
11995 +
11996 +
11997 + c = "hel\u1234o";
11998 + w = toUTF16(c);
11999 + assert(w == "hel\u1234o");
12000 + d = toUTF32(c);
12001 + assert(d == "hel\u1234o");
12002 +
12003 + c = toUTF8(w);
12004 + assert(c == "hel\u1234o");
12005 + d = toUTF32(w);
12006 + assert(d == "hel\u1234o");
12007 +
12008 + c = toUTF8(d);
12009 + assert(c == "hel\u1234o");
12010 + w = toUTF16(d);
12011 + assert(w == "hel\u1234o");
12012 +
12013 +
12014 + c = "he\U0010AAAAllo";
12015 + w = toUTF16(c);
12016 + //foreach (wchar c; w) printf("c = x%x\n", c);
12017 + //foreach (wchar c; cast(wstring)"he\U0010AAAAllo") printf("c = x%x\n", c);
12018 + assert(w == "he\U0010AAAAllo");
12019 + d = toUTF32(c);
12020 + assert(d == "he\U0010AAAAllo");
12021 +
12022 + c = toUTF8(w);
12023 + assert(c == "he\U0010AAAAllo");
12024 + d = toUTF32(w);
12025 + assert(d == "he\U0010AAAAllo");
12026 +
12027 + c = toUTF8(d);
12028 + assert(c == "he\U0010AAAAllo");
12029 + w = toUTF16(d);
12030 + assert(w == "he\U0010AAAAllo");
12031 +}
12032 Index: src/compiler/ldc/util/console.d
12033 ===================================================================
12034 --- src/compiler/ldc/util/console.d (revision 0)
12035 +++ src/compiler/ldc/util/console.d (revision 0)
12036 @@ -0,0 +1,49 @@
12037 +/**
12038 + * The console module contains some simple routines for console output.
12039 + *
12040 + * Copyright: Public Domain
12041 + * License: Public Domain
12042 + * Authors: Sean Kelly
12043 + */
12044 +module rt.util.console;
12045 +
12046 +
12047 +private
12048 +{
12049 + version (Windows)
12050 + {
12051 + import core.sys.windows.windows;
12052 + }
12053 + else version( Posix )
12054 + {
12055 + import core.sys.posix.unistd;
12056 + }
12057 + import util.string;
12058 +}
12059 +
12060 +
12061 +struct Console
12062 +{
12063 + Console opCall( in char[] val )
12064 + {
12065 + version( Windows )
12066 + {
12067 + uint count = void;
12068 + WriteFile( GetStdHandle( 0xfffffff5 ), val.ptr, val.length, &count, null );
12069 + }
12070 + else version( Posix )
12071 + {
12072 + write( 2, val.ptr, val.length );
12073 + }
12074 + return *this;
12075 + }
12076 +
12077 +
12078 + Console opCall( uint val )
12079 + {
12080 + char[10] tmp = void;
12081 + return opCall( tmp.intToString( val ) );
12082 + }
12083 +}
12084 +
12085 +Console console;
12086 Index: src/compiler/ldc/util/ctype.d
12087 ===================================================================
12088 --- src/compiler/ldc/util/ctype.d (revision 0)
12089 +++ src/compiler/ldc/util/ctype.d (revision 0)
12090 @@ -0,0 +1,106 @@
12091 +
12092 +/*
12093 + * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
12094 + * Written by Walter Bright
12095 + *
12096 + * This software is provided 'as-is', without any express or implied
12097 + * warranty. In no event will the authors be held liable for any damages
12098 + * arising from the use of this software.
12099 + *
12100 + * Permission is granted to anyone to use this software for any purpose,
12101 + * including commercial applications, and to alter it and redistribute it
12102 + * freely, in both source and binary form, subject to the following
12103 + * restrictions:
12104 + *
12105 + * o The origin of this software must not be misrepresented; you must not
12106 + * claim that you wrote the original software. If you use this software
12107 + * in a product, an acknowledgment in the product documentation would be
12108 + * appreciated but is not required.
12109 + * o Altered source versions must be plainly marked as such, and must not
12110 + * be misrepresented as being the original software.
12111 + * o This notice may not be removed or altered from any source
12112 + * distribution.
12113 + */
12114 +
12115 +// Simple ASCII char classification functions
12116 +
12117 +module rt.util.ctype;
12118 +
12119 +int isalnum(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG) : 0; }
12120 +int isalpha(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP) : 0; }
12121 +int iscntrl(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_CTL) : 0; }
12122 +int isdigit(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_DIG) : 0; }
12123 +int islower(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_LC) : 0; }
12124 +int ispunct(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_PNC) : 0; }
12125 +int isspace(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_SPC) : 0; }
12126 +int isupper(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_UC) : 0; }
12127 +int isxdigit(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_HEX) : 0; }
12128 +int isgraph(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG|_PNC) : 0; }
12129 +int isprint(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG|_PNC|_BLK) : 0; }
12130 +int isascii(dchar c) { return c <= 0x7F; }
12131 +
12132 +dchar tolower(dchar c)
12133 + out (result)
12134 + {
12135 + assert(!isupper(result));
12136 + }
12137 + body
12138 + {
12139 + return isupper(c) ? c + (cast(dchar)'a' - 'A') : c;
12140 + }
12141 +
12142 +dchar toupper(dchar c)
12143 + out (result)
12144 + {
12145 + assert(!islower(result));
12146 + }
12147 + body
12148 + {
12149 + return islower(c) ? c - (cast(dchar)'a' - 'A') : c;
12150 + }
12151 +
12152 +private:
12153 +
12154 +enum
12155 +{
12156 + _SPC = 8,
12157 + _CTL = 0x20,
12158 + _BLK = 0x40,
12159 + _HEX = 0x80,
12160 + _UC = 1,
12161 + _LC = 2,
12162 + _PNC = 0x10,
12163 + _DIG = 4,
12164 + _ALP = _UC|_LC,
12165 +}
12166 +
12167 +ubyte _ctype[128] =
12168 +[
12169 + _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
12170 + _CTL,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL,_CTL,
12171 + _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
12172 + _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
12173 + _SPC|_BLK,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
12174 + _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
12175 + _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,
12176 + _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,
12177 + _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
12178 + _PNC,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC,
12179 + _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,
12180 + _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,
12181 + _UC,_UC,_UC,_PNC,_PNC,_PNC,_PNC,_PNC,
12182 + _PNC,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC,
12183 + _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC,
12184 + _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC,
12185 + _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL
12186 +];
12187 +
12188 +
12189 +unittest
12190 +{
12191 + assert(isspace(' '));
12192 + assert(!isspace('z'));
12193 + assert(toupper('a') == 'A');
12194 + assert(tolower('Q') == 'q');
12195 + assert(!isxdigit('G'));
12196 +}
12197 Index: src/compiler/ldc/util/string.d
12198 ===================================================================
12199 --- src/compiler/ldc/util/string.d (revision 0)
12200 +++ src/compiler/ldc/util/string.d (revision 0)
12201 @@ -0,0 +1,35 @@
12202 +/**
12203 + * The exception module defines all system-level exceptions and provides a
12204 + * mechanism to alter system-level error handling.
12205 + *
12206 + * Copyright: Copyright (c) 2005-2008, The D Runtime Project
12207 + * License: BSD Style, see LICENSE
12208 + * Authors: Sean Kelly
12209 + */
12210 +module rt.util.string;
12211 +
12212 +private import core.stdc.string;
12213 +
12214 +char[] intToString( char[] buf, uint val )
12215 +{
12216 + assert( buf.length > 9 );
12217 + auto p = buf.ptr + buf.length;
12218 +
12219 + do
12220 + {
12221 + *--p = cast(char)(val % 10 + '0');
12222 + } while( val /= 10 );
12223 +
12224 + return buf[p - buf.ptr .. $];
12225 +}
12226 +
12227 +
12228 +int dstrcmp( in char[] s1, in char[] s2 )
12229 +{
12230 + auto len = s1.length;
12231 + if( s2.length < len )
12232 + len = s2.length;
12233 + if( memcmp( s1.ptr, s2.ptr, len ) == 0 )
12234 + return 0;
12235 + return s1.length > s2.length ? 1 : -1;
12236 +}
12237 Index: src/compiler/ldc/invariant.d
12238 ===================================================================
12239 --- src/compiler/ldc/invariant.d (revision 0)
12240 +++ src/compiler/ldc/invariant.d (revision 0)
12241 @@ -0,0 +1,25 @@
12242 +
12243 +/*
12244 + * Placed into the Public Domain
12245 + * written by Walter Bright
12246 + * www.digitalmars.com
12247 + */
12248 +
12249 +extern(C) void _d_invariant(Object o)
12250 +{ ClassInfo c;
12251 +
12252 + //printf("__d_invariant(%p)\n", o);
12253 +
12254 + // BUG: needs to be filename/line of caller, not library routine
12255 + assert(o !is null); // just do null check, not invariant check
12256 +
12257 + c = o.classinfo;
12258 + do
12259 + {
12260 + if (c.classInvariant)
12261 + {
12262 + (*c.classInvariant)(o);
12263 + }
12264 + c = c.base;
12265 + } while (c);
12266 +}
12267 Index: src/compiler/ldc/eh.d
12268 ===================================================================
12269 --- src/compiler/ldc/eh.d (revision 0)
12270 +++ src/compiler/ldc/eh.d (revision 0)
12271 @@ -0,0 +1,388 @@
12272 +/**
12273 + * This module contains functions and structures required for
12274 + * exception handling.
12275 + */
12276 +module eh;
12277 +
12278 +import util.console;
12279 +import ldc.cstdarg;
12280 +
12281 +// debug = EH_personality;
12282 +
12283 +// current EH implementation works on x86
12284 +// if it has a working unwind runtime
12285 +version(X86) {
12286 + version(linux) version=X86_UNWIND;
12287 + version(darwin) version=X86_UNWIND;
12288 +}
12289 +version(X86_64) {
12290 + version(linux) version=X86_UNWIND;
12291 +}
12292 +
12293 +private extern(C) void abort();
12294 +private extern(C) int printf(in char*, ...);
12295 +private extern(C) int vprintf(in char*, va_list va);
12296 +
12297 +// D runtime functions
12298 +extern(C) {
12299 + int _d_isbaseof(ClassInfo oc, ClassInfo c);
12300 +}
12301 +
12302 +// libunwind headers
12303 +extern(C)
12304 +{
12305 + enum _Unwind_Reason_Code
12306 + {
12307 + NO_REASON = 0,
12308 + FOREIGN_EXCEPTION_CAUGHT = 1,
12309 + FATAL_PHASE2_ERROR = 2,
12310 + FATAL_PHASE1_ERROR = 3,
12311 + NORMAL_STOP = 4,
12312 + END_OF_STACK = 5,
12313 + HANDLER_FOUND = 6,
12314 + INSTALL_CONTEXT = 7,
12315 + CONTINUE_UNWIND = 8
12316 + }
12317 +
12318 + enum _Unwind_Action
12319 + {
12320 + SEARCH_PHASE = 1,
12321 + CLEANUP_PHASE = 2,
12322 + HANDLER_PHASE = 3,
12323 + FORCE_UNWIND = 4
12324 + }
12325 +
12326 + alias void* _Unwind_Context_Ptr;
12327 +
12328 + alias void function(_Unwind_Reason_Code, _Unwind_Exception*) _Unwind_Exception_Cleanup_Fn;
12329 +
12330 + struct _Unwind_Exception
12331 + {
12332 + char[8] exception_class;
12333 + _Unwind_Exception_Cleanup_Fn exception_cleanup;
12334 + int private_1;
12335 + int private_2;
12336 + }
12337 +
12338 +version(X86_UNWIND)
12339 +{
12340 + void _Unwind_Resume(_Unwind_Exception*);
12341 + _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*);
12342 + ulong _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context);
12343 + ulong _Unwind_GetIP(_Unwind_Context_Ptr context);
12344 + ulong _Unwind_SetIP(_Unwind_Context_Ptr context, ulong new_value);
12345 + ulong _Unwind_SetGR(_Unwind_Context_Ptr context, int index, ulong new_value);
12346 + ulong _Unwind_GetRegionStart(_Unwind_Context_Ptr context);
12347 +}
12348 +else
12349 +{
12350 + // runtime calls these directly
12351 + void _Unwind_Resume(_Unwind_Exception*)
12352 + {
12353 + console("_Unwind_Resume is not implemented on this platform.\n");
12354 + }
12355 + _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*)
12356 + {
12357 + console("_Unwind_RaiseException is not implemented on this platform.\n");
12358 + return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
12359 + }
12360 +}
12361 +
12362 +}
12363 +
12364 +// error and exit
12365 +extern(C) private void fatalerror(in char* format, ...)
12366 +{
12367 + va_list args;
12368 + va_start(args, format);
12369 + printf("Fatal error in EH code: ");
12370 + vprintf(format, args);
12371 + printf("\n");
12372 + abort();
12373 +}
12374 +
12375 +
12376 +// helpers for reading certain DWARF data
12377 +private ubyte* get_uleb128(ubyte* addr, ref size_t res)
12378 +{
12379 + res = 0;
12380 + size_t bitsize = 0;
12381 +
12382 + // read as long as high bit is set
12383 + while(*addr & 0x80) {
12384 + res |= (*addr & 0x7f) << bitsize;
12385 + bitsize += 7;
12386 + addr += 1;
12387 + if(bitsize >= size_t.sizeof*8)
12388 + fatalerror("tried to read uleb128 that exceeded size of size_t");
12389 + }
12390 + // read last
12391 + if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize)
12392 + fatalerror("Fatal error in EH code: tried to read uleb128 that exceeded size of size_t");
12393 + res |= (*addr) << bitsize;
12394 +
12395 + return addr + 1;
12396 +}
12397 +
12398 +private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res)
12399 +{
12400 + res = 0;
12401 + size_t bitsize = 0;
12402 +
12403 + // read as long as high bit is set
12404 + while(*addr & 0x80) {
12405 + res |= (*addr & 0x7f) << bitsize;
12406 + bitsize += 7;
12407 + addr += 1;
12408 + if(bitsize >= size_t.sizeof*8)
12409 + fatalerror("tried to read sleb128 that exceeded size of size_t");
12410 + }
12411 + // read last
12412 + if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize)
12413 + fatalerror("tried to read sleb128 that exceeded size of size_t");
12414 + res |= (*addr) << bitsize;
12415 +
12416 + // take care of sign
12417 + if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40))
12418 + res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1);
12419 +
12420 + return addr + 1;
12421 +}
12422 +
12423 +
12424 +// exception struct used by the runtime.
12425 +// _d_throw allocates a new instance and passes the address of its
12426 +// _Unwind_Exception member to the unwind call. The personality
12427 +// routine is then able to get the whole struct by looking at the data
12428 +// surrounding the unwind info.
12429 +struct _d_exception
12430 +{
12431 + Object exception_object;
12432 + _Unwind_Exception unwind_info;
12433 +}
12434 +
12435 +// the 8-byte string identifying the type of exception
12436 +// the first 4 are for vendor, the second 4 for language
12437 +//TODO: This may be the wrong way around
12438 +char[8] _d_exception_class = "LLDCD1\0\0";
12439 +
12440 +
12441 +//
12442 +// x86 unwind specific implementation of personality function
12443 +// and helpers
12444 +//
12445 +version(X86_UNWIND)
12446 +{
12447 +
12448 +// the personality routine gets called by the unwind handler and is responsible for
12449 +// reading the EH tables and deciding what to do
12450 +extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context)
12451 +{
12452 + // check ver: the C++ Itanium ABI only allows ver == 1
12453 + if(ver != 1)
12454 + return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
12455 +
12456 + // check exceptionClass
12457 + //TODO: Treat foreign exceptions with more respect
12458 + if((cast(char*)&exception_class)[0..8] != _d_exception_class)
12459 + return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
12460 +
12461 + // find call site table, action table and classinfo table
12462 + // Note: callsite and action tables do not contain static-length
12463 + // data and will be parsed as needed
12464 + // Note: classinfo_table points past the end of the table
12465 + ubyte* callsite_table;
12466 + ubyte* action_table;
12467 + ClassInfo* classinfo_table;
12468 + _d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table);
12469 +
12470 +
12471 + /*
12472 + find landing pad and action table index belonging to ip by walking
12473 + the callsite_table
12474 + */
12475 + ubyte* callsite_walker = callsite_table;
12476 +
12477 + // get the instruction pointer
12478 + // will be used to find the right entry in the callsite_table
12479 + // -1 because it will point past the last instruction
12480 + ulong ip = _Unwind_GetIP(context) - 1;
12481 +
12482 + // address block_start is relative to
12483 + ulong region_start = _Unwind_GetRegionStart(context);
12484 +
12485 + // table entries
12486 + uint block_start_offset, block_size;
12487 + ulong landing_pad;
12488 + size_t action_offset;
12489 +
12490 + while(true) {
12491 + // if we've gone through the list and found nothing...
12492 + if(callsite_walker >= action_table)
12493 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12494 +
12495 + block_start_offset = *cast(uint*)callsite_walker;
12496 + block_size = *(cast(uint*)callsite_walker + 1);
12497 + landing_pad = *(cast(uint*)callsite_walker + 2);
12498 + if(landing_pad)
12499 + landing_pad += region_start;
12500 + callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset);
12501 +
12502 + debug(EH_personality_verbose) printf("%d %d %d\n", block_start_offset, block_size, landing_pad);
12503 +
12504 + // since the list is sorted, as soon as we're past the ip
12505 + // there's no handler to be found
12506 + if(ip < region_start + block_start_offset)
12507 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12508 +
12509 + // if we've found our block, exit
12510 + if(ip < region_start + block_start_offset + block_size)
12511 + break;
12512 + }
12513 +
12514 + debug(EH_personality) printf("Found correct landing pad and actionOffset %d\n", action_offset);
12515 +
12516 + // now we need the exception's classinfo to find a handler
12517 + // the exception_info is actually a member of a larger _d_exception struct
12518 + // the runtime allocated. get that now
12519 + _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - _d_exception.unwind_info.offsetof);
12520 +
12521 + // if there's no action offset and no landing pad, continue unwinding
12522 + if(!action_offset && !landing_pad)
12523 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12524 +
12525 + // if there's no action offset but a landing pad, this is a cleanup handler
12526 + else if(!action_offset && landing_pad)
12527 + return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context);
12528 +
12529 + /*
12530 + walk action table chain, comparing classinfos using _d_isbaseof
12531 + */
12532 + ubyte* action_walker = action_table + action_offset - 1;
12533 +
12534 + ptrdiff_t ti_offset, next_action_offset;
12535 + while(true) {
12536 + action_walker = get_sleb128(action_walker, ti_offset);
12537 + // it is intentional that we not modify action_walker here
12538 + // next_action_offset is from current action_walker position
12539 + get_sleb128(action_walker, next_action_offset);
12540 +
12541 + // negative are 'filters' which we don't use
12542 + if(!(ti_offset >= 0))
12543 + fatalerror("Filter actions are unsupported");
12544 +
12545 + // zero means cleanup, which we require to be the last action
12546 + if(ti_offset == 0) {
12547 + if(!(next_action_offset == 0))
12548 + fatalerror("Cleanup action must be last in chain");
12549 + return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context);
12550 + }
12551 +
12552 + // get classinfo for action and check if the one in the
12553 + // exception structure is a base
12554 + ClassInfo catch_ci = classinfo_table[-ti_offset];
12555 + debug(EH_personality) printf("Comparing catch %s to exception %s\n", catch_ci.name.ptr, exception_struct.exception_object.classinfo.name.ptr);
12556 + if(_d_isbaseof(exception_struct.exception_object.classinfo, catch_ci))
12557 + return _d_eh_install_catch_context(actions, ti_offset, landing_pad, exception_struct, context);
12558 +
12559 + // we've walked through all actions and found nothing...
12560 + if(next_action_offset == 0)
12561 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12562 + else
12563 + action_walker += next_action_offset;
12564 + }
12565 +
12566 + fatalerror("reached unreachable");
12567 + return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
12568 +}
12569 +
12570 +// These are the register numbers for SetGR that
12571 +// llvm's eh.exception and eh.selector intrinsics
12572 +// will pick up.
12573 +// Found by trial-and-error :/
12574 +version (X86_64)
12575 +{
12576 + private int eh_exception_regno = 3;
12577 + private int eh_selector_regno = 1;
12578 +} else {
12579 + private int eh_exception_regno = 0;
12580 + private int eh_selector_regno = 2;
12581 +}
12582 +
12583 +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)
12584 +{
12585 + debug(EH_personality) printf("Found catch clause!\n");
12586 +
12587 + if(actions & _Unwind_Action.SEARCH_PHASE)
12588 + return _Unwind_Reason_Code.HANDLER_FOUND;
12589 +
12590 + else if(actions & _Unwind_Action.HANDLER_PHASE)
12591 + {
12592 + debug(EH_personality) printf("Setting switch value to: %d!\n", switchval);
12593 + _Unwind_SetGR(context, eh_exception_regno, cast(ulong)cast(void*)(exception_struct.exception_object));
12594 + _Unwind_SetGR(context, eh_selector_regno, switchval);
12595 + _Unwind_SetIP(context, landing_pad);
12596 + return _Unwind_Reason_Code.INSTALL_CONTEXT;
12597 + }
12598 +
12599 + fatalerror("reached unreachable");
12600 + return _Unwind_Reason_Code.FATAL_PHASE2_ERROR;
12601 +}
12602 +
12603 +private _Unwind_Reason_Code _d_eh_install_finally_context(_Unwind_Action actions, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
12604 +{
12605 + // if we're merely in search phase, continue
12606 + if(actions & _Unwind_Action.SEARCH_PHASE)
12607 + return _Unwind_Reason_Code.CONTINUE_UNWIND;
12608 +
12609 + debug(EH_personality) printf("Calling cleanup routine...\n");
12610 +
12611 + _Unwind_SetGR(context, eh_exception_regno, cast(ulong)exception_struct);
12612 + _Unwind_SetGR(context, eh_selector_regno, 0);
12613 + _Unwind_SetIP(context, landing_pad);
12614 + return _Unwind_Reason_Code.INSTALL_CONTEXT;
12615 +}
12616 +
12617 +private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci)
12618 +{
12619 + ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context);
12620 +
12621 + //TODO: Do proper DWARF reading here
12622 + if(*data++ != 0xff)
12623 + fatalerror("DWARF header has unexpected format 1");
12624 +
12625 + if(*data++ != 0x00)
12626 + fatalerror("DWARF header has unexpected format 2");
12627 + size_t cioffset;
12628 + data = get_uleb128(data, cioffset);
12629 + ci = cast(ClassInfo*)(data + cioffset);
12630 +
12631 + if(*data++ != 0x03)
12632 + fatalerror("DWARF header has unexpected format 3");
12633 + size_t callsitelength;
12634 + data = get_uleb128(data, callsitelength);
12635 + action = data + callsitelength;
12636 +
12637 + callsite = data;
12638 +}
12639 +
12640 +} // end of x86 Linux specific implementation
12641 +
12642 +
12643 +extern(C) void _d_throw_exception(Object e)
12644 +{
12645 + if (e !is null)
12646 + {
12647 + _d_exception* exc_struct = new _d_exception;
12648 + exc_struct.unwind_info.exception_class[] = _d_exception_class;
12649 + exc_struct.exception_object = e;
12650 + _Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info);
12651 + console("_Unwind_RaiseException failed with reason code: ")(ret)("\n");
12652 + }
12653 + abort();
12654 +}
12655 +
12656 +extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct)
12657 +{
12658 + _Unwind_Resume(&exception_struct.unwind_info);
12659 +}
233 Index: import/object.di 12660 Index: import/object.di
234 =================================================================== 12661 ===================================================================
235 --- import/object.di (revision 46) 12662 --- import/object.di (revision 46)
236 +++ import/object.di (working copy) 12663 +++ import/object.di (working copy)
237 @@ -208,6 +208,13 @@ 12664 @@ -208,6 +208,13 @@
246 + } 12673 + }
247 + 12674 +
248 static int opApply(int delegate(inout ModuleInfo)); 12675 static int opApply(int delegate(inout ModuleInfo));
249 } 12676 }
250 12677
12678 Index: import/ldc/intrinsics.di
12679 ===================================================================
12680 --- import/ldc/intrinsics.di (revision 0)
12681 +++ import/ldc/intrinsics.di (revision 0)
12682 @@ -0,0 +1,343 @@
12683 +/*
12684 + * This module holds declarations to LLVM intrinsics.
12685 + *
12686 + * See the LLVM language reference for more information:
12687 + *
12688 + * - http://llvm.org/docs/LangRef.html#intrinsics
12689 + *
12690 + */
12691 +
12692 +module ldc.intrinsics;
12693 +
12694 +// Check for the right compiler
12695 +version(LDC)
12696 +{
12697 + // OK
12698 +}
12699 +else
12700 +{
12701 + static assert(false, "This module is only valid for LDC");
12702 +}
12703 +
12704 +//
12705 +// CODE GENERATOR INTRINSICS
12706 +//
12707 +
12708 +
12709 +// The 'llvm.returnaddress' intrinsic attempts to compute a target-specific value indicating the return address of the current function or one of its callers.
12710 +
12711 +pragma(intrinsic, "llvm.returnaddress")
12712 + void* llvm_returnaddress(uint level);
12713 +
12714 +
12715 +// The 'llvm.frameaddress' intrinsic attempts to return the target-specific frame pointer value for the specified stack frame.
12716 +
12717 +pragma(intrinsic, "llvm.frameaddress")
12718 + void* llvm_frameaddress(uint level);
12719 +
12720 +
12721 +// 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.
12722 +
12723 +pragma(intrinsic, "llvm.stacksave")
12724 + void* llvm_stacksave();
12725 +
12726 +
12727 +// 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.
12728 +
12729 +pragma(intrinsic, "llvm.stackrestore")
12730 + void llvm_stackrestore(void* ptr);
12731 +
12732 +
12733 +// 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.
12734 +
12735 +pragma(intrinsic, "llvm.prefetch")
12736 + void llvm_prefetch(void* ptr, uint rw, uint locality);
12737 +
12738 +
12739 +// 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.
12740 +
12741 +pragma(intrinsic, "llvm.pcmarker")
12742 + void llvm_pcmarker(uint id);
12743 +
12744 +
12745 +// 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.
12746 +
12747 +pragma(intrinsic, "llvm.readcyclecounter")
12748 + ulong readcyclecounter();
12749 +
12750 +
12751 +
12752 +
12753 +//
12754 +// STANDARD C LIBRARY INTRINSICS
12755 +//
12756 +
12757 +
12758 +// The 'llvm.memcpy.*' intrinsics copy a block of memory from the source location to the destination location.
12759 +// Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do not return a value, and takes an extra alignment argument.
12760 +
12761 +pragma(intrinsic, "llvm.memcpy.i32")
12762 + void llvm_memcpy_i32(void* dst, void* src, uint len, uint alignment);
12763 +pragma(intrinsic, "llvm.memcpy.i64")
12764 + void llvm_memcpy_i64(void* dst, void* src, ulong len, uint alignment);
12765 +
12766 +
12767 +// 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.
12768 +// Note that, unlike the standard libc function, the llvm.memmove.* intrinsics do not return a value, and takes an extra alignment argument.
12769 +
12770 +pragma(intrinsic, "llvm.memmove.i32")
12771 + void llvm_memmove_i32(void* dst, void* src, uint len, uint alignment);
12772 +pragma(intrinsic, "llvm.memmove.i64")
12773 + void llvm_memmove_i64(void* dst, void* src, ulong len, int alignment);
12774 +
12775 +
12776 +// The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte value.
12777 +// Note that, unlike the standard libc function, the llvm.memset intrinsic does not return a value, and takes an extra alignment argument.
12778 +
12779 +pragma(intrinsic, "llvm.memset.i32")
12780 + void llvm_memset_i32(void* dst, ubyte val, uint len, uint alignment);
12781 +pragma(intrinsic, "llvm.memset.i64")
12782 + void llvm_memset_i64(void* dst, ubyte val, ulong len, uint alignment);
12783 +
12784 +
12785 +// 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.
12786 +
12787 +pragma(intrinsic, "llvm.sqrt.f32")
12788 + float llvm_sqrt_f32(float val);
12789 +pragma(intrinsic, "llvm.sqrt.f64")
12790 + double llvm_sqrt_f64(double val);
12791 +version(X86)
12792 +{
12793 +pragma(intrinsic, "llvm.sqrt.f80")
12794 + real llvm_sqrt_f80(real val);
12795 +}
12796 +
12797 +version(X86_64)
12798 +{
12799 +pragma(intrinsic, "llvm.sqrt.f80")
12800 + real llvm_sqrt_f80(real val);
12801 +}
12802 +
12803 +
12804 +// The 'llvm.sin.*' intrinsics return the sine of the operand.
12805 +
12806 +pragma(intrinsic, "llvm.sin.f32")
12807 + float llvm_sin_f32(float val);
12808 +pragma(intrinsic, "llvm.sin.f64")
12809 + double llvm_sin_f64(double val);
12810 +version(X86)
12811 +{
12812 +pragma(intrinsic, "llvm.sin.f80")
12813 + real llvm_sin_f80(real val);
12814 +}
12815 +
12816 +version(X86_64)
12817 +{
12818 +pragma(intrinsic, "llvm.sin.f80")
12819 + real llvm_sin_f80(real val);
12820 +}
12821 +
12822 +
12823 +// The 'llvm.cos.*' intrinsics return the cosine of the operand.
12824 +
12825 +pragma(intrinsic, "llvm.cos.f32")
12826 + float llvm_cos_f32(float val);
12827 +pragma(intrinsic, "llvm.cos.f64")
12828 + double llvm_cos_f64(double val);
12829 +version(X86)
12830 +{
12831 +pragma(intrinsic, "llvm.cos.f80")
12832 + real llvm_cos_f80(real val);
12833 +}
12834 +
12835 +version(X86_64)
12836 +{
12837 +pragma(intrinsic, "llvm.cos.f80")
12838 + real llvm_cos_f80(real val);
12839 +}
12840 +
12841 +
12842 +// 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.
12843 +
12844 +pragma(intrinsic, "llvm.powi.f32")
12845 + float llvm_powi_f32(float val, int power);
12846 +
12847 +pragma(intrinsic, "llvm.powi.f64")
12848 + double llvm_powi_f64(double val, int power);
12849 +version(X86)
12850 +{
12851 +pragma(intrinsic, "llvm.powi.f80")
12852 + real llvm_powi_f80(real val, int power);
12853 +}
12854 +
12855 +version(X86_64)
12856 +{
12857 +pragma(intrinsic, "llvm.powi.f80")
12858 + real llvm_powi_f80(real val, int power);
12859 +}
12860 +
12861 +// The 'llvm.pow.*' intrinsics return the first operand raised to the specified (positive or negative) power.
12862 +
12863 +pragma(intrinsic, "llvm.pow.f32")
12864 + float llvm_pow_f32(float val, float power);
12865 +
12866 +pragma(intrinsic, "llvm.pow.f64")
12867 + double llvm_pow_f64(double val, double power);
12868 +version(X86)
12869 +{
12870 +pragma(intrinsic, "llvm.pow.f80")
12871 + real llvm_pow_f80(real val, real power);
12872 +}
12873 +
12874 +version(X86_64)
12875 +{
12876 +pragma(intrinsic, "llvm.pow.f80")
12877 + real llvm_pow_f80(real val, real power);
12878 +}
12879 +
12880 +
12881 +//
12882 +// BIT MANIPULATION INTRINSICS
12883 +//
12884 +
12885 +// 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.
12886 +
12887 +pragma(intrinsic, "llvm.bswap.i16.i16")
12888 + ushort llvm_bswap_i16(ushort val);
12889 +
12890 +pragma(intrinsic, "llvm.bswap.i32.i32")
12891 + uint llvm_bswap_i32(uint val);
12892 +
12893 +pragma(intrinsic, "llvm.bswap.i64.i64")
12894 + ulong llvm_bswap_i64(ulong val);
12895 +
12896 +
12897 +// The 'llvm.ctpop' family of intrinsics counts the number of bits set in a value.
12898 +
12899 +pragma(intrinsic, "llvm.ctpop.i8")
12900 + ubyte llvm_ctpop_i8(ubyte src);
12901 +
12902 +pragma(intrinsic, "llvm.ctpop.i16")
12903 + ushort llvm_ctpop_i16(ushort src);
12904 +
12905 +pragma(intrinsic, "llvm.ctpop.i32")
12906 + uint llvm_ctpop_i32(uint src);
12907 +
12908 +pragma(intrinsic, "llvm.ctpop.i64")
12909 + ulong llvm_ctpop_i64(ulong src);
12910 +
12911 +
12912 +// The 'llvm.ctlz' family of intrinsic functions counts the number of leading zeros in a variable.
12913 +
12914 +pragma(intrinsic, "llvm.ctlz.i8")
12915 + ubyte llvm_ctlz_i8(ubyte src);
12916 +
12917 +pragma(intrinsic, "llvm.ctlz.i16")
12918 + ushort llvm_ctlz_i16(ushort src);
12919 +
12920 +pragma(intrinsic, "llvm.ctlz.i32")
12921 + uint llvm_ctlz_i32(uint src);
12922 +
12923 +pragma(intrinsic, "llvm.ctlz.i64")
12924 + ulong llvm_ctlz_i64(ulong src);
12925 +
12926 +
12927 +// The 'llvm.cttz' family of intrinsic functions counts the number of trailing zeros.
12928 +
12929 +pragma(intrinsic, "llvm.cttz.i8")
12930 + ubyte llvm_cttz_i8(ubyte src);
12931 +
12932 +pragma(intrinsic, "llvm.cttz.i16")
12933 + ushort llvm_cttz_i16(ushort src);
12934 +
12935 +pragma(intrinsic, "llvm.cttz.i32")
12936 + uint llvm_cttz_i32(uint src);
12937 +
12938 +pragma(intrinsic, "llvm.cttz.i64")
12939 + ulong llvm_cttz_i64(ulong src);
12940 +
12941 +
12942 +// 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.
12943 +
12944 +pragma(intrinsic, "llvm.part.select.i8")
12945 + ubyte llvm_part_select_i(ubyte val, uint loBit, uint hiBit);
12946 +
12947 +pragma(intrinsic, "llvm.part.select.i16")
12948 + ushort llvm_part_select_i(ushort val, uint loBit, uint hiBit);
12949 +
12950 +pragma(intrinsic, "llvm.part.select.i32")
12951 + uint llvm_part_select_i(uint val, uint loBit, uint hiBit);
12952 +
12953 +pragma(intrinsic, "llvm.part.select.i64")
12954 + ulong llvm_part_select_i(ulong val, uint loBit, uint hiBit);
12955 +
12956 +
12957 +// 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.
12958 +
12959 +// TODO
12960 +// declare i17 @llvm.part.set.i17.i9 (i17 %val, i9 %repl, i32 %lo, i32 %hi)
12961 +// declare i29 @llvm.part.set.i29.i9 (i29 %val, i9 %repl, i32 %lo, i32 %hi)
12962 +
12963 +
12964 +
12965 +
12966 +//
12967 +// ATOMIC OPERATIONS AND SYNCHRONIZATION INTRINSICS
12968 +//
12969 +
12970 +// The llvm.memory.barrier intrinsic guarantees ordering between specific pairs of memory access types.
12971 +
12972 +pragma(intrinsic, "llvm.memory.barrier")
12973 + void llvm_memory_barrier(bool ll, bool ls, bool sl, bool ss, bool device);
12974 +
12975 +// 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.
12976 +
12977 +pragma(intrinsic, "llvm.atomic.cmp.swap.i#.p0i#")
12978 + T llvm_atomic_cmp_swap(T)(T* ptr, T cmp, T val);
12979 +
12980 +// 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.
12981 +
12982 +pragma(intrinsic, "llvm.atomic.swap.i#.p0i#")
12983 + T llvm_atomic_swap(T)(T* ptr, T val);
12984 +
12985 +// This intrinsic adds delta to the value stored in memory at ptr. It yields the original value at ptr.
12986 +
12987 +pragma(intrinsic, "llvm.atomic.load.add.i#.p0i#")
12988 + T llvm_atomic_load_add(T)(T* ptr, T val);
12989 +
12990 +// This intrinsic subtracts delta to the value stored in memory at ptr. It yields the original value at ptr.
12991 +
12992 +pragma(intrinsic, "llvm.atomic.load.sub.i#.p0i#")
12993 + T llvm_atomic_load_sub(T)(T* ptr, T val);
12994 +
12995 +// 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.
12996 +
12997 +pragma(intrinsic, "llvm.atomic.load.and.i#.p0i#")
12998 + T llvm_atomic_load_and(T)(T* ptr, T val);
12999 +pragma(intrinsic, "llvm.atomic.load.nand.i#.p0i#")
13000 + T llvm_atomic_load_nand(T)(T* ptr, T val);
13001 +pragma(intrinsic, "llvm.atomic.load.or.i#.p0i#")
13002 + T llvm_atomic_load_or(T)(T* ptr, T val);
13003 +pragma(intrinsic, "llvm.atomic.load.xor.i#.p0i#")
13004 + T llvm_atomic_load_xor(T)(T* ptr, T val);
13005 +
13006 +// 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.
13007 +
13008 +pragma(intrinsic, "llvm.atomic.load.max.i#.p0i#")
13009 + T llvm_atomic_load_max(T)(T* ptr, T val);
13010 +pragma(intrinsic, "llvm.atomic.load.min.i#.p0i#")
13011 + T llvm_atomic_load_min(T)(T* ptr, T val);
13012 +pragma(intrinsic, "llvm.atomic.load.umax.i#.p0i#")
13013 + T llvm_atomic_load_umax(T)(T* ptr, T val);
13014 +pragma(intrinsic, "llvm.atomic.load.umin.i#.p0i#")
13015 + T llvm_atomic_load_umin(T)(T* ptr, T val);
13016 +
13017 +//
13018 +// GENERAL INTRINSICS
13019 +//
13020 +
13021 +
13022 +// 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.
13023 +
13024 +pragma(intrinsic, "llvm.trap")
13025 + void llvm_trap();
13026 Index: import/ldc/cstdarg.di
13027 ===================================================================
13028 --- import/ldc/cstdarg.di (revision 0)
13029 +++ import/ldc/cstdarg.di (revision 0)
13030 @@ -0,0 +1,29 @@
13031 +/*
13032 + * vararg support for extern(C) functions
13033 + */
13034 +
13035 +module ldc.cstdarg;
13036 +
13037 +// Check for the right compiler
13038 +version(LDC)
13039 +{
13040 + // OK
13041 +}
13042 +else
13043 +{
13044 + static assert(false, "This module is only valid for LDC");
13045 +}
13046 +
13047 +alias void* va_list;
13048 +
13049 +pragma(va_start)
13050 + void va_start(T)(va_list ap, ref T);
13051 +
13052 +pragma(va_arg)
13053 + T va_arg(T)(va_list ap);
13054 +
13055 +pragma(va_end)
13056 + void va_end(va_list args);
13057 +
13058 +pragma(va_copy)
13059 + void va_copy(va_list dst, va_list src);
251 Index: import/core/stdc/stdarg.d 13060 Index: import/core/stdc/stdarg.d
252 =================================================================== 13061 ===================================================================
253 --- import/core/stdc/stdarg.d (revision 46) 13062 --- import/core/stdc/stdarg.d (revision 46)
254 +++ import/core/stdc/stdarg.d (working copy) 13063 +++ import/core/stdc/stdarg.d (working copy)
255 @@ -9,8 +9,12 @@ 13064 @@ -9,8 +9,12 @@