aboutsummaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2021-09-13 19:49:49 +0200
committerThomas Koenig <tkoenig@gcc.gnu.org>2021-09-13 19:49:49 +0200
commitb18a97e5dd0935e1c4a626c230f21457d0aad3d5 (patch)
treec1818f41af6fe780deafb6cd6a183f32085fe654 /libphobos
parente76a53644c9d70e998c0d050e9a456af388c6b61 (diff)
downloadgcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.zip
gcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.tar.gz
gcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.tar.bz2
Merged current trunk to branch.
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/ChangeLog296
-rw-r--r--libphobos/Makefile.am2
-rw-r--r--libphobos/Makefile.in6
-rw-r--r--libphobos/acinclude.m42
-rwxr-xr-xlibphobos/configure129
-rw-r--r--libphobos/configure.ac20
-rw-r--r--libphobos/configure.tgt2
-rw-r--r--libphobos/d_rules.am2
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/Makefile.am179
-rw-r--r--libphobos/libdruntime/Makefile.in576
-rw-r--r--libphobos/libdruntime/__entrypoint.di2
-rw-r--r--libphobos/libdruntime/__main.di2
-rw-r--r--libphobos/libdruntime/config/aarch64/switchcontext.S2
-rw-r--r--libphobos/libdruntime/config/arm/switchcontext.S2
-rw-r--r--libphobos/libdruntime/config/common/threadasm.S4
-rw-r--r--libphobos/libdruntime/config/mingw/msvc.c169
-rw-r--r--libphobos/libdruntime/config/mingw/switchcontext.S14
-rw-r--r--libphobos/libdruntime/config/mips/switchcontext.S2
-rw-r--r--libphobos/libdruntime/config/powerpc/switchcontext.S280
-rw-r--r--libphobos/libdruntime/config/s390/get_tls_offset.S2
-rw-r--r--libphobos/libdruntime/config/systemz/get_tls_offset.S2
-rw-r--r--libphobos/libdruntime/config/x86/switchcontext.S161
-rw-r--r--libphobos/libdruntime/core/bitop.d145
-rw-r--r--libphobos/libdruntime/core/checkedint.d48
-rw-r--r--libphobos/libdruntime/core/cpuid.d69
-rw-r--r--libphobos/libdruntime/core/internal/abort.d2
-rw-r--r--libphobos/libdruntime/core/internal/attributes.d11
-rw-r--r--libphobos/libdruntime/core/internal/traits.d152
-rw-r--r--libphobos/libdruntime/core/simd.d1096
-rw-r--r--libphobos/libdruntime/core/stdc/complex.d84
-rw-r--r--libphobos/libdruntime/core/stdc/config.d58
-rw-r--r--libphobos/libdruntime/core/stdc/errno.d260
-rw-r--r--libphobos/libdruntime/core/stdc/fenv.d22
-rw-r--r--libphobos/libdruntime/core/stdc/inttypes.d8
-rw-r--r--libphobos/libdruntime/core/stdc/limits.d2
-rw-r--r--libphobos/libdruntime/core/stdc/locale.d2
-rw-r--r--libphobos/libdruntime/core/stdc/math.d942
-rw-r--r--libphobos/libdruntime/core/stdc/stdarg.d713
-rw-r--r--libphobos/libdruntime/core/stdc/stdint.d8
-rw-r--r--libphobos/libdruntime/core/stdc/stdio.d209
-rw-r--r--libphobos/libdruntime/core/stdc/stdlib.d35
-rw-r--r--libphobos/libdruntime/core/stdc/string.d58
-rw-r--r--libphobos/libdruntime/core/stdc/tgmath.d1210
-rw-r--r--libphobos/libdruntime/core/stdc/time.d221
-rw-r--r--libphobos/libdruntime/core/stdc/wchar_.d95
-rw-r--r--libphobos/libdruntime/core/stdc/wctype.d4
-rw-r--r--libphobos/libdruntime/core/sys/bionic/err.d23
-rw-r--r--libphobos/libdruntime/core/sys/bionic/stdlib.d17
-rw-r--r--libphobos/libdruntime/core/sys/darwin/config.d53
-rw-r--r--libphobos/libdruntime/core/sys/darwin/dlfcn.d2
-rw-r--r--libphobos/libdruntime/core/sys/darwin/err.d41
-rw-r--r--libphobos/libdruntime/core/sys/darwin/fcntl.d20
-rw-r--r--libphobos/libdruntime/core/sys/darwin/ifaddrs.d77
-rw-r--r--libphobos/libdruntime/core/sys/darwin/mach/dyld.d7
-rw-r--r--libphobos/libdruntime/core/sys/darwin/mach/getsect.d172
-rw-r--r--libphobos/libdruntime/core/sys/darwin/mach/loader.d41
-rw-r--r--libphobos/libdruntime/core/sys/darwin/mach/nlist.d317
-rw-r--r--libphobos/libdruntime/core/sys/darwin/mach/stab.d90
-rw-r--r--libphobos/libdruntime/core/sys/darwin/mach/thread_act.d66
-rw-r--r--libphobos/libdruntime/core/sys/darwin/netinet/in_.d18
-rw-r--r--libphobos/libdruntime/core/sys/darwin/pthread.d8
-rw-r--r--libphobos/libdruntime/core/sys/darwin/stdlib.d26
-rw-r--r--libphobos/libdruntime/core/sys/darwin/sys/attr.d338
-rw-r--r--libphobos/libdruntime/core/sys/darwin/sys/sysctl.d253
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d23
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/err.d31
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d14
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/stdlib.d17
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d4
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/sys/sysctl.d199
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/dlfcn.d12
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/err.d31
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/execinfo.d2
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/netinet/in_.d14
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/stdlib.d17
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/event.d23
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d4
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/mount.d58
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/sysctl.d211
-rw-r--r--libphobos/libdruntime/core/sys/linux/dlfcn.d11
-rw-r--r--libphobos/libdruntime/core/sys/linux/elf.d2
-rw-r--r--libphobos/libdruntime/core/sys/linux/epoll.d89
-rw-r--r--libphobos/libdruntime/core/sys/linux/err.d24
-rw-r--r--libphobos/libdruntime/core/sys/linux/errno.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/execinfo.d2
-rw-r--r--libphobos/libdruntime/core/sys/linux/fcntl.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/ifaddrs.d3
-rw-r--r--libphobos/libdruntime/core/sys/linux/link.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/netinet/in_.d22
-rw-r--r--libphobos/libdruntime/core/sys/linux/sched.d44
-rw-r--r--libphobos/libdruntime/core/sys/linux/stdio.d2
-rw-r--r--libphobos/libdruntime/core/sys/linux/string.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/inotify.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/mman.d2
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/prctl.d2
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/signalfd.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/sysinfo.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/time.d2
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/xattr.d23
-rw-r--r--libphobos/libdruntime/core/sys/linux/tipc.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/unistd.d4
-rw-r--r--libphobos/libdruntime/core/sys/netbsd/dlfcn.d23
-rw-r--r--libphobos/libdruntime/core/sys/netbsd/err.d27
-rw-r--r--libphobos/libdruntime/core/sys/netbsd/stdlib.d17
-rw-r--r--libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d4
-rw-r--r--libphobos/libdruntime/core/sys/netbsd/sys/sysctl.d254
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/err.d27
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/stdlib.d17
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/string.d2
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d7
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/sys/sysctl.d254
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/unistd.d17
-rw-r--r--libphobos/libdruntime/core/sys/posix/aio.d4
-rw-r--r--libphobos/libdruntime/core/sys/posix/arpa/inet.d68
-rw-r--r--libphobos/libdruntime/core/sys/posix/config.d2
-rw-r--r--libphobos/libdruntime/core/sys/posix/dirent.d64
-rw-r--r--libphobos/libdruntime/core/sys/posix/dlfcn.d60
-rw-r--r--libphobos/libdruntime/core/sys/posix/fcntl.d71
-rw-r--r--libphobos/libdruntime/core/sys/posix/grp.d27
-rw-r--r--libphobos/libdruntime/core/sys/posix/iconv.d5
-rw-r--r--libphobos/libdruntime/core/sys/posix/inttypes.d19
-rw-r--r--libphobos/libdruntime/core/sys/posix/libgen.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/locale.d452
-rw-r--r--libphobos/libdruntime/core/sys/posix/mqueue.d7
-rw-r--r--libphobos/libdruntime/core/sys/posix/net/if_.d20
-rw-r--r--libphobos/libdruntime/core/sys/posix/netdb.d3
-rw-r--r--libphobos/libdruntime/core/sys/posix/netinet/in_.d158
-rw-r--r--libphobos/libdruntime/core/sys/posix/netinet/tcp.d2
-rw-r--r--libphobos/libdruntime/core/sys/posix/poll.d13
-rw-r--r--libphobos/libdruntime/core/sys/posix/pthread.d392
-rw-r--r--libphobos/libdruntime/core/sys/posix/pwd.d27
-rw-r--r--libphobos/libdruntime/core/sys/posix/sched.d11
-rw-r--r--libphobos/libdruntime/core/sys/posix/semaphore.d35
-rw-r--r--libphobos/libdruntime/core/sys/posix/setjmp.d14
-rw-r--r--libphobos/libdruntime/core/sys/posix/signal.d259
-rw-r--r--libphobos/libdruntime/core/sys/posix/spawn.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/stdc/time.d191
-rw-r--r--libphobos/libdruntime/core/sys/posix/stdio.d355
-rw-r--r--libphobos/libdruntime/core/sys/posix/stdlib.d189
-rw-r--r--libphobos/libdruntime/core/sys/posix/string.d52
-rw-r--r--libphobos/libdruntime/core/sys/posix/strings.d34
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/filio.d1
-rwxr-xr-x[-rw-r--r--]libphobos/libdruntime/core/sys/posix/sys/ioccom.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/ioctl.d5
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/ipc.d19
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/mman.d95
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/msg.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/resource.d25
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/select.d25
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/shm.d31
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/socket.d141
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/stat.d279
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/statvfs.d100
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/time.d45
-rwxr-xr-x[-rw-r--r--]libphobos/libdruntime/core/sys/posix/sys/ttycom.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/types.d51
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/uio.d47
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/un.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/utsname.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/wait.d47
-rw-r--r--libphobos/libdruntime/core/sys/posix/syslog.d49
-rw-r--r--libphobos/libdruntime/core/sys/posix/termios.d57
-rw-r--r--libphobos/libdruntime/core/sys/posix/time.d209
-rw-r--r--libphobos/libdruntime/core/sys/posix/ucontext.d104
-rw-r--r--libphobos/libdruntime/core/sys/posix/unistd.d205
-rw-r--r--libphobos/libdruntime/core/sys/posix/utime.d25
-rw-r--r--libphobos/libdruntime/core/sys/solaris/dlfcn.d4
-rw-r--r--libphobos/libdruntime/core/sys/solaris/err.d23
-rw-r--r--libphobos/libdruntime/core/sys/solaris/libelf.d12
-rw-r--r--libphobos/libdruntime/core/sys/solaris/link.d34
-rw-r--r--libphobos/libdruntime/core/sys/solaris/stdlib.d17
-rw-r--r--libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/accctrl.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/aclapi.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/aclui.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/basetsd.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/basetyps.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/cguid.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/com.d23
-rw-r--r--libphobos/libdruntime/core/sys/windows/comcat.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/commctrl.d9
-rw-r--r--libphobos/libdruntime/core/sys/windows/commdlg.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/cpl.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/cplext.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/custcntl.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/dbghelp.d10
-rw-r--r--libphobos/libdruntime/core/sys/windows/dbghelp_types.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/dbt.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/dde.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ddeml.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/dhcpcsdk.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/dlgs.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/dll.d133
-rw-r--r--libphobos/libdruntime/core/sys/windows/docobj.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/errorrep.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/exdisp.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/httpext.d7
-rw-r--r--libphobos/libdruntime/core/sys/windows/imagehlp.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/imm.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/intshcut.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ipexport.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/iphlpapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/iprtrmib.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/iptypes.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/isguids.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lm.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmaccess.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmalert.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmapibuf.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmat.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmaudit.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmbrowsr.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmchdev.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmconfig.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmcons.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmerr.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmerrlog.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmmsg.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmremutl.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmrepl.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmserver.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmshare.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmsname.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmstats.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmsvc.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmuse.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lmwksta.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/lzexpand.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/mapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/mciavi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/mcx.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/mgmtapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/mmsystem.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/msacm.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/mshtml.d27
-rw-r--r--libphobos/libdruntime/core/sys/windows/mswsock.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/nb30.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/nddeapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/nspapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntdef.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntdll.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntldap.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntsecapi.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntsecpkg.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/oaidl.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/objbase.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/objfwd.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/objidl.d13
-rw-r--r--libphobos/libdruntime/core/sys/windows/objsafe.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ocidl.d13
-rw-r--r--libphobos/libdruntime/core/sys/windows/odbcinst.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ole.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ole2.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/oleacc.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/oleauto.d13
-rw-r--r--libphobos/libdruntime/core/sys/windows/olectl.d9
-rw-r--r--libphobos/libdruntime/core/sys/windows/olectlid.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/oledlg.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/oleidl.d7
-rw-r--r--libphobos/libdruntime/core/sys/windows/pbt.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/powrprof.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/prsht.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/psapi.d25
-rw-r--r--libphobos/libdruntime/core/sys/windows/rapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/ras.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/rasdlg.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/raserror.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/rassapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/reason.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/regstr.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/richedit.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/richole.d9
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpc.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcdce.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcdce2.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcdcep.d7
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcndr.d7
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcnsi.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcnsip.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcnterr.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/schannel.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/sdkddkver.d118
-rw-r--r--libphobos/libdruntime/core/sys/windows/secext.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/security.d134
-rw-r--r--libphobos/libdruntime/core/sys/windows/servprov.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/setupapi.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/shellapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/shldisp.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/shlguid.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/shlobj.d21
-rw-r--r--libphobos/libdruntime/core/sys/windows/shlwapi.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/snmp.d7
-rw-r--r--libphobos/libdruntime/core/sys/windows/sql.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/sqlext.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/sqltypes.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/sqlucode.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/sspi.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/stacktrace.d40
-rw-r--r--libphobos/libdruntime/core/sys/windows/stat.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/stdc/malloc.d26
-rw-r--r--libphobos/libdruntime/core/sys/windows/stdc/time.d59
-rw-r--r--libphobos/libdruntime/core/sys/windows/subauth.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/threadaux.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/tlhelp32.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/tmschema.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/unknwn.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/uuid.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/vfw.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/w32api.d11
-rw-r--r--libphobos/libdruntime/core/sys/windows/winbase.d39
-rw-r--r--libphobos/libdruntime/core/sys/windows/winber.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/wincon.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/wincrypt.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/windef.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/windows.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/winerror.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/wingdi.d7
-rw-r--r--libphobos/libdruntime/core/sys/windows/winhttp.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/wininet.d236
-rw-r--r--libphobos/libdruntime/core/sys/windows/winioctl.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/winldap.d213
-rw-r--r--libphobos/libdruntime/core/sys/windows/winnetwk.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/winnls.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/winnt.d149
-rw-r--r--libphobos/libdruntime/core/sys/windows/winperf.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/winreg.d103
-rw-r--r--libphobos/libdruntime/core/sys/windows/winsock2.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/winspool.d5
-rw-r--r--libphobos/libdruntime/core/sys/windows/winsvc.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/winuser.d7
-rw-r--r--libphobos/libdruntime/core/sys/windows/winver.d92
-rw-r--r--libphobos/libdruntime/core/sys/windows/wtsapi32.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/wtypes.d7
-rw-r--r--libphobos/libdruntime/core/thread.d5732
-rw-r--r--libphobos/libdruntime/core/thread/context.d65
-rw-r--r--libphobos/libdruntime/core/thread/fiber.d2141
-rw-r--r--libphobos/libdruntime/core/thread/osthread.d2907
-rw-r--r--libphobos/libdruntime/core/thread/package.d20
-rw-r--r--libphobos/libdruntime/core/thread/threadbase.d1386
-rw-r--r--libphobos/libdruntime/core/thread/threadgroup.d162
-rw-r--r--libphobos/libdruntime/core/thread/types.d77
-rw-r--r--libphobos/libdruntime/core/vararg.d122
-rw-r--r--libphobos/libdruntime/core/volatile.d67
-rw-r--r--libphobos/libdruntime/gc/impl/conservative/gc.d4
-rw-r--r--libphobos/libdruntime/gcc/attribute.d13
-rw-r--r--libphobos/libdruntime/gcc/attributes.d605
-rw-r--r--libphobos/libdruntime/gcc/backtrace.d6
-rw-r--r--libphobos/libdruntime/gcc/builtins.d2
-rw-r--r--libphobos/libdruntime/gcc/config.d.in2
-rw-r--r--libphobos/libdruntime/gcc/deh.d35
-rw-r--r--libphobos/libdruntime/gcc/drtstuff.c2
-rw-r--r--libphobos/libdruntime/gcc/emutls.d2
-rw-r--r--libphobos/libdruntime/gcc/gthread.d8
-rw-r--r--libphobos/libdruntime/gcc/libbacktrace.d.in2
-rw-r--r--libphobos/libdruntime/gcc/sections/android.d184
-rw-r--r--libphobos/libdruntime/gcc/sections/common.d39
-rw-r--r--libphobos/libdruntime/gcc/sections/elf.d (renamed from libphobos/libdruntime/gcc/sections/elf_shared.d)149
-rw-r--r--libphobos/libdruntime/gcc/sections/macho.d738
-rw-r--r--libphobos/libdruntime/gcc/sections/osx.d284
-rw-r--r--libphobos/libdruntime/gcc/sections/package.d50
-rw-r--r--libphobos/libdruntime/gcc/sections/pecoff.d826
-rw-r--r--libphobos/libdruntime/gcc/sections/win32.d183
-rw-r--r--libphobos/libdruntime/gcc/sections/win64.d321
-rw-r--r--libphobos/libdruntime/gcc/unwind/arm.d2
-rw-r--r--libphobos/libdruntime/gcc/unwind/arm_common.d2
-rw-r--r--libphobos/libdruntime/gcc/unwind/c6x.d2
-rw-r--r--libphobos/libdruntime/gcc/unwind/generic.d4
-rw-r--r--libphobos/libdruntime/gcc/unwind/package.d2
-rw-r--r--libphobos/libdruntime/gcc/unwind/pe.d83
-rw-r--r--libphobos/libdruntime/object.d102
-rw-r--r--libphobos/libdruntime/rt/aaA.d2
-rw-r--r--libphobos/libdruntime/rt/critical_.d7
-rw-r--r--libphobos/libdruntime/rt/dmain2.d67
-rw-r--r--libphobos/libdruntime/rt/lifetime.d109
-rw-r--r--libphobos/libdruntime/rt/monitor_.d28
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Acdouble.d47
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Acfloat.d47
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Acreal.d47
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Adouble.d61
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Afloat.d61
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Ag.d154
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Aint.d151
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Along.d103
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Areal.d61
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_Ashort.d113
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_C.d75
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_byte.d60
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_cdouble.d74
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_cent.d72
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_cfloat.d73
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_char.d62
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_creal.d74
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_dchar.d62
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_delegate.d63
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_double.d76
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_float.d71
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_idouble.d27
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_ifloat.d27
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_int.d64
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_ireal.d27
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_long.d73
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_n.d58
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_ptr.d65
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_real.d67
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_short.d60
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_ubyte.d70
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_ucent.d71
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_uint.d64
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_ulong.d73
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_ushort.d60
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_void.d65
-rw-r--r--libphobos/libdruntime/rt/typeinfo/ti_wchar.d62
-rw-r--r--libphobos/libdruntime/rt/util/typeinfo.d517
-rw-r--r--libphobos/m4/autoconf.m42
-rw-r--r--libphobos/m4/druntime.m419
-rw-r--r--libphobos/m4/druntime/libraries.m44
-rw-r--r--libphobos/m4/druntime/os.m429
-rw-r--r--libphobos/m4/gcc_support.m42
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/Makefile.am22
-rw-r--r--libphobos/src/Makefile.in27
-rw-r--r--libphobos/src/std/algorithm/iteration.d8
-rw-r--r--libphobos/src/std/algorithm/searching.d4
-rw-r--r--libphobos/src/std/container/rbtree.d4
-rw-r--r--libphobos/src/std/conv.d4
-rw-r--r--libphobos/src/std/datetime/systime.d146
-rw-r--r--libphobos/src/std/datetime/timezone.d17
-rw-r--r--libphobos/src/std/exception.d5
-rw-r--r--libphobos/src/std/experimental/allocator/building_blocks/region.d44
-rw-r--r--libphobos/src/std/experimental/allocator/mmap_allocator.d17
-rw-r--r--libphobos/src/std/experimental/logger/nulllogger.d2
-rw-r--r--libphobos/src/std/experimental/typecons.d6
-rw-r--r--libphobos/src/std/file.d116
-rw-r--r--libphobos/src/std/format.d4
-rw-r--r--libphobos/src/std/internal/math/biguintcore.d4
-rw-r--r--libphobos/src/std/math.d37
-rw-r--r--libphobos/src/std/parallelism.d237
-rw-r--r--libphobos/src/std/process.d54
-rw-r--r--libphobos/src/std/range/package.d1
-rw-r--r--libphobos/src/std/regex/internal/tests.d653
-rw-r--r--libphobos/src/std/regex/internal/tests2.d662
-rw-r--r--libphobos/src/std/socket.d6
-rw-r--r--libphobos/src/std/stdio.d611
-rw-r--r--libphobos/src/std/system.d6
-rw-r--r--libphobos/src/std/typecons.d25
-rw-r--r--libphobos/src/std/zip.d6
-rw-r--r--libphobos/testsuite/Makefile.am2
-rw-r--r--libphobos/testsuite/Makefile.in4
-rw-r--r--libphobos/testsuite/config/default.exp2
-rw-r--r--libphobos/testsuite/lib/libphobos-dg.exp2
-rw-r--r--libphobos/testsuite/lib/libphobos.exp2
-rw-r--r--libphobos/testsuite/libphobos.aa/aa.exp2
-rw-r--r--libphobos/testsuite/libphobos.allocations/allocations.exp2
-rw-r--r--libphobos/testsuite/libphobos.allocations/tls_gc_integration.d2
-rw-r--r--libphobos/testsuite/libphobos.cycles/cycles.exp2
-rw-r--r--libphobos/testsuite/libphobos.druntime/druntime.exp7
-rw-r--r--libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp4
-rw-r--r--libphobos/testsuite/libphobos.exceptions/chain.d4
-rw-r--r--libphobos/testsuite/libphobos.exceptions/exceptions.exp2
-rw-r--r--libphobos/testsuite/libphobos.exceptions/line_trace.d2
-rw-r--r--libphobos/testsuite/libphobos.hash/hash.exp2
-rw-r--r--libphobos/testsuite/libphobos.init_fini/init_fini.exp2
-rw-r--r--libphobos/testsuite/libphobos.phobos/phobos.exp13
-rw-r--r--libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp12
-rw-r--r--libphobos/testsuite/libphobos.shared/shared.exp2
-rw-r--r--libphobos/testsuite/libphobos.thread/fiber_guard_page.d15
-rw-r--r--libphobos/testsuite/libphobos.thread/thread.exp2
-rw-r--r--libphobos/testsuite/libphobos.typeinfo/typeinfo.exp2
-rwxr-xr-xlibphobos/testsuite/testsuite_flags.in3
470 files changed, 22391 insertions, 16651 deletions
diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog
index 8dca301..fa1aef7 100644
--- a/libphobos/ChangeLog
+++ b/libphobos/ChangeLog
@@ -1,3 +1,297 @@
+2021-09-01 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * m4/druntime/os.m4: Update comment for DRUNTIME_OS_SOURCES.
+
+2021-09-01 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * src/Makefile.am: Don't add zlib when ENABLE_LIBDRUNTIME_ONLY.
+ * src/Makefile.in: Regenerate.
+
+2021-08-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * configure: Regenerate.
+ * m4/autoconf.m4 (AC_LANG_PROGRAM): Declare module name 'object'.
+ * m4/gcc_support.m4 (WITH_LOCAL_DRUNTIME): Compile tests with
+ -fno-druntime.
+
+2021-06-11 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/100999
+ * src/MERGE: Merge upstream phobos 55bb17543.
+
+2021-05-14 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * src/std/process.d (unittest): Remove tmpname on exit.
+ * src/MERGE: Merge upstream phobos 63f4caa90.
+
+2021-05-13 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/MERGE: Merge upstream druntime 98c6ff0c.
+
+2021-05-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * src/MERGE: Merge upstream phobos 32cfe9b61.
+
+2021-04-21 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/core/thread/osthread.d (callWithStackShell): Statically
+ generate PPC and PPC64 asm implementations, and conditionally remove
+ PPC register names on non-Darwin targets.
+
+2021-04-20 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/98584
+ * libdruntime/gcc/deh.d (scanLSDA): Update calls to read_uleb128 and
+ read_encoded_value.
+ (actionTableLookup): Update calls to read_sleb128 and
+ read_encoded_value_with_base.
+ * libdruntime/gcc/unwind/pe.d (read_uleb128): Update signature.
+ (read_sleb128): Update signature.
+ (read_unaligned): New function.
+ (read_encoded_value_with_base): Update signature. Call read_unaligned
+ instead of unsafe pointer dereferencing.
+ (read_encoded_value): Update signature.
+
+2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/98494
+ * libdruntime/MERGE: Merge upstream druntime 89f870b7.
+ * src/MERGE: Merge upstream phobos e6907ff3e.
+
+2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/98058
+ * configure: Regenerate.
+ * libdruntime/Makefile.am (DRUNTIME_DSOURCES_DARWIN): Add
+ core/sys/darwin/config.d
+ * libdruntime/Makefile.in: Regenerate.
+ * libdruntime/config/powerpc/switchcontext.S: Implement
+ fiber_switchContext for __MACH__.
+ * libdruntime/config/x86/switchcontext.S: Likewise.
+ * libdruntime/core/sys/darwin/config.d: New file.
+ * libdruntime/core/thread/fiber.d (Fiber.getThis): Mark noinline.
+ (UnsafeFiberMigration): Define for OSX/X86 and OSX/X86_64.
+ * libdruntime/core/thread/osthread.d (callWithStackShell): Add inline
+ assembler implementation for X86, X86_64, PPC, and PPC64.
+ * libdruntime/core/thread/threadbase.d (ThreadBase.getThis): Mark
+ noinline.
+ * libdruntime/gcc/deh.d (FuncTable): Remove definition.
+ * m4/druntime/os.m4 (DRUNTIME_OS_MINFO_BRACKETING): Check for right
+ bracket symbol on darwin* targets.
+ * testsuite/libphobos.thread/fiber_guard_page.d: Update test to
+ support ucontext-based Fibers.
+
+2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/99794
+ * libdruntime/Makefile.am (DRUNTIME_SOURCES_CONFIGURED): Add
+ config/mingw/msvc.c on DRUNTIME_OS_MINGW.
+ * libdruntime/Makefile.in: Regenerate.
+ * libdruntime/config/mingw/msvc.c: New file.
+ * libdruntime/config/mingw/switchcontext.S (fiber_switchContext): Fix
+ function definition.
+ * libdruntime/gcc/deh.d (__gdc_personality_seh0): Fix call to
+ _GCC_specific_handler.
+ * libdruntime/gcc/gthread.d (__gthread_once_t): Fix definition.
+ * libdruntime/gcc/unwind/generic.d (_GCC_specific_handler): Fix
+ declaration.
+ * libdruntime/rt/dmain2.d (rt_loadLibrary): Remove function.
+ (rt_loadLibraryW): Remove function.
+ (initLibrary): Remove function.
+ (rt_unloadLibrary): Remove function.
+
+2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/99691
+ * configure: Regenerate.
+ * libdruntime/config/common/threadasm.S: Add __OpenBSD__.
+ * libdruntime/gcc/backtrace.d: Import core.sys.openbsd.dlfcn on
+ OpenBSD platforms.
+ * libdruntime/gcc/sections/elf.d (SharedElf): Define on OpenBSD.
+ (linkMapForHandle): Implement for OpenBSD.
+ (exeLinkMap): Remove.
+ (getDependencies): Adjust dlpi_addr on OpenBSD.
+ (handleForName): Implement for OpenBSD.
+ (IterateManually): Define on OpenBSD.
+ * libdruntime/gcc/sections/package.d (SectionsElf): Define on OpenBSD.
+ * m4/druntime/libraries.m4 (DRUNTIME_LIBRARIES_ATOMIC): Test for
+ enable_libatomic.
+ (DRUNTIME_LIBRARIES_BACKTRACE): Test for enable_libbacktrace.
+
+2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Call DRUNTIME_SECTION_FLAGS.
+ * libdruntime/Makefile.am: Add SECTION_FLAGS to AM_DFLAGS.
+ * libdruntime/Makefile.in: Regenerate.
+ * m4/druntime.m4 (DRUNTIME_SECTION_FLAGS): New macro.
+ * src/Makefile.am: Add SECTION_FLAGS to AM_DFLAGS.
+ * src/Makefile.in: Regenerate.
+ * testsuite/Makefile.in: Regenerate.
+
+2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Removed
+ gcc/sections/android.d, elf_shared.d, osx.d, win32.d, and win64.d.
+ Added gcc/sections/common.d, elf.d macho.d, and pecoff.d.
+ * libdruntime/Makefile.in: Regenerate.
+ * libdruntime/core/thread/osthread.d: Update externDFunc FQDN names to
+ use platform independant section function names.
+ * libdruntime/gcc/sections/elf_shared.d: Renamed to...
+ * libdruntime/gcc/sections/elf.d: ...this. Mangle functions for
+ core.thread interface as if they come from the gcc.sections module.
+ * libdruntime/gcc/sections/package.d: Update public imports, declare
+ functions for core.thread interface.
+ * libdruntime/gcc/sections/android.d: Removed.
+ * libdruntime/gcc/sections/osx.d: Removed.
+ * libdruntime/gcc/sections/win32.d: Removed.
+ * libdruntime/gcc/sections/win64.d: Removed.
+ * libdruntime/gcc/sections/common.d: New file.
+ * libdruntime/gcc/sections/macho.d: New file.
+ * libdruntime/gcc/sections/pecoff.d: New file.
+
+2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * testsuite/libphobos.druntime/druntime.exp: Compile all tests with
+ -static-libphobos.
+ * testsuite/libphobos.phobos/phobos.exp: Likewise.
+
+2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * testsuite/libphobos.druntime/druntime.exp: Remove
+ is-effective-target static.
+ * testsuite/libphobos.phobos/phobos.exp: Likewise.
+
+2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/99812
+ * testsuite/libphobos.druntime_shared/druntime_shared.exp: Re-add
+ -fno-moduleinfo flag to dg-runtest.
+ * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.
+
+2021-04-08 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add
+ gcc/attributes.d.
+ * libdruntime/Makefile.in: Regenerate.
+ * libdruntime/gcc/attribute.d: Deprecate module, publicly import
+ gcc.attributes.
+ * libdruntime/gcc/deh.d: Update imports.
+ * libdruntime/gcc/attributes.d: New file.
+
+2021-04-06 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/MERGE: Merge upstream druntime 1134b710.
+
+2021-04-03 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/MERGE: Merge upstream druntime 483bc129.
+ * libdruntime/Makefile.am (DRUNTIME_DSOURCES_DARWIN): Add
+ core/sys/darwin/fcntl.d.
+ (DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/unistd.d.
+ (DRUNTIME_DSOURCES_WINDOWS): Add core/sys/windows/stdc/malloc.d.
+ * libdruntime/Makefile.in: Regenerate.
+ * src/MERGE: Merge upstream phobos f89dc217a.
+ * src/Makefile.am (PHOBOS_DSOURCES): Add std/regex/internal/tests2.d.
+ * src/Makefile.in: Regenerate.
+ * testsuite/libphobos.exceptions/chain.d: Fix format arguments.
+ * testsuite/libphobos.exceptions/line_trace.d: Likewise.
+
+2021-03-26 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Substitute enable_shared, enable_static, and
+ phobos_lt_pic_flag.
+ * libdruntime/Makefile.am (AM_DFLAGS): Replace
+ phobos_compiler_pic_flag with phobos_lt_pic_flags, and
+ phobos_compiler_shared_flag.
+ * libdruntime/Makefile.in: Regenerate.
+ * src/Makefile.am (AM_DFLAGS): Replace phobos_compiler_pic_flag
+ with phobos_lt_pic_flag, and phobos_compiler_shared_flag.
+ * src/Makefile.in: Regenerate.
+ * testsuite/Makefile.in: Regenerate.
+ * testsuite/libphobos.druntime_shared/druntime_shared.exp: Remove
+ -fversion=Shared and -fno-moduleinfo from default extra test flags.
+ * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.
+ * testsuite/testsuite_flags.in: Add phobos_compiler_shared_flag to
+ --gdcflags.
+
+2021-02-04 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/98910
+ * libdruntime/MERGE: Merge upstream druntime 0fd4364c.
+ * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add core/volatile.d.
+ * libdruntime/Makefile.in: Regenerate.
+ * testsuite/libphobos.allocations/tls_gc_integration.d: Update test.
+
+2021-02-03 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/98910
+ * libdruntime/MERGE: Merge upstream druntime 9d0c8364.
+ * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add
+ core/internal/attributes.d
+ (DRUNTIME_DSOURCES_BIONIC): Add core/sys/bionic/stdlib.d.
+ (DRUNTIME_DSOURCES_DARWIN): Add core/sys/darwin/stdlib.d, and
+ core/sys/darwin/sys/sysctl.d.
+ (DRUNTIME_DSOURCES_DRAGONFLYBSD): Add
+ core/sys/dragonflybsd/stdlib.d, and
+ core/sys/dragonflybsd/sys/sysctl.d.
+ (DRUNTIME_DSOURCES_FREEBSD): Add core/sys/freebsd/stdlib.d, and
+ core/sys/freebsd/sys/sysctl.d.
+ (DRUNTIME_DSOURCES_NETBSD): Add core/sys/netbsd/stdlib.d, and
+ core/sys/netbsd/sys/sysctl.d.
+ (DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/stdlib.d, and
+ core/sys/openbsd/sys/sysctl.d.
+ (DRUNTIME_DSOURCES_SOLARIS): Add core/sys/solaris/stdlib.d.
+ * libdruntime/Makefile.in: Regenerate.
+ * src/MERGE: Merge upstream phobos 9d575282e.
+
+2021-01-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * libdruntime/MERGE: Merge upstream druntime e4aae28e.
+ * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Refresh module list.
+ (DRUNTIME_DSOURCES_BIONIC): Add core/sys/bionic/err.d.
+ (DRUNTIME_DSOURCES_DARWIN): Add core/sys/darwin/err.d,
+ core/sys/darwin/ifaddrs.d, core/sys/darwin/mach/nlist.d,
+ core/sys/darwin/mach/stab.d, and core/sys/darwin/sys/attr.d.
+ (DRUNTIME_DSOURCES_DRAGONFLYBSD): Add core/sys/dragonflybsd/err.d.
+ (DRUNTIME_DSOURCES_FREEBSD): Add core/sys/freebsd/err.d.
+ (DRUNTIME_DSOURCES_LINUX): Add core/sys/linux/err.d.
+ (DRUNTIME_DSOURCES_NETBSD): Add core/sys/netbsd/err.d.
+ (DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/err.d.
+ (DRUNTIME_DSOURCES_POSIX): Add core/sys/posix/locale.d,
+ core/sys/posix/stdc/time.d, core/sys/posix/string.d, and
+ core/sys/posix/strings.d.
+ (DRUNTIME_DSOURCES_SOLARIS): Add core/sys/solaris/err.d.
+ (DRUNTIME_DSOURCES_WINDOWS): Add core/sys/windows/sdkddkver.d,
+ and core/sys/windows/stdc/time.d
+ * libdruntime/Makefile.in: Regenerate.
+ * libdruntime/gcc/sections/elf_shared.d (sizeofTLS): New function.
+ * testsuite/libphobos.thread/fiber_guard_page.d: Use
+ __traits(getMember) to get internal fields.
+
+2021-01-26 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * src/MERGE: Merge upstream phobos 3dd5df686.
+ * testsuite/libphobos.phobos/phobos.exp: Add compiler flag
+ -fversion=Linux_Pre_2639 if target is linux_pre_2639.
+ * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.
+
+2021-01-23 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/98806
+ * libdruntime/gcc/sections/elf_shared.d (MIPS_Any): Declare version
+ for MIPS32 and MIPS64.
+ (getDependencies): Adjust dlpi_addr on MIPS_Any.
+
+2021-01-05 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * configure: Re-generate.
+
2020-12-05 Iain Sandoe <iain@sandoe.co.uk>
PR target/97865
@@ -906,7 +1200,7 @@
* testsuite/testsuite_flags.in: New file.
-Copyright (C) 2018-2020 Free Software Foundation, Inc.
+Copyright (C) 2018-2021 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
diff --git a/libphobos/Makefile.am b/libphobos/Makefile.am
index 874b3a2..e5f005d 100644
--- a/libphobos/Makefile.am
+++ b/libphobos/Makefile.am
@@ -1,5 +1,5 @@
# Makefile for the toplevel directory of the D Standard library.
-# Copyright (C) 2006-2020 Free Software Foundation, Inc.
+# Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in
index a139592..a8f7e16 100644
--- a/libphobos/Makefile.in
+++ b/libphobos/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
# Makefile for the toplevel directory of the D Standard library.
-# Copyright (C) 2006-2020 Free Software Foundation, Inc.
+# Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -271,6 +271,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
+SECTION_FLAGS = @SECTION_FLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -298,6 +299,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -327,6 +330,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
diff --git a/libphobos/acinclude.m4 b/libphobos/acinclude.m4
index eb52c10..7d5a6ac 100644
--- a/libphobos/acinclude.m4
+++ b/libphobos/acinclude.m4
@@ -1,4 +1,4 @@
-dnl Copyright (C) 2013-2020 Free Software Foundation, Inc.
+dnl Copyright (C) 2013-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
diff --git a/libphobos/configure b/libphobos/configure
index a7fb5ed..14298a0 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -700,11 +700,15 @@ DRUNTIME_CPU_ARM_FALSE
DRUNTIME_CPU_ARM_TRUE
DRUNTIME_CPU_AARCH64_FALSE
DRUNTIME_CPU_AARCH64_TRUE
+SECTION_FLAGS
libphobos_srcdir
libphobos_builddir
get_gcc_base_ver
phobos_compiler_shared_flag
phobos_compiler_pic_flag
+phobos_lt_pic_flag
+enable_static
+enable_shared
OTOOL64
OTOOL
LIPO
@@ -5378,7 +5382,7 @@ fi
gdc_save_DFLAGS=$GDCFLAGS
- GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $GDCFLAGS"
+ GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $GDCFLAGS"
ac_ext=d
ac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5'
@@ -5388,7 +5392,7 @@ ac_compiler_gnu=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking If $GDC can compile D sources" >&5
$as_echo_n "checking If $GDC can compile D sources... " >&6; }
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
extern(C) int main() {
@@ -10936,16 +10940,6 @@ freebsd* | dragonfly*)
esac
;;
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
haiku*)
version_type=linux
need_lib_prefix=no
@@ -11067,7 +11061,7 @@ linux*oldld* | linux*aout* | linux*coff*)
# project, but have not yet been accepted: they are GCC-local changes
# for the time being. (See
# https://lists.gnu.org/archive/html/libtool-patches/2018-05/msg00000.html)
-linux* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu* | uclinuxfdpiceabi)
version_type=linux
need_lib_prefix=no
need_version=no
@@ -11756,7 +11750,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11759 "configure"
+#line 11753 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11862,7 +11856,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11865 "configure"
+#line 11859 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12103,7 +12097,7 @@ CC="$lt_save_CC"
gdc_save_DFLAGS=$GDCFLAGS
- GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $GDCFLAGS"
+ GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $GDCFLAGS"
# Source file extension for D test sources.
@@ -14007,8 +14001,14 @@ CFLAGS=$lt_save_CFLAGS
GDCFLAGS=$gdc_save_DFLAGS
+
+
# libtool variables for Phobos shared and position-independent compiles.
#
+# Use phobos_lt_pic_flag to designate the automake variable
+# used to encapsulate the default libtool approach to creating objects
+# with position-independent code. Default: -prefer-pic.
+#
# Use phobos_compiler_shared_flag to designate the compile-time flags for
# creating shared objects. Default: -fversion=Shared.
#
@@ -14020,26 +14020,23 @@ CFLAGS=$lt_save_CFLAGS
# libtool, and so we make it here. How it is handled is that in shared
# compilations the `lt_prog_compiler_pic_D' variable is used to instead
# ensure that conditional compilation of shared runtime code is compiled in.
-# The original PIC flags are then used in the compilation of every object.
-#
-# Why are objects destined for libgphobos.a compiled with -fPIC?
-# Because -fPIC is not harmful to use for objects destined for static
-# libraries. In addition, using -fPIC will allow the use of static
-# libgphobos.a in the creation of other D shared libraries.
if test "$enable_shared" = yes; then
+ phobos_lt_pic_flag="-prefer-pic"
phobos_compiler_pic_flag="$lt_prog_compiler_pic_D"
phobos_compiler_shared_flag="-fversion=Shared"
else
+ phobos_lt_pic_flag=
phobos_compiler_pic_flag=
phobos_compiler_shared_flag=
fi
+
# Override the libtool's pic_flag and pic_mode.
# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.
# NB: this impacts --with-pic and --without-pic.
-lt_prog_compiler_pic_D="$phobos_compiler_shared_flag"
+lt_prog_compiler_pic_D="$phobos_compiler_pic_flag $phobos_compiler_shared_flag"
pic_mode='default'
# Determine what GCC version number to use in filesystem paths.
@@ -14089,6 +14086,48 @@ fi
fi
+
+
+ gdc_save_DFLAGS=$GDCFLAGS
+ GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS"
+
+ ac_ext=d
+ac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5'
+ac_link='$GDC -o conftest$ac_exeext $GDCFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=yes
+
+ GDCFLAGS="$GDCFLAGS -g -Werror -ffunction-sections -fdata-sections"
+ cat > conftest.$ac_ext <<_ACEOF
+module object;
+int foo; void bar() { }
+
+extern(C) int main() {
+ return 0;
+}
+_ACEOF
+if ac_fn_d_try_compile "$LINENO"; then :
+ ac_fdsections=yes
+else
+ ac_fdsections=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test "x$ac_fdsections" = "xyes"; then
+ SECTION_FLAGS='-ffunction-sections -fdata-sections'
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_fdsections" >&5
+$as_echo "$ac_fdsections" >&6; }
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ GDCFLAGS=$gdc_save_DFLAGS
+
+
+
+
druntime_target_cpu_parsed=""
case "$target_cpu" in
aarch64*)
@@ -14383,6 +14422,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -14391,17 +14432,29 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for minfo section bracketing" >&5
$as_echo_n "checking for minfo section bracketing... " >&6; }
+ case "$druntime_cv_target_os" in
+ darwin*)
+ section="__DATA,__minfodata"
+ start="section\$start\$__DATA\$__minfodata"
+ stop="section\$end\$__DATA\$__minfodata"
+ ;;
+ *)
+ section="minfo"
+ start="__start_minfo"
+ stop="__stop_minfo"
+ ;;
+ esac
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- void* module_info_ptr __attribute__((section ("minfo")));
- extern void* __start_minfo __attribute__((visibility ("hidden")));
- extern void* __stop_minfo __attribute__((visibility ("hidden")));
+ void* module_info_ptr __attribute__((section ("$section")));
+ extern void* start_minfo __asm__("$start") __attribute__((visibility ("hidden")));
+ extern void* stop_minfo __asm__("$stop") __attribute__((visibility ("hidden")));
int main()
{
// Never run, just to prevent compiler from optimizing access
- return &__start_minfo == &__stop_minfo;
+ return (int)(&stop_minfo - &start_minfo);
}
_ACEOF
@@ -14509,7 +14562,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
gdc_save_DFLAGS=$GDCFLAGS
- GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS"
+ GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS"
ac_ext=d
ac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5'
@@ -14523,7 +14576,7 @@ if ${ac_cv_search_malloc+:} false; then :
else
ac_func_search_save_LIBS=$LIBS
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
extern(C) int malloc();
extern(C) int main() {
@@ -14569,7 +14622,7 @@ if ${ac_cv_search_pthread_create+:} false; then :
else
ac_func_search_save_LIBS=$LIBS
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
extern(C) int pthread_create();
extern(C) int main() {
@@ -14615,7 +14668,7 @@ if ${ac_cv_search_cosf+:} false; then :
else
ac_func_search_save_LIBS=$LIBS
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
extern(C) int cosf();
extern(C) int main() {
@@ -14661,7 +14714,7 @@ if ${ac_cv_search_clock_gettime+:} false; then :
else
ac_func_search_save_LIBS=$LIBS
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
extern(C) int clock_gettime();
extern(C) int main() {
@@ -14712,7 +14765,7 @@ $as_echo_n "checking for atomic builtins for byte... " >&6; }
else
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
import gcc.builtins;
extern(C) int main() {
@@ -14746,7 +14799,7 @@ $as_echo_n "checking for atomic builtins for short... " >&6; }
else
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
import gcc.builtins;
extern(C) int main() {
@@ -14780,7 +14833,7 @@ $as_echo_n "checking for atomic builtins for int... " >&6; }
else
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
import gcc.builtins;
extern(C) int main() {
@@ -14814,7 +14867,7 @@ $as_echo_n "checking for atomic builtins for long... " >&6; }
else
cat > conftest.$ac_ext <<_ACEOF
-module mod;
+module object;
import gcc.builtins;
extern(C) int main() {
@@ -14878,7 +14931,7 @@ fi
DCFG_HAVE_LIBATOMIC=false
LIBATOMIC=
- if test "x$with_libatomic" != "xno"; then :
+ if test "x$enable_libatomic" != "xno" && test "x$with_libatomic" != "xno"; then :
DCFG_HAVE_LIBATOMIC=true
LIBATOMIC=../../libatomic/libatomic_convenience.la
@@ -14914,7 +14967,7 @@ if test "${with_libbacktrace+set}" = set; then :
fi
- if test "x$with_libbacktrace" != "xno"; then :
+ if test "x$enable_libbacktrace" != "xno" && test "x$with_libbacktrace" != "xno"; then :
LIBBACKTRACE=../../libbacktrace/libbacktrace.la
diff --git a/libphobos/configure.ac b/libphobos/configure.ac
index 2d51e46..3b5a830 100644
--- a/libphobos/configure.ac
+++ b/libphobos/configure.ac
@@ -1,5 +1,5 @@
# Process this file with autoconf to produce a configure script.
-# Copyright (C) 2006-2020 Free Software Foundation, Inc.
+# Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -91,9 +91,15 @@ AC_SUBST(CFLAGS_FOR_BUILD)
LT_INIT(dlopen)
AM_PROG_LIBTOOL
WITH_LOCAL_DRUNTIME([LT_LANG([D])], [])
+AC_SUBST(enable_shared)
+AC_SUBST(enable_static)
# libtool variables for Phobos shared and position-independent compiles.
#
+# Use phobos_lt_pic_flag to designate the automake variable
+# used to encapsulate the default libtool approach to creating objects
+# with position-independent code. Default: -prefer-pic.
+#
# Use phobos_compiler_shared_flag to designate the compile-time flags for
# creating shared objects. Default: -fversion=Shared.
#
@@ -105,26 +111,23 @@ WITH_LOCAL_DRUNTIME([LT_LANG([D])], [])
# libtool, and so we make it here. How it is handled is that in shared
# compilations the `lt_prog_compiler_pic_D' variable is used to instead
# ensure that conditional compilation of shared runtime code is compiled in.
-# The original PIC flags are then used in the compilation of every object.
-#
-# Why are objects destined for libgphobos.a compiled with -fPIC?
-# Because -fPIC is not harmful to use for objects destined for static
-# libraries. In addition, using -fPIC will allow the use of static
-# libgphobos.a in the creation of other D shared libraries.
if test "$enable_shared" = yes; then
+ phobos_lt_pic_flag="-prefer-pic"
phobos_compiler_pic_flag="$lt_prog_compiler_pic_D"
phobos_compiler_shared_flag="-fversion=Shared"
else
+ phobos_lt_pic_flag=
phobos_compiler_pic_flag=
phobos_compiler_shared_flag=
fi
+AC_SUBST(phobos_lt_pic_flag)
AC_SUBST(phobos_compiler_pic_flag)
AC_SUBST(phobos_compiler_shared_flag)
# Override the libtool's pic_flag and pic_mode.
# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.
# NB: this impacts --with-pic and --without-pic.
-lt_prog_compiler_pic_D="$phobos_compiler_shared_flag"
+lt_prog_compiler_pic_D="$phobos_compiler_pic_flag $phobos_compiler_shared_flag"
pic_mode='default'
# Determine what GCC version number to use in filesystem paths.
@@ -134,6 +137,7 @@ GCC_BASE_VER
DRUNTIME_CONFIGURE
DRUNTIME_MULTILIB
DRUNTIME_WERROR
+DRUNTIME_SECTION_FLAGS
DRUNTIME_CPU_SOURCES
DRUNTIME_OS_SOURCES
DRUNTIME_OS_THREAD_MODEL
diff --git a/libphobos/configure.tgt b/libphobos/configure.tgt
index 7d9c6bc..88c027d 100644
--- a/libphobos/configure.tgt
+++ b/libphobos/configure.tgt
@@ -1,5 +1,5 @@
# -*- shell-script -*-
-# Copyright (C) 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2018-2021 Free Software Foundation, Inc.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/d_rules.am b/libphobos/d_rules.am
index c05c8e8..5648d8b 100644
--- a/libphobos/d_rules.am
+++ b/libphobos/d_rules.am
@@ -1,5 +1,5 @@
## Common rules for D source compilation used in all Makefile.am's.
-## Copyright (C) 2016-2020 Free Software Foundation, Inc.
+## Copyright (C) 2016-2021 Free Software Foundation, Inc.
##
## GCC is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 7162844..0d554e0 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-0fe7974cf53b75db59461de2a3d6e53ce933d297
+98c6ff0cf1241a0cfac196bf8a0523b1d4ecd3ac
The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 4798bdf..a2e2bff 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -1,5 +1,5 @@
# Makefile for the D runtime library.
-# Copyright (C) 2012-2020 Free Software Foundation, Inc.
+# Copyright (C) 2012-2021 Free Software Foundation, Inc.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,8 +23,8 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) -I .
# D flags for compilation
AM_DFLAGS= \
- $(phobos_compiler_pic_flag) \
- $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
+ $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
AM_CFLAGS=$(CET_FLAGS)
@@ -69,7 +69,8 @@ if DRUNTIME_OS_LINUX
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_LINUX)
endif
if DRUNTIME_OS_MINGW
- DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS)
+ DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS) \
+ config/mingw/msvc.c
endif
if DRUNTIME_OS_SOLARIS
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_SOLARIS)
@@ -166,7 +167,8 @@ DRUNTIME_CSOURCES = core/stdc/errno_.c
DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/checkedint.d core/cpuid.d core/demangle.d core/exception.d \
- core/internal/abort.d core/internal/arrayop.d core/internal/convert.d \
+ core/internal/abort.d core/internal/arrayop.d \
+ core/internal/attributes.d core/internal/convert.d \
core/internal/hash.d core/internal/spinlock.d core/internal/string.d \
core/internal/traits.d core/math.d core/memory.d core/runtime.d \
core/simd.d core/stdc/assert_.d core/stdc/complex.d core/stdc/config.d \
@@ -178,33 +180,21 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/stdc/tgmath.d core/stdc/time.d core/stdc/wchar_.d \
core/stdc/wctype.d core/sync/barrier.d core/sync/condition.d \
core/sync/config.d core/sync/exception.d core/sync/mutex.d \
- core/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \
- core/vararg.d gc/bits.d gc/config.d gc/gcinterface.d \
- gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.d gc/pooltable.d \
- gc/proxy.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \
- gcc/emutls.d gcc/gthread.d gcc/sections/android.d \
- gcc/sections/elf_shared.d gcc/sections/osx.d gcc/sections/package.d \
- gcc/sections/win32.d gcc/sections/win64.d gcc/unwind/arm.d \
+ core/sync/rwmutex.d core/sync/semaphore.d core/thread/context.d \
+ core/thread/fiber.d core/thread/osthread.d core/thread/package.d \
+ core/thread/threadbase.d core/thread/threadgroup.d core/thread/types.d \
+ core/time.d core/vararg.d core/volatile.d gc/bits.d gc/config.d \
+ gc/gcinterface.d gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.d \
+ gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/attributes.d \
+ gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
+ gcc/sections/common.d gcc/sections/elf.d gcc/sections/macho.d \
+ gcc/sections/package.d gcc/sections/pecoff.d gcc/unwind/arm.d \
gcc/unwind/arm_common.d gcc/unwind/c6x.d gcc/unwind/generic.d \
gcc/unwind/package.d gcc/unwind/pe.d object.d rt/aApply.d rt/aApplyR.d \
rt/aaA.d rt/adi.d rt/arrayassign.d rt/arraycast.d rt/arraycat.d \
rt/cast_.d rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d \
rt/invariant.d rt/lifetime.d rt/memory.d rt/minfo.d rt/monitor_.d \
rt/obj.d rt/qsort.d rt/sections.d rt/switch_.d rt/tlsgc.d \
- rt/typeinfo/ti_Acdouble.d rt/typeinfo/ti_Acfloat.d \
- rt/typeinfo/ti_Acreal.d rt/typeinfo/ti_Adouble.d \
- rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d rt/typeinfo/ti_Aint.d \
- rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d rt/typeinfo/ti_Ashort.d \
- rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d rt/typeinfo/ti_cdouble.d \
- rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d rt/typeinfo/ti_char.d \
- rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \
- rt/typeinfo/ti_delegate.d rt/typeinfo/ti_double.d \
- rt/typeinfo/ti_float.d rt/typeinfo/ti_idouble.d \
- rt/typeinfo/ti_ifloat.d rt/typeinfo/ti_int.d rt/typeinfo/ti_ireal.d \
- rt/typeinfo/ti_long.d rt/typeinfo/ti_n.d rt/typeinfo/ti_ptr.d \
- rt/typeinfo/ti_real.d rt/typeinfo/ti_short.d rt/typeinfo/ti_ubyte.d \
- rt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \
- rt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \
rt/util/array.d rt/util/container/array.d rt/util/container/common.d \
rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \
rt/util/typeinfo.d rt/util/utf.d
@@ -212,22 +202,28 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
core/stdcpp/typeinfo.d
-DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
+DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
+ core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
core/sys/bionic/string.d core/sys/bionic/unistd.d
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
- core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+ core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+ core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+ core/sys/darwin/fcntl.d core/sys/darwin/ifaddrs.d \
core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
- core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+ core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
+ core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
- core/sys/darwin/pthread.d core/sys/darwin/string.d \
+ core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
+ core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
- core/sys/darwin/sys/mman.d
+ core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
- core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
- core/sys/dragonflybsd/pthread_np.d core/sys/dragonflybsd/string.d \
+ core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
+ core/sys/dragonflybsd/netinet/in_.d core/sys/dragonflybsd/pthread_np.d \
+ core/sys/dragonflybsd/stdlib.d core/sys/dragonflybsd/string.d \
core/sys/dragonflybsd/sys/_bitset.d \
core/sys/dragonflybsd/sys/_cpuset.d core/sys/dragonflybsd/sys/cdefs.d \
core/sys/dragonflybsd/sys/elf.d core/sys/dragonflybsd/sys/elf32.d \
@@ -235,22 +231,24 @@ DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
core/sys/dragonflybsd/sys/elf_common.d \
core/sys/dragonflybsd/sys/event.d core/sys/dragonflybsd/sys/link_elf.d \
core/sys/dragonflybsd/sys/mman.d core/sys/dragonflybsd/sys/socket.d \
- core/sys/dragonflybsd/time.d
+ core/sys/dragonflybsd/sys/sysctl.d core/sys/dragonflybsd/time.d
DRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/config.d \
- core/sys/freebsd/dlfcn.d core/sys/freebsd/execinfo.d \
- core/sys/freebsd/netinet/in_.d core/sys/freebsd/pthread_np.d \
+ core/sys/freebsd/dlfcn.d core/sys/freebsd/err.d \
+ core/sys/freebsd/execinfo.d core/sys/freebsd/netinet/in_.d \
+ core/sys/freebsd/pthread_np.d core/sys/freebsd/stdlib.d \
core/sys/freebsd/string.d core/sys/freebsd/sys/_bitset.d \
core/sys/freebsd/sys/_cpuset.d core/sys/freebsd/sys/cdefs.d \
core/sys/freebsd/sys/elf.d core/sys/freebsd/sys/elf32.d \
core/sys/freebsd/sys/elf64.d core/sys/freebsd/sys/elf_common.d \
core/sys/freebsd/sys/event.d core/sys/freebsd/sys/link_elf.d \
core/sys/freebsd/sys/mman.d core/sys/freebsd/sys/mount.d \
- core/sys/freebsd/time.d core/sys/freebsd/unistd.d
+ core/sys/freebsd/sys/sysctl.d core/sys/freebsd/time.d \
+ core/sys/freebsd/unistd.d
DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \
- core/sys/linux/errno.d core/sys/linux/execinfo.d \
+ core/sys/linux/err.d core/sys/linux/errno.d core/sys/linux/execinfo.d \
core/sys/linux/fcntl.d core/sys/linux/ifaddrs.d core/sys/linux/link.d \
core/sys/linux/netinet/in_.d core/sys/linux/netinet/tcp.d \
core/sys/linux/sched.d core/sys/linux/stdio.d core/sys/linux/string.d \
@@ -264,48 +262,54 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/unistd.d
DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
- core/sys/netbsd/execinfo.d core/sys/netbsd/string.d \
+ core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
+ core/sys/netbsd/stdlib.d core/sys/netbsd/string.d \
core/sys/netbsd/sys/elf.d core/sys/netbsd/sys/elf32.d \
core/sys/netbsd/sys/elf64.d core/sys/netbsd/sys/elf_common.d \
core/sys/netbsd/sys/event.d core/sys/netbsd/sys/featuretest.d \
core/sys/netbsd/sys/link_elf.d core/sys/netbsd/sys/mman.d \
- core/sys/netbsd/time.d
+ core/sys/netbsd/sys/sysctl.d core/sys/netbsd/time.d
DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \
+ core/sys/openbsd/err.d core/sys/openbsd/stdlib.d \
core/sys/openbsd/string.d core/sys/openbsd/sys/cdefs.d \
core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \
core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \
core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \
- core/sys/openbsd/time.d
+ core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d \
+ core/sys/openbsd/unistd.d
DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \
core/sys/posix/arpa/inet.d core/sys/posix/config.d \
core/sys/posix/dirent.d core/sys/posix/dlfcn.d core/sys/posix/fcntl.d \
core/sys/posix/grp.d core/sys/posix/iconv.d core/sys/posix/inttypes.d \
- core/sys/posix/libgen.d core/sys/posix/mqueue.d \
- core/sys/posix/net/if_.d core/sys/posix/netdb.d \
- core/sys/posix/netinet/in_.d core/sys/posix/netinet/tcp.d \
- core/sys/posix/poll.d core/sys/posix/pthread.d core/sys/posix/pwd.d \
- core/sys/posix/sched.d core/sys/posix/semaphore.d \
- core/sys/posix/setjmp.d core/sys/posix/signal.d core/sys/posix/spawn.d \
- core/sys/posix/stdio.d core/sys/posix/stdlib.d \
- core/sys/posix/sys/filio.d core/sys/posix/sys/ioccom.d \
- core/sys/posix/sys/ioctl.d core/sys/posix/sys/ipc.d \
- core/sys/posix/sys/mman.d core/sys/posix/sys/msg.d \
- core/sys/posix/sys/resource.d core/sys/posix/sys/select.d \
- core/sys/posix/sys/shm.d core/sys/posix/sys/socket.d \
- core/sys/posix/sys/stat.d core/sys/posix/sys/statvfs.d \
- core/sys/posix/sys/time.d core/sys/posix/sys/ttycom.d \
- core/sys/posix/sys/types.d core/sys/posix/sys/uio.d \
- core/sys/posix/sys/un.d core/sys/posix/sys/utsname.d \
- core/sys/posix/sys/wait.d core/sys/posix/syslog.d \
- core/sys/posix/termios.d core/sys/posix/time.d \
+ core/sys/posix/libgen.d core/sys/posix/locale.d \
+ core/sys/posix/mqueue.d core/sys/posix/net/if_.d \
+ core/sys/posix/netdb.d core/sys/posix/netinet/in_.d \
+ core/sys/posix/netinet/tcp.d core/sys/posix/poll.d \
+ core/sys/posix/pthread.d core/sys/posix/pwd.d core/sys/posix/sched.d \
+ core/sys/posix/semaphore.d core/sys/posix/setjmp.d \
+ core/sys/posix/signal.d core/sys/posix/spawn.d \
+ core/sys/posix/stdc/time.d core/sys/posix/stdio.d \
+ core/sys/posix/stdlib.d core/sys/posix/string.d \
+ core/sys/posix/strings.d core/sys/posix/sys/filio.d \
+ core/sys/posix/sys/ioccom.d core/sys/posix/sys/ioctl.d \
+ core/sys/posix/sys/ipc.d core/sys/posix/sys/mman.d \
+ core/sys/posix/sys/msg.d core/sys/posix/sys/resource.d \
+ core/sys/posix/sys/select.d core/sys/posix/sys/shm.d \
+ core/sys/posix/sys/socket.d core/sys/posix/sys/stat.d \
+ core/sys/posix/sys/statvfs.d core/sys/posix/sys/time.d \
+ core/sys/posix/sys/ttycom.d core/sys/posix/sys/types.d \
+ core/sys/posix/sys/uio.d core/sys/posix/sys/un.d \
+ core/sys/posix/sys/utsname.d core/sys/posix/sys/wait.d \
+ core/sys/posix/syslog.d core/sys/posix/termios.d core/sys/posix/time.d \
core/sys/posix/ucontext.d core/sys/posix/unistd.d \
core/sys/posix/utime.d
DRUNTIME_DSOURCES_SOLARIS = core/sys/solaris/dlfcn.d \
- core/sys/solaris/elf.d core/sys/solaris/execinfo.d \
- core/sys/solaris/libelf.d core/sys/solaris/link.d \
+ core/sys/solaris/elf.d core/sys/solaris/err.d \
+ core/sys/solaris/execinfo.d core/sys/solaris/libelf.d \
+ core/sys/solaris/link.d core/sys/solaris/stdlib.d \
core/sys/solaris/sys/elf.d core/sys/solaris/sys/elf_386.d \
core/sys/solaris/sys/elf_SPARC.d core/sys/solaris/sys/elf_amd64.d \
core/sys/solaris/sys/elf_notes.d core/sys/solaris/sys/elftypes.d \
@@ -371,30 +375,31 @@ DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \
core/sys/windows/rpcdcep.d core/sys/windows/rpcndr.d \
core/sys/windows/rpcnsi.d core/sys/windows/rpcnsip.d \
core/sys/windows/rpcnterr.d core/sys/windows/schannel.d \
- core/sys/windows/secext.d core/sys/windows/security.d \
- core/sys/windows/servprov.d core/sys/windows/setupapi.d \
- core/sys/windows/shellapi.d core/sys/windows/shldisp.d \
- core/sys/windows/shlguid.d core/sys/windows/shlobj.d \
- core/sys/windows/shlwapi.d core/sys/windows/snmp.d \
- core/sys/windows/sql.d core/sys/windows/sqlext.d \
- core/sys/windows/sqltypes.d core/sys/windows/sqlucode.d \
- core/sys/windows/sspi.d core/sys/windows/stacktrace.d \
- core/sys/windows/stat.d core/sys/windows/subauth.d \
- core/sys/windows/threadaux.d core/sys/windows/tlhelp32.d \
- core/sys/windows/tmschema.d core/sys/windows/unknwn.d \
- core/sys/windows/uuid.d core/sys/windows/vfw.d \
- core/sys/windows/w32api.d core/sys/windows/winbase.d \
- core/sys/windows/winber.d core/sys/windows/wincon.d \
- core/sys/windows/wincrypt.d core/sys/windows/windef.d \
- core/sys/windows/windows.d core/sys/windows/winerror.d \
- core/sys/windows/wingdi.d core/sys/windows/winhttp.d \
- core/sys/windows/wininet.d core/sys/windows/winioctl.d \
- core/sys/windows/winldap.d core/sys/windows/winnetwk.d \
- core/sys/windows/winnls.d core/sys/windows/winnt.d \
- core/sys/windows/winperf.d core/sys/windows/winreg.d \
- core/sys/windows/winsock2.d core/sys/windows/winspool.d \
- core/sys/windows/winsvc.d core/sys/windows/winuser.d \
- core/sys/windows/winver.d core/sys/windows/wtsapi32.d \
- core/sys/windows/wtypes.d
+ core/sys/windows/sdkddkver.d core/sys/windows/secext.d \
+ core/sys/windows/security.d core/sys/windows/servprov.d \
+ core/sys/windows/setupapi.d core/sys/windows/shellapi.d \
+ core/sys/windows/shldisp.d core/sys/windows/shlguid.d \
+ core/sys/windows/shlobj.d core/sys/windows/shlwapi.d \
+ core/sys/windows/snmp.d core/sys/windows/sql.d \
+ core/sys/windows/sqlext.d core/sys/windows/sqltypes.d \
+ core/sys/windows/sqlucode.d core/sys/windows/sspi.d \
+ core/sys/windows/stacktrace.d core/sys/windows/stat.d \
+ core/sys/windows/stdc/malloc.d core/sys/windows/stdc/time.d \
+ core/sys/windows/subauth.d core/sys/windows/threadaux.d \
+ core/sys/windows/tlhelp32.d core/sys/windows/tmschema.d \
+ core/sys/windows/unknwn.d core/sys/windows/uuid.d \
+ core/sys/windows/vfw.d core/sys/windows/w32api.d \
+ core/sys/windows/winbase.d core/sys/windows/winber.d \
+ core/sys/windows/wincon.d core/sys/windows/wincrypt.d \
+ core/sys/windows/windef.d core/sys/windows/windows.d \
+ core/sys/windows/winerror.d core/sys/windows/wingdi.d \
+ core/sys/windows/winhttp.d core/sys/windows/wininet.d \
+ core/sys/windows/winioctl.d core/sys/windows/winldap.d \
+ core/sys/windows/winnetwk.d core/sys/windows/winnls.d \
+ core/sys/windows/winnt.d core/sys/windows/winperf.d \
+ core/sys/windows/winreg.d core/sys/windows/winsock2.d \
+ core/sys/windows/winspool.d core/sys/windows/winsvc.d \
+ core/sys/windows/winuser.d core/sys/windows/winver.d \
+ core/sys/windows/wtsapi32.d core/sys/windows/wtypes.d
DRUNTIME_DISOURCES = __entrypoint.di __main.di
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 99ee8b9..cb2e372 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
# Makefile for the D runtime library.
-# Copyright (C) 2012-2020 Free Software Foundation, Inc.
+# Copyright (C) 2012-2021 Free Software Foundation, Inc.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -117,7 +117,9 @@ target_triplet = @target@
@DRUNTIME_OS_NETBSD_TRUE@am__append_6 = $(DRUNTIME_DSOURCES_NETBSD)
@DRUNTIME_OS_OPENBSD_TRUE@am__append_7 = $(DRUNTIME_DSOURCES_OPENBSD)
@DRUNTIME_OS_LINUX_TRUE@am__append_8 = $(DRUNTIME_DSOURCES_LINUX)
-@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS)
+@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/msvc.c
+
@DRUNTIME_OS_SOLARIS_TRUE@am__append_10 = $(DRUNTIME_DSOURCES_SOLARIS)
# CPU specific sources
@DRUNTIME_CPU_AARCH64_TRUE@am__append_11 = config/aarch64/switchcontext.S
@@ -188,28 +190,32 @@ am__dirstamp = $(am__leading_dot)dirstamp
am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
core/checkedint.lo core/cpuid.lo core/demangle.lo \
core/exception.lo core/internal/abort.lo \
- core/internal/arrayop.lo core/internal/convert.lo \
- core/internal/hash.lo core/internal/spinlock.lo \
- core/internal/string.lo core/internal/traits.lo core/math.lo \
- core/memory.lo core/runtime.lo core/simd.lo \
- core/stdc/assert_.lo core/stdc/complex.lo core/stdc/config.lo \
- core/stdc/ctype.lo core/stdc/errno.lo core/stdc/fenv.lo \
- core/stdc/float_.lo core/stdc/inttypes.lo core/stdc/limits.lo \
- core/stdc/locale.lo core/stdc/math.lo core/stdc/signal.lo \
- core/stdc/stdarg.lo core/stdc/stddef.lo core/stdc/stdint.lo \
- core/stdc/stdio.lo core/stdc/stdlib.lo core/stdc/string.lo \
- core/stdc/tgmath.lo core/stdc/time.lo core/stdc/wchar_.lo \
- core/stdc/wctype.lo core/sync/barrier.lo \
- core/sync/condition.lo core/sync/config.lo \
- core/sync/exception.lo core/sync/mutex.lo core/sync/rwmutex.lo \
- core/sync/semaphore.lo core/thread.lo core/time.lo \
- core/vararg.lo gc/bits.lo gc/config.lo gc/gcinterface.lo \
+ core/internal/arrayop.lo core/internal/attributes.lo \
+ core/internal/convert.lo core/internal/hash.lo \
+ core/internal/spinlock.lo core/internal/string.lo \
+ core/internal/traits.lo core/math.lo core/memory.lo \
+ core/runtime.lo core/simd.lo core/stdc/assert_.lo \
+ core/stdc/complex.lo core/stdc/config.lo core/stdc/ctype.lo \
+ core/stdc/errno.lo core/stdc/fenv.lo core/stdc/float_.lo \
+ core/stdc/inttypes.lo core/stdc/limits.lo core/stdc/locale.lo \
+ core/stdc/math.lo core/stdc/signal.lo core/stdc/stdarg.lo \
+ core/stdc/stddef.lo core/stdc/stdint.lo core/stdc/stdio.lo \
+ core/stdc/stdlib.lo core/stdc/string.lo core/stdc/tgmath.lo \
+ core/stdc/time.lo core/stdc/wchar_.lo core/stdc/wctype.lo \
+ core/sync/barrier.lo core/sync/condition.lo \
+ core/sync/config.lo core/sync/exception.lo core/sync/mutex.lo \
+ core/sync/rwmutex.lo core/sync/semaphore.lo \
+ core/thread/context.lo core/thread/fiber.lo \
+ core/thread/osthread.lo core/thread/package.lo \
+ core/thread/threadbase.lo core/thread/threadgroup.lo \
+ core/thread/types.lo core/time.lo core/vararg.lo \
+ core/volatile.lo gc/bits.lo gc/config.lo gc/gcinterface.lo \
gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \
- gc/pooltable.lo gc/proxy.lo gcc/attribute.lo gcc/backtrace.lo \
- gcc/builtins.lo gcc/deh.lo gcc/emutls.lo gcc/gthread.lo \
- gcc/sections/android.lo gcc/sections/elf_shared.lo \
- gcc/sections/osx.lo gcc/sections/package.lo \
- gcc/sections/win32.lo gcc/sections/win64.lo gcc/unwind/arm.lo \
+ gc/pooltable.lo gc/proxy.lo gcc/attribute.lo gcc/attributes.lo \
+ gcc/backtrace.lo gcc/builtins.lo gcc/deh.lo gcc/emutls.lo \
+ gcc/gthread.lo gcc/sections/common.lo gcc/sections/elf.lo \
+ gcc/sections/macho.lo gcc/sections/package.lo \
+ gcc/sections/pecoff.lo gcc/unwind/arm.lo \
gcc/unwind/arm_common.lo gcc/unwind/c6x.lo \
gcc/unwind/generic.lo gcc/unwind/package.lo gcc/unwind/pe.lo \
object.lo rt/aApply.lo rt/aApplyR.lo rt/aaA.lo rt/adi.lo \
@@ -217,43 +223,26 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
rt/config.lo rt/critical_.lo rt/deh.lo rt/dmain2.lo \
rt/invariant.lo rt/lifetime.lo rt/memory.lo rt/minfo.lo \
rt/monitor_.lo rt/obj.lo rt/qsort.lo rt/sections.lo \
- rt/switch_.lo rt/tlsgc.lo rt/typeinfo/ti_Acdouble.lo \
- rt/typeinfo/ti_Acfloat.lo rt/typeinfo/ti_Acreal.lo \
- rt/typeinfo/ti_Adouble.lo rt/typeinfo/ti_Afloat.lo \
- rt/typeinfo/ti_Ag.lo rt/typeinfo/ti_Aint.lo \
- rt/typeinfo/ti_Along.lo rt/typeinfo/ti_Areal.lo \
- rt/typeinfo/ti_Ashort.lo rt/typeinfo/ti_C.lo \
- rt/typeinfo/ti_byte.lo rt/typeinfo/ti_cdouble.lo \
- rt/typeinfo/ti_cent.lo rt/typeinfo/ti_cfloat.lo \
- rt/typeinfo/ti_char.lo rt/typeinfo/ti_creal.lo \
- rt/typeinfo/ti_dchar.lo rt/typeinfo/ti_delegate.lo \
- rt/typeinfo/ti_double.lo rt/typeinfo/ti_float.lo \
- rt/typeinfo/ti_idouble.lo rt/typeinfo/ti_ifloat.lo \
- rt/typeinfo/ti_int.lo rt/typeinfo/ti_ireal.lo \
- rt/typeinfo/ti_long.lo rt/typeinfo/ti_n.lo \
- rt/typeinfo/ti_ptr.lo rt/typeinfo/ti_real.lo \
- rt/typeinfo/ti_short.lo rt/typeinfo/ti_ubyte.lo \
- rt/typeinfo/ti_ucent.lo rt/typeinfo/ti_uint.lo \
- rt/typeinfo/ti_ulong.lo rt/typeinfo/ti_ushort.lo \
- rt/typeinfo/ti_void.lo rt/typeinfo/ti_wchar.lo \
- rt/util/array.lo rt/util/container/array.lo \
- rt/util/container/common.lo rt/util/container/hashtab.lo \
- rt/util/container/treap.lo rt/util/random.lo \
- rt/util/typeinfo.lo rt/util/utf.lo
+ rt/switch_.lo rt/tlsgc.lo rt/util/array.lo \
+ rt/util/container/array.lo rt/util/container/common.lo \
+ rt/util/container/hashtab.lo rt/util/container/treap.lo \
+ rt/util/random.lo rt/util/typeinfo.lo rt/util/utf.lo
am__objects_2 = core/stdc/libgdruntime_la-errno_.lo
am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
core/sys/posix/config.lo core/sys/posix/dirent.lo \
core/sys/posix/dlfcn.lo core/sys/posix/fcntl.lo \
core/sys/posix/grp.lo core/sys/posix/iconv.lo \
core/sys/posix/inttypes.lo core/sys/posix/libgen.lo \
- core/sys/posix/mqueue.lo core/sys/posix/net/if_.lo \
- core/sys/posix/netdb.lo core/sys/posix/netinet/in_.lo \
- core/sys/posix/netinet/tcp.lo core/sys/posix/poll.lo \
- core/sys/posix/pthread.lo core/sys/posix/pwd.lo \
- core/sys/posix/sched.lo core/sys/posix/semaphore.lo \
- core/sys/posix/setjmp.lo core/sys/posix/signal.lo \
- core/sys/posix/spawn.lo core/sys/posix/stdio.lo \
- core/sys/posix/stdlib.lo core/sys/posix/sys/filio.lo \
+ core/sys/posix/locale.lo core/sys/posix/mqueue.lo \
+ core/sys/posix/net/if_.lo core/sys/posix/netdb.lo \
+ core/sys/posix/netinet/in_.lo core/sys/posix/netinet/tcp.lo \
+ core/sys/posix/poll.lo core/sys/posix/pthread.lo \
+ core/sys/posix/pwd.lo core/sys/posix/sched.lo \
+ core/sys/posix/semaphore.lo core/sys/posix/setjmp.lo \
+ core/sys/posix/signal.lo core/sys/posix/spawn.lo \
+ core/sys/posix/stdc/time.lo core/sys/posix/stdio.lo \
+ core/sys/posix/stdlib.lo core/sys/posix/string.lo \
+ core/sys/posix/strings.lo core/sys/posix/sys/filio.lo \
core/sys/posix/sys/ioccom.lo core/sys/posix/sys/ioctl.lo \
core/sys/posix/sys/ipc.lo core/sys/posix/sys/mman.lo \
core/sys/posix/sys/msg.lo core/sys/posix/sys/resource.lo \
@@ -267,21 +256,27 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
core/sys/posix/time.lo core/sys/posix/ucontext.lo \
core/sys/posix/unistd.lo core/sys/posix/utime.lo
@DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3)
-am__objects_5 = core/sys/darwin/crt_externs.lo \
- core/sys/darwin/dlfcn.lo core/sys/darwin/execinfo.lo \
+am__objects_5 = core/sys/darwin/config.lo \
+ core/sys/darwin/crt_externs.lo core/sys/darwin/dlfcn.lo \
+ core/sys/darwin/err.lo core/sys/darwin/execinfo.lo \
+ core/sys/darwin/fcntl.lo core/sys/darwin/ifaddrs.lo \
core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \
core/sys/darwin/mach/kern_return.lo \
- core/sys/darwin/mach/loader.lo core/sys/darwin/mach/port.lo \
- core/sys/darwin/mach/semaphore.lo \
+ core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \
+ core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \
+ core/sys/darwin/mach/stab.lo \
core/sys/darwin/mach/thread_act.lo \
core/sys/darwin/netinet/in_.lo core/sys/darwin/pthread.lo \
- core/sys/darwin/string.lo core/sys/darwin/sys/cdefs.lo \
- core/sys/darwin/sys/event.lo core/sys/darwin/sys/mman.lo
+ core/sys/darwin/stdlib.lo core/sys/darwin/string.lo \
+ core/sys/darwin/sys/attr.lo core/sys/darwin/sys/cdefs.lo \
+ core/sys/darwin/sys/event.lo core/sys/darwin/sys/mman.lo \
+ core/sys/darwin/sys/sysctl.lo
@DRUNTIME_OS_DARWIN_TRUE@am__objects_6 = $(am__objects_5)
am__objects_7 = core/sys/dragonflybsd/dlfcn.lo \
- core/sys/dragonflybsd/execinfo.lo \
+ core/sys/dragonflybsd/err.lo core/sys/dragonflybsd/execinfo.lo \
core/sys/dragonflybsd/netinet/in_.lo \
core/sys/dragonflybsd/pthread_np.lo \
+ core/sys/dragonflybsd/stdlib.lo \
core/sys/dragonflybsd/string.lo \
core/sys/dragonflybsd/sys/_bitset.lo \
core/sys/dragonflybsd/sys/_cpuset.lo \
@@ -294,14 +289,17 @@ am__objects_7 = core/sys/dragonflybsd/dlfcn.lo \
core/sys/dragonflybsd/sys/link_elf.lo \
core/sys/dragonflybsd/sys/mman.lo \
core/sys/dragonflybsd/sys/socket.lo \
+ core/sys/dragonflybsd/sys/sysctl.lo \
core/sys/dragonflybsd/time.lo
@DRUNTIME_OS_DRAGONFLYBSD_TRUE@am__objects_8 = $(am__objects_7)
-am__objects_9 = core/sys/bionic/fcntl.lo core/sys/bionic/string.lo \
+am__objects_9 = core/sys/bionic/err.lo core/sys/bionic/fcntl.lo \
+ core/sys/bionic/stdlib.lo core/sys/bionic/string.lo \
core/sys/bionic/unistd.lo
@DRUNTIME_OS_ANDROID_TRUE@am__objects_10 = $(am__objects_9)
am__objects_11 = core/sys/freebsd/config.lo core/sys/freebsd/dlfcn.lo \
- core/sys/freebsd/execinfo.lo core/sys/freebsd/netinet/in_.lo \
- core/sys/freebsd/pthread_np.lo core/sys/freebsd/string.lo \
+ core/sys/freebsd/err.lo core/sys/freebsd/execinfo.lo \
+ core/sys/freebsd/netinet/in_.lo core/sys/freebsd/pthread_np.lo \
+ core/sys/freebsd/stdlib.lo core/sys/freebsd/string.lo \
core/sys/freebsd/sys/_bitset.lo \
core/sys/freebsd/sys/_cpuset.lo core/sys/freebsd/sys/cdefs.lo \
core/sys/freebsd/sys/elf.lo core/sys/freebsd/sys/elf32.lo \
@@ -309,38 +307,43 @@ am__objects_11 = core/sys/freebsd/config.lo core/sys/freebsd/dlfcn.lo \
core/sys/freebsd/sys/elf_common.lo \
core/sys/freebsd/sys/event.lo core/sys/freebsd/sys/link_elf.lo \
core/sys/freebsd/sys/mman.lo core/sys/freebsd/sys/mount.lo \
- core/sys/freebsd/time.lo core/sys/freebsd/unistd.lo
+ core/sys/freebsd/sys/sysctl.lo core/sys/freebsd/time.lo \
+ core/sys/freebsd/unistd.lo
@DRUNTIME_OS_FREEBSD_TRUE@am__objects_12 = $(am__objects_11)
-am__objects_13 = core/sys/netbsd/dlfcn.lo core/sys/netbsd/execinfo.lo \
+am__objects_13 = core/sys/netbsd/dlfcn.lo core/sys/netbsd/err.lo \
+ core/sys/netbsd/execinfo.lo core/sys/netbsd/stdlib.lo \
core/sys/netbsd/string.lo core/sys/netbsd/sys/elf.lo \
core/sys/netbsd/sys/elf32.lo core/sys/netbsd/sys/elf64.lo \
core/sys/netbsd/sys/elf_common.lo core/sys/netbsd/sys/event.lo \
core/sys/netbsd/sys/featuretest.lo \
core/sys/netbsd/sys/link_elf.lo core/sys/netbsd/sys/mman.lo \
- core/sys/netbsd/time.lo
+ core/sys/netbsd/sys/sysctl.lo core/sys/netbsd/time.lo
@DRUNTIME_OS_NETBSD_TRUE@am__objects_14 = $(am__objects_13)
-am__objects_15 = core/sys/openbsd/dlfcn.lo core/sys/openbsd/string.lo \
+am__objects_15 = core/sys/openbsd/dlfcn.lo core/sys/openbsd/err.lo \
+ core/sys/openbsd/stdlib.lo core/sys/openbsd/string.lo \
core/sys/openbsd/sys/cdefs.lo core/sys/openbsd/sys/elf.lo \
core/sys/openbsd/sys/elf32.lo core/sys/openbsd/sys/elf64.lo \
core/sys/openbsd/sys/elf_common.lo \
core/sys/openbsd/sys/link_elf.lo core/sys/openbsd/sys/mman.lo \
- core/sys/openbsd/time.lo
+ core/sys/openbsd/sys/sysctl.lo core/sys/openbsd/time.lo \
+ core/sys/openbsd/unistd.lo
@DRUNTIME_OS_OPENBSD_TRUE@am__objects_16 = $(am__objects_15)
am__objects_17 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
core/sys/linux/elf.lo core/sys/linux/epoll.lo \
- core/sys/linux/errno.lo core/sys/linux/execinfo.lo \
- core/sys/linux/fcntl.lo core/sys/linux/ifaddrs.lo \
- core/sys/linux/link.lo core/sys/linux/netinet/in_.lo \
- core/sys/linux/netinet/tcp.lo core/sys/linux/sched.lo \
- core/sys/linux/stdio.lo core/sys/linux/string.lo \
- core/sys/linux/sys/auxv.lo core/sys/linux/sys/eventfd.lo \
- core/sys/linux/sys/file.lo core/sys/linux/sys/inotify.lo \
- core/sys/linux/sys/mman.lo core/sys/linux/sys/prctl.lo \
- core/sys/linux/sys/signalfd.lo core/sys/linux/sys/socket.lo \
- core/sys/linux/sys/sysinfo.lo core/sys/linux/sys/time.lo \
- core/sys/linux/sys/xattr.lo core/sys/linux/termios.lo \
- core/sys/linux/time.lo core/sys/linux/timerfd.lo \
- core/sys/linux/tipc.lo core/sys/linux/unistd.lo
+ core/sys/linux/err.lo core/sys/linux/errno.lo \
+ core/sys/linux/execinfo.lo core/sys/linux/fcntl.lo \
+ core/sys/linux/ifaddrs.lo core/sys/linux/link.lo \
+ core/sys/linux/netinet/in_.lo core/sys/linux/netinet/tcp.lo \
+ core/sys/linux/sched.lo core/sys/linux/stdio.lo \
+ core/sys/linux/string.lo core/sys/linux/sys/auxv.lo \
+ core/sys/linux/sys/eventfd.lo core/sys/linux/sys/file.lo \
+ core/sys/linux/sys/inotify.lo core/sys/linux/sys/mman.lo \
+ core/sys/linux/sys/prctl.lo core/sys/linux/sys/signalfd.lo \
+ core/sys/linux/sys/socket.lo core/sys/linux/sys/sysinfo.lo \
+ core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.lo \
+ core/sys/linux/termios.lo core/sys/linux/time.lo \
+ core/sys/linux/timerfd.lo core/sys/linux/tipc.lo \
+ core/sys/linux/unistd.lo
@DRUNTIME_OS_LINUX_TRUE@am__objects_18 = $(am__objects_17)
am__objects_19 = core/sys/windows/accctrl.lo \
core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \
@@ -400,35 +403,39 @@ am__objects_19 = core/sys/windows/accctrl.lo \
core/sys/windows/rpcdce2.lo core/sys/windows/rpcdcep.lo \
core/sys/windows/rpcndr.lo core/sys/windows/rpcnsi.lo \
core/sys/windows/rpcnsip.lo core/sys/windows/rpcnterr.lo \
- core/sys/windows/schannel.lo core/sys/windows/secext.lo \
- core/sys/windows/security.lo core/sys/windows/servprov.lo \
- core/sys/windows/setupapi.lo core/sys/windows/shellapi.lo \
- core/sys/windows/shldisp.lo core/sys/windows/shlguid.lo \
- core/sys/windows/shlobj.lo core/sys/windows/shlwapi.lo \
- core/sys/windows/snmp.lo core/sys/windows/sql.lo \
- core/sys/windows/sqlext.lo core/sys/windows/sqltypes.lo \
- core/sys/windows/sqlucode.lo core/sys/windows/sspi.lo \
- core/sys/windows/stacktrace.lo core/sys/windows/stat.lo \
- core/sys/windows/subauth.lo core/sys/windows/threadaux.lo \
- core/sys/windows/tlhelp32.lo core/sys/windows/tmschema.lo \
- core/sys/windows/unknwn.lo core/sys/windows/uuid.lo \
- core/sys/windows/vfw.lo core/sys/windows/w32api.lo \
- core/sys/windows/winbase.lo core/sys/windows/winber.lo \
- core/sys/windows/wincon.lo core/sys/windows/wincrypt.lo \
- core/sys/windows/windef.lo core/sys/windows/windows.lo \
- core/sys/windows/winerror.lo core/sys/windows/wingdi.lo \
- core/sys/windows/winhttp.lo core/sys/windows/wininet.lo \
- core/sys/windows/winioctl.lo core/sys/windows/winldap.lo \
- core/sys/windows/winnetwk.lo core/sys/windows/winnls.lo \
- core/sys/windows/winnt.lo core/sys/windows/winperf.lo \
- core/sys/windows/winreg.lo core/sys/windows/winsock2.lo \
- core/sys/windows/winspool.lo core/sys/windows/winsvc.lo \
- core/sys/windows/winuser.lo core/sys/windows/winver.lo \
- core/sys/windows/wtsapi32.lo core/sys/windows/wtypes.lo
-@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19)
+ core/sys/windows/schannel.lo core/sys/windows/sdkddkver.lo \
+ core/sys/windows/secext.lo core/sys/windows/security.lo \
+ core/sys/windows/servprov.lo core/sys/windows/setupapi.lo \
+ core/sys/windows/shellapi.lo core/sys/windows/shldisp.lo \
+ core/sys/windows/shlguid.lo core/sys/windows/shlobj.lo \
+ core/sys/windows/shlwapi.lo core/sys/windows/snmp.lo \
+ core/sys/windows/sql.lo core/sys/windows/sqlext.lo \
+ core/sys/windows/sqltypes.lo core/sys/windows/sqlucode.lo \
+ core/sys/windows/sspi.lo core/sys/windows/stacktrace.lo \
+ core/sys/windows/stat.lo core/sys/windows/stdc/malloc.lo \
+ core/sys/windows/stdc/time.lo core/sys/windows/subauth.lo \
+ core/sys/windows/threadaux.lo core/sys/windows/tlhelp32.lo \
+ core/sys/windows/tmschema.lo core/sys/windows/unknwn.lo \
+ core/sys/windows/uuid.lo core/sys/windows/vfw.lo \
+ core/sys/windows/w32api.lo core/sys/windows/winbase.lo \
+ core/sys/windows/winber.lo core/sys/windows/wincon.lo \
+ core/sys/windows/wincrypt.lo core/sys/windows/windef.lo \
+ core/sys/windows/windows.lo core/sys/windows/winerror.lo \
+ core/sys/windows/wingdi.lo core/sys/windows/winhttp.lo \
+ core/sys/windows/wininet.lo core/sys/windows/winioctl.lo \
+ core/sys/windows/winldap.lo core/sys/windows/winnetwk.lo \
+ core/sys/windows/winnls.lo core/sys/windows/winnt.lo \
+ core/sys/windows/winperf.lo core/sys/windows/winreg.lo \
+ core/sys/windows/winsock2.lo core/sys/windows/winspool.lo \
+ core/sys/windows/winsvc.lo core/sys/windows/winuser.lo \
+ core/sys/windows/winver.lo core/sys/windows/wtsapi32.lo \
+ core/sys/windows/wtypes.lo
+@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_la-msvc.lo
am__objects_21 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
- core/sys/solaris/execinfo.lo core/sys/solaris/libelf.lo \
- core/sys/solaris/link.lo core/sys/solaris/sys/elf.lo \
+ core/sys/solaris/err.lo core/sys/solaris/execinfo.lo \
+ core/sys/solaris/libelf.lo core/sys/solaris/link.lo \
+ core/sys/solaris/stdlib.lo core/sys/solaris/sys/elf.lo \
core/sys/solaris/sys/elf_386.lo \
core/sys/solaris/sys/elf_SPARC.lo \
core/sys/solaris/sys/elf_amd64.lo \
@@ -459,24 +466,26 @@ am_libgdruntime_la_OBJECTS = $(am__objects_33)
libgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__objects_34 = core/stdc/libgdruntime_convenience_la-errno_.lo
-@DRUNTIME_CPU_AARCH64_TRUE@am__objects_35 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_ARM_TRUE@am__objects_36 = config/arm/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_MIPS_TRUE@am__objects_37 = config/mips/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_POWERPC_TRUE@am__objects_38 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_39 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_40 = config/x86/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_41 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
-@DRUNTIME_CPU_S390_TRUE@am__objects_42 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
-am__objects_43 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
+@DRUNTIME_OS_MINGW_TRUE@am__objects_35 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_convenience_la-msvc.lo
+@DRUNTIME_CPU_AARCH64_TRUE@am__objects_36 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_ARM_TRUE@am__objects_37 = config/arm/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_MIPS_TRUE@am__objects_38 = config/mips/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_POWERPC_TRUE@am__objects_39 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_40 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_41 = config/x86/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_42 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
+@DRUNTIME_CPU_S390_TRUE@am__objects_43 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
+am__objects_44 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
$(am__objects_10) $(am__objects_12) $(am__objects_14) \
- $(am__objects_16) $(am__objects_18) $(am__objects_20) \
- $(am__objects_22) $(am__objects_35) $(am__objects_36) \
- $(am__objects_37) $(am__objects_38) $(am__objects_39) \
- $(am__objects_40) $(am__objects_41) $(am__objects_42)
-am__objects_44 = $(am__objects_1) $(am__objects_34) $(am__objects_43) \
+ $(am__objects_16) $(am__objects_18) $(am__objects_35) \
+ $(am__objects_22) $(am__objects_36) $(am__objects_37) \
+ $(am__objects_38) $(am__objects_39) $(am__objects_40) \
+ $(am__objects_41) $(am__objects_42) $(am__objects_43)
+am__objects_45 = $(am__objects_1) $(am__objects_34) $(am__objects_44) \
$(am__objects_32)
-am__objects_45 = $(am__objects_44)
-am_libgdruntime_convenience_la_OBJECTS = $(am__objects_45)
+am__objects_46 = $(am__objects_45)
+am_libgdruntime_convenience_la_OBJECTS = $(am__objects_46)
libgdruntime_convenience_la_OBJECTS = \
$(am_libgdruntime_convenience_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
@@ -631,6 +640,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
+SECTION_FLAGS = @SECTION_FLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -658,6 +668,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -687,6 +699,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -719,8 +732,8 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) -I .
# D flags for compilation
AM_DFLAGS = \
- $(phobos_compiler_pic_flag) \
- $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
+ $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
@@ -791,7 +804,8 @@ libgdruntime_convenience_la_LINK = $(libgdruntime_la_LINK)
DRUNTIME_CSOURCES = core/stdc/errno_.c
DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/checkedint.d core/cpuid.d core/demangle.d core/exception.d \
- core/internal/abort.d core/internal/arrayop.d core/internal/convert.d \
+ core/internal/abort.d core/internal/arrayop.d \
+ core/internal/attributes.d core/internal/convert.d \
core/internal/hash.d core/internal/spinlock.d core/internal/string.d \
core/internal/traits.d core/math.d core/memory.d core/runtime.d \
core/simd.d core/stdc/assert_.d core/stdc/complex.d core/stdc/config.d \
@@ -803,33 +817,21 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/stdc/tgmath.d core/stdc/time.d core/stdc/wchar_.d \
core/stdc/wctype.d core/sync/barrier.d core/sync/condition.d \
core/sync/config.d core/sync/exception.d core/sync/mutex.d \
- core/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \
- core/vararg.d gc/bits.d gc/config.d gc/gcinterface.d \
- gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.d gc/pooltable.d \
- gc/proxy.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \
- gcc/emutls.d gcc/gthread.d gcc/sections/android.d \
- gcc/sections/elf_shared.d gcc/sections/osx.d gcc/sections/package.d \
- gcc/sections/win32.d gcc/sections/win64.d gcc/unwind/arm.d \
+ core/sync/rwmutex.d core/sync/semaphore.d core/thread/context.d \
+ core/thread/fiber.d core/thread/osthread.d core/thread/package.d \
+ core/thread/threadbase.d core/thread/threadgroup.d core/thread/types.d \
+ core/time.d core/vararg.d core/volatile.d gc/bits.d gc/config.d \
+ gc/gcinterface.d gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.d \
+ gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/attributes.d \
+ gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
+ gcc/sections/common.d gcc/sections/elf.d gcc/sections/macho.d \
+ gcc/sections/package.d gcc/sections/pecoff.d gcc/unwind/arm.d \
gcc/unwind/arm_common.d gcc/unwind/c6x.d gcc/unwind/generic.d \
gcc/unwind/package.d gcc/unwind/pe.d object.d rt/aApply.d rt/aApplyR.d \
rt/aaA.d rt/adi.d rt/arrayassign.d rt/arraycast.d rt/arraycat.d \
rt/cast_.d rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d \
rt/invariant.d rt/lifetime.d rt/memory.d rt/minfo.d rt/monitor_.d \
rt/obj.d rt/qsort.d rt/sections.d rt/switch_.d rt/tlsgc.d \
- rt/typeinfo/ti_Acdouble.d rt/typeinfo/ti_Acfloat.d \
- rt/typeinfo/ti_Acreal.d rt/typeinfo/ti_Adouble.d \
- rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d rt/typeinfo/ti_Aint.d \
- rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d rt/typeinfo/ti_Ashort.d \
- rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d rt/typeinfo/ti_cdouble.d \
- rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d rt/typeinfo/ti_char.d \
- rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \
- rt/typeinfo/ti_delegate.d rt/typeinfo/ti_double.d \
- rt/typeinfo/ti_float.d rt/typeinfo/ti_idouble.d \
- rt/typeinfo/ti_ifloat.d rt/typeinfo/ti_int.d rt/typeinfo/ti_ireal.d \
- rt/typeinfo/ti_long.d rt/typeinfo/ti_n.d rt/typeinfo/ti_ptr.d \
- rt/typeinfo/ti_real.d rt/typeinfo/ti_short.d rt/typeinfo/ti_ubyte.d \
- rt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \
- rt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \
rt/util/array.d rt/util/container/array.d rt/util/container/common.d \
rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \
rt/util/typeinfo.d rt/util/utf.d
@@ -837,22 +839,28 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
core/stdcpp/typeinfo.d
-DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \
+DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \
+ core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \
core/sys/bionic/string.d core/sys/bionic/unistd.d
-DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \
- core/sys/darwin/dlfcn.d core/sys/darwin/execinfo.d \
+DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \
+ core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \
+ core/sys/darwin/err.d core/sys/darwin/execinfo.d \
+ core/sys/darwin/fcntl.d core/sys/darwin/ifaddrs.d \
core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \
core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \
- core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \
+ core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \
+ core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \
core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \
- core/sys/darwin/pthread.d core/sys/darwin/string.d \
+ core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \
+ core/sys/darwin/string.d core/sys/darwin/sys/attr.d \
core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \
- core/sys/darwin/sys/mman.d
+ core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d
DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
- core/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \
- core/sys/dragonflybsd/pthread_np.d core/sys/dragonflybsd/string.d \
+ core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \
+ core/sys/dragonflybsd/netinet/in_.d core/sys/dragonflybsd/pthread_np.d \
+ core/sys/dragonflybsd/stdlib.d core/sys/dragonflybsd/string.d \
core/sys/dragonflybsd/sys/_bitset.d \
core/sys/dragonflybsd/sys/_cpuset.d core/sys/dragonflybsd/sys/cdefs.d \
core/sys/dragonflybsd/sys/elf.d core/sys/dragonflybsd/sys/elf32.d \
@@ -860,22 +868,24 @@ DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
core/sys/dragonflybsd/sys/elf_common.d \
core/sys/dragonflybsd/sys/event.d core/sys/dragonflybsd/sys/link_elf.d \
core/sys/dragonflybsd/sys/mman.d core/sys/dragonflybsd/sys/socket.d \
- core/sys/dragonflybsd/time.d
+ core/sys/dragonflybsd/sys/sysctl.d core/sys/dragonflybsd/time.d
DRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/config.d \
- core/sys/freebsd/dlfcn.d core/sys/freebsd/execinfo.d \
- core/sys/freebsd/netinet/in_.d core/sys/freebsd/pthread_np.d \
+ core/sys/freebsd/dlfcn.d core/sys/freebsd/err.d \
+ core/sys/freebsd/execinfo.d core/sys/freebsd/netinet/in_.d \
+ core/sys/freebsd/pthread_np.d core/sys/freebsd/stdlib.d \
core/sys/freebsd/string.d core/sys/freebsd/sys/_bitset.d \
core/sys/freebsd/sys/_cpuset.d core/sys/freebsd/sys/cdefs.d \
core/sys/freebsd/sys/elf.d core/sys/freebsd/sys/elf32.d \
core/sys/freebsd/sys/elf64.d core/sys/freebsd/sys/elf_common.d \
core/sys/freebsd/sys/event.d core/sys/freebsd/sys/link_elf.d \
core/sys/freebsd/sys/mman.d core/sys/freebsd/sys/mount.d \
- core/sys/freebsd/time.d core/sys/freebsd/unistd.d
+ core/sys/freebsd/sys/sysctl.d core/sys/freebsd/time.d \
+ core/sys/freebsd/unistd.d
DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \
- core/sys/linux/errno.d core/sys/linux/execinfo.d \
+ core/sys/linux/err.d core/sys/linux/errno.d core/sys/linux/execinfo.d \
core/sys/linux/fcntl.d core/sys/linux/ifaddrs.d core/sys/linux/link.d \
core/sys/linux/netinet/in_.d core/sys/linux/netinet/tcp.d \
core/sys/linux/sched.d core/sys/linux/stdio.d core/sys/linux/string.d \
@@ -889,48 +899,54 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/unistd.d
DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
- core/sys/netbsd/execinfo.d core/sys/netbsd/string.d \
+ core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
+ core/sys/netbsd/stdlib.d core/sys/netbsd/string.d \
core/sys/netbsd/sys/elf.d core/sys/netbsd/sys/elf32.d \
core/sys/netbsd/sys/elf64.d core/sys/netbsd/sys/elf_common.d \
core/sys/netbsd/sys/event.d core/sys/netbsd/sys/featuretest.d \
core/sys/netbsd/sys/link_elf.d core/sys/netbsd/sys/mman.d \
- core/sys/netbsd/time.d
+ core/sys/netbsd/sys/sysctl.d core/sys/netbsd/time.d
DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \
+ core/sys/openbsd/err.d core/sys/openbsd/stdlib.d \
core/sys/openbsd/string.d core/sys/openbsd/sys/cdefs.d \
core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \
core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \
core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \
- core/sys/openbsd/time.d
+ core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d \
+ core/sys/openbsd/unistd.d
DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \
core/sys/posix/arpa/inet.d core/sys/posix/config.d \
core/sys/posix/dirent.d core/sys/posix/dlfcn.d core/sys/posix/fcntl.d \
core/sys/posix/grp.d core/sys/posix/iconv.d core/sys/posix/inttypes.d \
- core/sys/posix/libgen.d core/sys/posix/mqueue.d \
- core/sys/posix/net/if_.d core/sys/posix/netdb.d \
- core/sys/posix/netinet/in_.d core/sys/posix/netinet/tcp.d \
- core/sys/posix/poll.d core/sys/posix/pthread.d core/sys/posix/pwd.d \
- core/sys/posix/sched.d core/sys/posix/semaphore.d \
- core/sys/posix/setjmp.d core/sys/posix/signal.d core/sys/posix/spawn.d \
- core/sys/posix/stdio.d core/sys/posix/stdlib.d \
- core/sys/posix/sys/filio.d core/sys/posix/sys/ioccom.d \
- core/sys/posix/sys/ioctl.d core/sys/posix/sys/ipc.d \
- core/sys/posix/sys/mman.d core/sys/posix/sys/msg.d \
- core/sys/posix/sys/resource.d core/sys/posix/sys/select.d \
- core/sys/posix/sys/shm.d core/sys/posix/sys/socket.d \
- core/sys/posix/sys/stat.d core/sys/posix/sys/statvfs.d \
- core/sys/posix/sys/time.d core/sys/posix/sys/ttycom.d \
- core/sys/posix/sys/types.d core/sys/posix/sys/uio.d \
- core/sys/posix/sys/un.d core/sys/posix/sys/utsname.d \
- core/sys/posix/sys/wait.d core/sys/posix/syslog.d \
- core/sys/posix/termios.d core/sys/posix/time.d \
+ core/sys/posix/libgen.d core/sys/posix/locale.d \
+ core/sys/posix/mqueue.d core/sys/posix/net/if_.d \
+ core/sys/posix/netdb.d core/sys/posix/netinet/in_.d \
+ core/sys/posix/netinet/tcp.d core/sys/posix/poll.d \
+ core/sys/posix/pthread.d core/sys/posix/pwd.d core/sys/posix/sched.d \
+ core/sys/posix/semaphore.d core/sys/posix/setjmp.d \
+ core/sys/posix/signal.d core/sys/posix/spawn.d \
+ core/sys/posix/stdc/time.d core/sys/posix/stdio.d \
+ core/sys/posix/stdlib.d core/sys/posix/string.d \
+ core/sys/posix/strings.d core/sys/posix/sys/filio.d \
+ core/sys/posix/sys/ioccom.d core/sys/posix/sys/ioctl.d \
+ core/sys/posix/sys/ipc.d core/sys/posix/sys/mman.d \
+ core/sys/posix/sys/msg.d core/sys/posix/sys/resource.d \
+ core/sys/posix/sys/select.d core/sys/posix/sys/shm.d \
+ core/sys/posix/sys/socket.d core/sys/posix/sys/stat.d \
+ core/sys/posix/sys/statvfs.d core/sys/posix/sys/time.d \
+ core/sys/posix/sys/ttycom.d core/sys/posix/sys/types.d \
+ core/sys/posix/sys/uio.d core/sys/posix/sys/un.d \
+ core/sys/posix/sys/utsname.d core/sys/posix/sys/wait.d \
+ core/sys/posix/syslog.d core/sys/posix/termios.d core/sys/posix/time.d \
core/sys/posix/ucontext.d core/sys/posix/unistd.d \
core/sys/posix/utime.d
DRUNTIME_DSOURCES_SOLARIS = core/sys/solaris/dlfcn.d \
- core/sys/solaris/elf.d core/sys/solaris/execinfo.d \
- core/sys/solaris/libelf.d core/sys/solaris/link.d \
+ core/sys/solaris/elf.d core/sys/solaris/err.d \
+ core/sys/solaris/execinfo.d core/sys/solaris/libelf.d \
+ core/sys/solaris/link.d core/sys/solaris/stdlib.d \
core/sys/solaris/sys/elf.d core/sys/solaris/sys/elf_386.d \
core/sys/solaris/sys/elf_SPARC.d core/sys/solaris/sys/elf_amd64.d \
core/sys/solaris/sys/elf_notes.d core/sys/solaris/sys/elftypes.d \
@@ -996,31 +1012,32 @@ DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \
core/sys/windows/rpcdcep.d core/sys/windows/rpcndr.d \
core/sys/windows/rpcnsi.d core/sys/windows/rpcnsip.d \
core/sys/windows/rpcnterr.d core/sys/windows/schannel.d \
- core/sys/windows/secext.d core/sys/windows/security.d \
- core/sys/windows/servprov.d core/sys/windows/setupapi.d \
- core/sys/windows/shellapi.d core/sys/windows/shldisp.d \
- core/sys/windows/shlguid.d core/sys/windows/shlobj.d \
- core/sys/windows/shlwapi.d core/sys/windows/snmp.d \
- core/sys/windows/sql.d core/sys/windows/sqlext.d \
- core/sys/windows/sqltypes.d core/sys/windows/sqlucode.d \
- core/sys/windows/sspi.d core/sys/windows/stacktrace.d \
- core/sys/windows/stat.d core/sys/windows/subauth.d \
- core/sys/windows/threadaux.d core/sys/windows/tlhelp32.d \
- core/sys/windows/tmschema.d core/sys/windows/unknwn.d \
- core/sys/windows/uuid.d core/sys/windows/vfw.d \
- core/sys/windows/w32api.d core/sys/windows/winbase.d \
- core/sys/windows/winber.d core/sys/windows/wincon.d \
- core/sys/windows/wincrypt.d core/sys/windows/windef.d \
- core/sys/windows/windows.d core/sys/windows/winerror.d \
- core/sys/windows/wingdi.d core/sys/windows/winhttp.d \
- core/sys/windows/wininet.d core/sys/windows/winioctl.d \
- core/sys/windows/winldap.d core/sys/windows/winnetwk.d \
- core/sys/windows/winnls.d core/sys/windows/winnt.d \
- core/sys/windows/winperf.d core/sys/windows/winreg.d \
- core/sys/windows/winsock2.d core/sys/windows/winspool.d \
- core/sys/windows/winsvc.d core/sys/windows/winuser.d \
- core/sys/windows/winver.d core/sys/windows/wtsapi32.d \
- core/sys/windows/wtypes.d
+ core/sys/windows/sdkddkver.d core/sys/windows/secext.d \
+ core/sys/windows/security.d core/sys/windows/servprov.d \
+ core/sys/windows/setupapi.d core/sys/windows/shellapi.d \
+ core/sys/windows/shldisp.d core/sys/windows/shlguid.d \
+ core/sys/windows/shlobj.d core/sys/windows/shlwapi.d \
+ core/sys/windows/snmp.d core/sys/windows/sql.d \
+ core/sys/windows/sqlext.d core/sys/windows/sqltypes.d \
+ core/sys/windows/sqlucode.d core/sys/windows/sspi.d \
+ core/sys/windows/stacktrace.d core/sys/windows/stat.d \
+ core/sys/windows/stdc/malloc.d core/sys/windows/stdc/time.d \
+ core/sys/windows/subauth.d core/sys/windows/threadaux.d \
+ core/sys/windows/tlhelp32.d core/sys/windows/tmschema.d \
+ core/sys/windows/unknwn.d core/sys/windows/uuid.d \
+ core/sys/windows/vfw.d core/sys/windows/w32api.d \
+ core/sys/windows/winbase.d core/sys/windows/winber.d \
+ core/sys/windows/wincon.d core/sys/windows/wincrypt.d \
+ core/sys/windows/windef.d core/sys/windows/windows.d \
+ core/sys/windows/winerror.d core/sys/windows/wingdi.d \
+ core/sys/windows/winhttp.d core/sys/windows/wininet.d \
+ core/sys/windows/winioctl.d core/sys/windows/winldap.d \
+ core/sys/windows/winnetwk.d core/sys/windows/winnls.d \
+ core/sys/windows/winnt.d core/sys/windows/winperf.d \
+ core/sys/windows/winreg.d core/sys/windows/winsock2.d \
+ core/sys/windows/winspool.d core/sys/windows/winsvc.d \
+ core/sys/windows/winuser.d core/sys/windows/winver.d \
+ core/sys/windows/wtsapi32.d core/sys/windows/wtypes.d
DRUNTIME_DISOURCES = __entrypoint.di __main.di
all: all-am
@@ -1118,6 +1135,7 @@ core/internal/$(am__dirstamp):
@: > core/internal/$(am__dirstamp)
core/internal/abort.lo: core/internal/$(am__dirstamp)
core/internal/arrayop.lo: core/internal/$(am__dirstamp)
+core/internal/attributes.lo: core/internal/$(am__dirstamp)
core/internal/convert.lo: core/internal/$(am__dirstamp)
core/internal/hash.lo: core/internal/$(am__dirstamp)
core/internal/spinlock.lo: core/internal/$(am__dirstamp)
@@ -1162,9 +1180,19 @@ core/sync/exception.lo: core/sync/$(am__dirstamp)
core/sync/mutex.lo: core/sync/$(am__dirstamp)
core/sync/rwmutex.lo: core/sync/$(am__dirstamp)
core/sync/semaphore.lo: core/sync/$(am__dirstamp)
-core/thread.lo: core/$(am__dirstamp)
+core/thread/$(am__dirstamp):
+ @$(MKDIR_P) core/thread
+ @: > core/thread/$(am__dirstamp)
+core/thread/context.lo: core/thread/$(am__dirstamp)
+core/thread/fiber.lo: core/thread/$(am__dirstamp)
+core/thread/osthread.lo: core/thread/$(am__dirstamp)
+core/thread/package.lo: core/thread/$(am__dirstamp)
+core/thread/threadbase.lo: core/thread/$(am__dirstamp)
+core/thread/threadgroup.lo: core/thread/$(am__dirstamp)
+core/thread/types.lo: core/thread/$(am__dirstamp)
core/time.lo: core/$(am__dirstamp)
core/vararg.lo: core/$(am__dirstamp)
+core/volatile.lo: core/$(am__dirstamp)
gc/$(am__dirstamp):
@$(MKDIR_P) gc
@: > gc/$(am__dirstamp)
@@ -1186,6 +1214,7 @@ gcc/$(am__dirstamp):
@$(MKDIR_P) gcc
@: > gcc/$(am__dirstamp)
gcc/attribute.lo: gcc/$(am__dirstamp)
+gcc/attributes.lo: gcc/$(am__dirstamp)
gcc/backtrace.lo: gcc/$(am__dirstamp)
gcc/builtins.lo: gcc/$(am__dirstamp)
gcc/deh.lo: gcc/$(am__dirstamp)
@@ -1194,12 +1223,11 @@ gcc/gthread.lo: gcc/$(am__dirstamp)
gcc/sections/$(am__dirstamp):
@$(MKDIR_P) gcc/sections
@: > gcc/sections/$(am__dirstamp)
-gcc/sections/android.lo: gcc/sections/$(am__dirstamp)
-gcc/sections/elf_shared.lo: gcc/sections/$(am__dirstamp)
-gcc/sections/osx.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/common.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/elf.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/macho.lo: gcc/sections/$(am__dirstamp)
gcc/sections/package.lo: gcc/sections/$(am__dirstamp)
-gcc/sections/win32.lo: gcc/sections/$(am__dirstamp)
-gcc/sections/win64.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/pecoff.lo: gcc/sections/$(am__dirstamp)
gcc/unwind/$(am__dirstamp):
@$(MKDIR_P) gcc/unwind
@: > gcc/unwind/$(am__dirstamp)
@@ -1234,46 +1262,6 @@ rt/qsort.lo: rt/$(am__dirstamp)
rt/sections.lo: rt/$(am__dirstamp)
rt/switch_.lo: rt/$(am__dirstamp)
rt/tlsgc.lo: rt/$(am__dirstamp)
-rt/typeinfo/$(am__dirstamp):
- @$(MKDIR_P) rt/typeinfo
- @: > rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Acdouble.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Acfloat.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Acreal.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Adouble.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Afloat.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Ag.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Aint.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Along.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Areal.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_Ashort.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_C.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_byte.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_cdouble.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_cent.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_cfloat.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_char.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_creal.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_dchar.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_delegate.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_double.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_float.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_idouble.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_ifloat.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_int.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_ireal.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_long.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_n.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_ptr.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_real.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_short.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_ubyte.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_ucent.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_uint.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_ulong.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_ushort.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_void.lo: rt/typeinfo/$(am__dirstamp)
-rt/typeinfo/ti_wchar.lo: rt/typeinfo/$(am__dirstamp)
rt/util/$(am__dirstamp):
@$(MKDIR_P) rt/util
@: > rt/util/$(am__dirstamp)
@@ -1305,6 +1293,7 @@ core/sys/posix/grp.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/iconv.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/inttypes.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/libgen.lo: core/sys/posix/$(am__dirstamp)
+core/sys/posix/locale.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/mqueue.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/net/$(am__dirstamp):
@$(MKDIR_P) core/sys/posix/net
@@ -1324,8 +1313,14 @@ core/sys/posix/semaphore.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/setjmp.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/signal.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/spawn.lo: core/sys/posix/$(am__dirstamp)
+core/sys/posix/stdc/$(am__dirstamp):
+ @$(MKDIR_P) core/sys/posix/stdc
+ @: > core/sys/posix/stdc/$(am__dirstamp)
+core/sys/posix/stdc/time.lo: core/sys/posix/stdc/$(am__dirstamp)
core/sys/posix/stdio.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/stdlib.lo: core/sys/posix/$(am__dirstamp)
+core/sys/posix/string.lo: core/sys/posix/$(am__dirstamp)
+core/sys/posix/strings.lo: core/sys/posix/$(am__dirstamp)
core/sys/posix/sys/$(am__dirstamp):
@$(MKDIR_P) core/sys/posix/sys
@: > core/sys/posix/sys/$(am__dirstamp)
@@ -1357,9 +1352,13 @@ core/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp)
core/sys/darwin/$(am__dirstamp):
@$(MKDIR_P) core/sys/darwin
@: > core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/config.lo: core/sys/darwin/$(am__dirstamp)
core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp)
core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp)
core/sys/darwin/execinfo.lo: core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/fcntl.lo: core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/ifaddrs.lo: core/sys/darwin/$(am__dirstamp)
core/sys/darwin/mach/$(am__dirstamp):
@$(MKDIR_P) core/sys/darwin/mach
@: > core/sys/darwin/mach/$(am__dirstamp)
@@ -1368,9 +1367,11 @@ core/sys/darwin/mach/getsect.lo: core/sys/darwin/mach/$(am__dirstamp)
core/sys/darwin/mach/kern_return.lo: \
core/sys/darwin/mach/$(am__dirstamp)
core/sys/darwin/mach/loader.lo: core/sys/darwin/mach/$(am__dirstamp)
+core/sys/darwin/mach/nlist.lo: core/sys/darwin/mach/$(am__dirstamp)
core/sys/darwin/mach/port.lo: core/sys/darwin/mach/$(am__dirstamp)
core/sys/darwin/mach/semaphore.lo: \
core/sys/darwin/mach/$(am__dirstamp)
+core/sys/darwin/mach/stab.lo: core/sys/darwin/mach/$(am__dirstamp)
core/sys/darwin/mach/thread_act.lo: \
core/sys/darwin/mach/$(am__dirstamp)
core/sys/darwin/netinet/$(am__dirstamp):
@@ -1379,17 +1380,21 @@ core/sys/darwin/netinet/$(am__dirstamp):
core/sys/darwin/netinet/in_.lo: \
core/sys/darwin/netinet/$(am__dirstamp)
core/sys/darwin/pthread.lo: core/sys/darwin/$(am__dirstamp)
+core/sys/darwin/stdlib.lo: core/sys/darwin/$(am__dirstamp)
core/sys/darwin/string.lo: core/sys/darwin/$(am__dirstamp)
core/sys/darwin/sys/$(am__dirstamp):
@$(MKDIR_P) core/sys/darwin/sys
@: > core/sys/darwin/sys/$(am__dirstamp)
+core/sys/darwin/sys/attr.lo: core/sys/darwin/sys/$(am__dirstamp)
core/sys/darwin/sys/cdefs.lo: core/sys/darwin/sys/$(am__dirstamp)
core/sys/darwin/sys/event.lo: core/sys/darwin/sys/$(am__dirstamp)
core/sys/darwin/sys/mman.lo: core/sys/darwin/sys/$(am__dirstamp)
+core/sys/darwin/sys/sysctl.lo: core/sys/darwin/sys/$(am__dirstamp)
core/sys/dragonflybsd/$(am__dirstamp):
@$(MKDIR_P) core/sys/dragonflybsd
@: > core/sys/dragonflybsd/$(am__dirstamp)
core/sys/dragonflybsd/dlfcn.lo: core/sys/dragonflybsd/$(am__dirstamp)
+core/sys/dragonflybsd/err.lo: core/sys/dragonflybsd/$(am__dirstamp)
core/sys/dragonflybsd/execinfo.lo: \
core/sys/dragonflybsd/$(am__dirstamp)
core/sys/dragonflybsd/netinet/$(am__dirstamp):
@@ -1399,6 +1404,8 @@ core/sys/dragonflybsd/netinet/in_.lo: \
core/sys/dragonflybsd/netinet/$(am__dirstamp)
core/sys/dragonflybsd/pthread_np.lo: \
core/sys/dragonflybsd/$(am__dirstamp)
+core/sys/dragonflybsd/stdlib.lo: \
+ core/sys/dragonflybsd/$(am__dirstamp)
core/sys/dragonflybsd/string.lo: \
core/sys/dragonflybsd/$(am__dirstamp)
core/sys/dragonflybsd/sys/$(am__dirstamp):
@@ -1426,11 +1433,15 @@ core/sys/dragonflybsd/sys/mman.lo: \
core/sys/dragonflybsd/sys/$(am__dirstamp)
core/sys/dragonflybsd/sys/socket.lo: \
core/sys/dragonflybsd/sys/$(am__dirstamp)
+core/sys/dragonflybsd/sys/sysctl.lo: \
+ core/sys/dragonflybsd/sys/$(am__dirstamp)
core/sys/dragonflybsd/time.lo: core/sys/dragonflybsd/$(am__dirstamp)
core/sys/bionic/$(am__dirstamp):
@$(MKDIR_P) core/sys/bionic
@: > core/sys/bionic/$(am__dirstamp)
+core/sys/bionic/err.lo: core/sys/bionic/$(am__dirstamp)
core/sys/bionic/fcntl.lo: core/sys/bionic/$(am__dirstamp)
+core/sys/bionic/stdlib.lo: core/sys/bionic/$(am__dirstamp)
core/sys/bionic/string.lo: core/sys/bionic/$(am__dirstamp)
core/sys/bionic/unistd.lo: core/sys/bionic/$(am__dirstamp)
core/sys/freebsd/$(am__dirstamp):
@@ -1438,6 +1449,7 @@ core/sys/freebsd/$(am__dirstamp):
@: > core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/config.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/dlfcn.lo: core/sys/freebsd/$(am__dirstamp)
+core/sys/freebsd/err.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/execinfo.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/netinet/$(am__dirstamp):
@$(MKDIR_P) core/sys/freebsd/netinet
@@ -1445,6 +1457,7 @@ core/sys/freebsd/netinet/$(am__dirstamp):
core/sys/freebsd/netinet/in_.lo: \
core/sys/freebsd/netinet/$(am__dirstamp)
core/sys/freebsd/pthread_np.lo: core/sys/freebsd/$(am__dirstamp)
+core/sys/freebsd/stdlib.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/string.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/sys/$(am__dirstamp):
@$(MKDIR_P) core/sys/freebsd/sys
@@ -1462,13 +1475,16 @@ core/sys/freebsd/sys/link_elf.lo: \
core/sys/freebsd/sys/$(am__dirstamp)
core/sys/freebsd/sys/mman.lo: core/sys/freebsd/sys/$(am__dirstamp)
core/sys/freebsd/sys/mount.lo: core/sys/freebsd/sys/$(am__dirstamp)
+core/sys/freebsd/sys/sysctl.lo: core/sys/freebsd/sys/$(am__dirstamp)
core/sys/freebsd/time.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/unistd.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/netbsd/$(am__dirstamp):
@$(MKDIR_P) core/sys/netbsd
@: > core/sys/netbsd/$(am__dirstamp)
core/sys/netbsd/dlfcn.lo: core/sys/netbsd/$(am__dirstamp)
+core/sys/netbsd/err.lo: core/sys/netbsd/$(am__dirstamp)
core/sys/netbsd/execinfo.lo: core/sys/netbsd/$(am__dirstamp)
+core/sys/netbsd/stdlib.lo: core/sys/netbsd/$(am__dirstamp)
core/sys/netbsd/string.lo: core/sys/netbsd/$(am__dirstamp)
core/sys/netbsd/sys/$(am__dirstamp):
@$(MKDIR_P) core/sys/netbsd/sys
@@ -1483,11 +1499,14 @@ core/sys/netbsd/sys/featuretest.lo: \
core/sys/netbsd/sys/$(am__dirstamp)
core/sys/netbsd/sys/link_elf.lo: core/sys/netbsd/sys/$(am__dirstamp)
core/sys/netbsd/sys/mman.lo: core/sys/netbsd/sys/$(am__dirstamp)
+core/sys/netbsd/sys/sysctl.lo: core/sys/netbsd/sys/$(am__dirstamp)
core/sys/netbsd/time.lo: core/sys/netbsd/$(am__dirstamp)
core/sys/openbsd/$(am__dirstamp):
@$(MKDIR_P) core/sys/openbsd
@: > core/sys/openbsd/$(am__dirstamp)
core/sys/openbsd/dlfcn.lo: core/sys/openbsd/$(am__dirstamp)
+core/sys/openbsd/err.lo: core/sys/openbsd/$(am__dirstamp)
+core/sys/openbsd/stdlib.lo: core/sys/openbsd/$(am__dirstamp)
core/sys/openbsd/string.lo: core/sys/openbsd/$(am__dirstamp)
core/sys/openbsd/sys/$(am__dirstamp):
@$(MKDIR_P) core/sys/openbsd/sys
@@ -1501,7 +1520,9 @@ core/sys/openbsd/sys/elf_common.lo: \
core/sys/openbsd/sys/link_elf.lo: \
core/sys/openbsd/sys/$(am__dirstamp)
core/sys/openbsd/sys/mman.lo: core/sys/openbsd/sys/$(am__dirstamp)
+core/sys/openbsd/sys/sysctl.lo: core/sys/openbsd/sys/$(am__dirstamp)
core/sys/openbsd/time.lo: core/sys/openbsd/$(am__dirstamp)
+core/sys/openbsd/unistd.lo: core/sys/openbsd/$(am__dirstamp)
core/sys/linux/$(am__dirstamp):
@$(MKDIR_P) core/sys/linux
@: > core/sys/linux/$(am__dirstamp)
@@ -1509,6 +1530,7 @@ core/sys/linux/config.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/dlfcn.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/elf.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/epoll.lo: core/sys/linux/$(am__dirstamp)
+core/sys/linux/err.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/errno.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/execinfo.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/fcntl.lo: core/sys/linux/$(am__dirstamp)
@@ -1660,6 +1682,7 @@ core/sys/windows/rpcnsi.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/rpcnsip.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/rpcnterr.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/schannel.lo: core/sys/windows/$(am__dirstamp)
+core/sys/windows/sdkddkver.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/secext.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/security.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/servprov.lo: core/sys/windows/$(am__dirstamp)
@@ -1677,6 +1700,12 @@ core/sys/windows/sqlucode.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/sspi.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/stacktrace.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/stat.lo: core/sys/windows/$(am__dirstamp)
+core/sys/windows/stdc/$(am__dirstamp):
+ @$(MKDIR_P) core/sys/windows/stdc
+ @: > core/sys/windows/stdc/$(am__dirstamp)
+core/sys/windows/stdc/malloc.lo: \
+ core/sys/windows/stdc/$(am__dirstamp)
+core/sys/windows/stdc/time.lo: core/sys/windows/stdc/$(am__dirstamp)
core/sys/windows/subauth.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/threadaux.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/tlhelp32.lo: core/sys/windows/$(am__dirstamp)
@@ -1709,14 +1738,20 @@ core/sys/windows/winuser.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/winver.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtsapi32.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtypes.lo: core/sys/windows/$(am__dirstamp)
+config/mingw/$(am__dirstamp):
+ @$(MKDIR_P) config/mingw
+ @: > config/mingw/$(am__dirstamp)
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/$(am__dirstamp)
core/sys/solaris/$(am__dirstamp):
@$(MKDIR_P) core/sys/solaris
@: > core/sys/solaris/$(am__dirstamp)
core/sys/solaris/dlfcn.lo: core/sys/solaris/$(am__dirstamp)
core/sys/solaris/elf.lo: core/sys/solaris/$(am__dirstamp)
+core/sys/solaris/err.lo: core/sys/solaris/$(am__dirstamp)
core/sys/solaris/execinfo.lo: core/sys/solaris/$(am__dirstamp)
core/sys/solaris/libelf.lo: core/sys/solaris/$(am__dirstamp)
core/sys/solaris/link.lo: core/sys/solaris/$(am__dirstamp)
+core/sys/solaris/stdlib.lo: core/sys/solaris/$(am__dirstamp)
core/sys/solaris/sys/$(am__dirstamp):
@$(MKDIR_P) core/sys/solaris/sys
@: > core/sys/solaris/sys/$(am__dirstamp)
@@ -1756,9 +1791,6 @@ config/powerpc/$(am__dirstamp):
@: > config/powerpc/$(am__dirstamp)
config/powerpc/libgdruntime_la-switchcontext.lo: \
config/powerpc/$(am__dirstamp)
-config/mingw/$(am__dirstamp):
- @$(MKDIR_P) config/mingw
- @: > config/mingw/$(am__dirstamp)
config/mingw/libgdruntime_la-switchcontext.lo: \
config/mingw/$(am__dirstamp)
config/x86/$(am__dirstamp):
@@ -1783,6 +1815,8 @@ libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EX
$(AM_V_GEN)$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)
core/stdc/libgdruntime_convenience_la-errno_.lo: \
core/stdc/$(am__dirstamp)
+config/mingw/libgdruntime_convenience_la-msvc.lo: \
+ config/mingw/$(am__dirstamp)
config/aarch64/libgdruntime_convenience_la-switchcontext.lo: \
config/aarch64/$(am__dirstamp)
config/arm/libgdruntime_convenience_la-switchcontext.lo: \
@@ -1873,6 +1907,8 @@ mostlyclean-compile:
-rm -f core/sys/posix/net/*.lo
-rm -f core/sys/posix/netinet/*.$(OBJEXT)
-rm -f core/sys/posix/netinet/*.lo
+ -rm -f core/sys/posix/stdc/*.$(OBJEXT)
+ -rm -f core/sys/posix/stdc/*.lo
-rm -f core/sys/posix/sys/*.$(OBJEXT)
-rm -f core/sys/posix/sys/*.lo
-rm -f core/sys/solaris/*.$(OBJEXT)
@@ -1881,6 +1917,10 @@ mostlyclean-compile:
-rm -f core/sys/solaris/sys/*.lo
-rm -f core/sys/windows/*.$(OBJEXT)
-rm -f core/sys/windows/*.lo
+ -rm -f core/sys/windows/stdc/*.$(OBJEXT)
+ -rm -f core/sys/windows/stdc/*.lo
+ -rm -f core/thread/*.$(OBJEXT)
+ -rm -f core/thread/*.lo
-rm -f gc/*.$(OBJEXT)
-rm -f gc/*.lo
-rm -f gc/impl/conservative/*.$(OBJEXT)
@@ -1895,8 +1935,6 @@ mostlyclean-compile:
-rm -f gcc/unwind/*.lo
-rm -f rt/*.$(OBJEXT)
-rm -f rt/*.lo
- -rm -f rt/typeinfo/*.$(OBJEXT)
- -rm -f rt/typeinfo/*.lo
-rm -f rt/util/*.$(OBJEXT)
-rm -f rt/util/*.lo
-rm -f rt/util/container/*.$(OBJEXT)
@@ -1974,9 +2012,15 @@ config/s390/libgdruntime_convenience_la-get_tls_offset.lo: config/s390/get_tls_o
core/stdc/libgdruntime_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/msvc.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
core/stdc/libgdruntime_convenience_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_convenience_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+config/mingw/libgdruntime_convenience_la-msvc.lo: config/mingw/msvc.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_convenience_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
mostlyclean-libtool:
-rm -f *.lo
@@ -2016,10 +2060,13 @@ clean-libtool:
-rm -rf core/sys/posix/arpa/.libs core/sys/posix/arpa/_libs
-rm -rf core/sys/posix/net/.libs core/sys/posix/net/_libs
-rm -rf core/sys/posix/netinet/.libs core/sys/posix/netinet/_libs
+ -rm -rf core/sys/posix/stdc/.libs core/sys/posix/stdc/_libs
-rm -rf core/sys/posix/sys/.libs core/sys/posix/sys/_libs
-rm -rf core/sys/solaris/.libs core/sys/solaris/_libs
-rm -rf core/sys/solaris/sys/.libs core/sys/solaris/sys/_libs
-rm -rf core/sys/windows/.libs core/sys/windows/_libs
+ -rm -rf core/sys/windows/stdc/.libs core/sys/windows/stdc/_libs
+ -rm -rf core/thread/.libs core/thread/_libs
-rm -rf gc/.libs gc/_libs
-rm -rf gc/impl/conservative/.libs gc/impl/conservative/_libs
-rm -rf gc/impl/manual/.libs gc/impl/manual/_libs
@@ -2027,7 +2074,6 @@ clean-libtool:
-rm -rf gcc/sections/.libs gcc/sections/_libs
-rm -rf gcc/unwind/.libs gcc/unwind/_libs
-rm -rf rt/.libs rt/_libs
- -rm -rf rt/typeinfo/.libs rt/typeinfo/_libs
-rm -rf rt/util/.libs rt/util/_libs
-rm -rf rt/util/container/.libs rt/util/container/_libs
install-toolexeclibDATA: $(toolexeclib_DATA)
@@ -2170,10 +2216,13 @@ distclean-generic:
-rm -f core/sys/posix/arpa/$(am__dirstamp)
-rm -f core/sys/posix/net/$(am__dirstamp)
-rm -f core/sys/posix/netinet/$(am__dirstamp)
+ -rm -f core/sys/posix/stdc/$(am__dirstamp)
-rm -f core/sys/posix/sys/$(am__dirstamp)
-rm -f core/sys/solaris/$(am__dirstamp)
-rm -f core/sys/solaris/sys/$(am__dirstamp)
-rm -f core/sys/windows/$(am__dirstamp)
+ -rm -f core/sys/windows/stdc/$(am__dirstamp)
+ -rm -f core/thread/$(am__dirstamp)
-rm -f gc/$(am__dirstamp)
-rm -f gc/impl/conservative/$(am__dirstamp)
-rm -f gc/impl/manual/$(am__dirstamp)
@@ -2181,7 +2230,6 @@ distclean-generic:
-rm -f gcc/sections/$(am__dirstamp)
-rm -f gcc/unwind/$(am__dirstamp)
-rm -f rt/$(am__dirstamp)
- -rm -f rt/typeinfo/$(am__dirstamp)
-rm -f rt/util/$(am__dirstamp)
-rm -f rt/util/container/$(am__dirstamp)
diff --git a/libphobos/libdruntime/__entrypoint.di b/libphobos/libdruntime/__entrypoint.di
index 5db5b6a..fba2ae28 100644
--- a/libphobos/libdruntime/__entrypoint.di
+++ b/libphobos/libdruntime/__entrypoint.di
@@ -1,5 +1,5 @@
/* GDC -- D front-end for GCC
- Copyright (C) 2013-2020 Free Software Foundation, Inc.
+ Copyright (C) 2013-2021 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/__main.di b/libphobos/libdruntime/__main.di
index 56c12b8..8062bf4 100644
--- a/libphobos/libdruntime/__main.di
+++ b/libphobos/libdruntime/__main.di
@@ -1,5 +1,5 @@
/* GDC -- D front-end for GCC
- Copyright (C) 2018-2020 Free Software Foundation, Inc.
+ Copyright (C) 2018-2021 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/config/aarch64/switchcontext.S b/libphobos/libdruntime/config/aarch64/switchcontext.S
index 3a0aa7d..d47f81f 100644
--- a/libphobos/libdruntime/config/aarch64/switchcontext.S
+++ b/libphobos/libdruntime/config/aarch64/switchcontext.S
@@ -1,5 +1,5 @@
/* AArch64 support code for fibers and multithreading.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/libphobos/libdruntime/config/arm/switchcontext.S b/libphobos/libdruntime/config/arm/switchcontext.S
index 133354f..532e3dc 100644
--- a/libphobos/libdruntime/config/arm/switchcontext.S
+++ b/libphobos/libdruntime/config/arm/switchcontext.S
@@ -1,5 +1,5 @@
/* ARM support code for fibers and multithreading.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/libphobos/libdruntime/config/common/threadasm.S b/libphobos/libdruntime/config/common/threadasm.S
index 1f5432f..3546217 100644
--- a/libphobos/libdruntime/config/common/threadasm.S
+++ b/libphobos/libdruntime/config/common/threadasm.S
@@ -1,5 +1,5 @@
/* Support code for fibers and multithreading.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,7 +22,7 @@ a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
-#if (__linux__ || __FreeBSD__ || __NetBSD__ || __DragonFly__) && __ELF__
+#if (__linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__) && __ELF__
/*
* Mark the resulting object file as not requiring execution permissions on
* stack memory. The absence of this section would mark the whole resulting
diff --git a/libphobos/libdruntime/config/mingw/msvc.c b/libphobos/libdruntime/config/mingw/msvc.c
new file mode 100644
index 0000000..da40718
--- /dev/null
+++ b/libphobos/libdruntime/config/mingw/msvc.c
@@ -0,0 +1,169 @@
+/* Windows support code to wrap differences between different
+ versions of the Microsoft C libaries.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#ifdef __MINGW32__
+#include <_mingw.h>
+#endif
+#include <stdio.h>
+
+/* The D runtime library defines stdin, stdout, and stderr as extern(C) symbols
+ in the core.stdc.stdio module, and require initializing at start-up. */
+__attribute__((weakref ("stdin")))
+static FILE *core_stdc_stdin;
+
+__attribute__((weakref ("stdout")))
+static FILE *core_stdc_stdout;
+
+__attribute__((weakref ("stderr")))
+static FILE *core_stdc_stderr;
+
+/* Set to 1 if runtime is using libucrt.dll. */
+unsigned char msvcUsesUCRT;
+
+void
+init_msvc (void)
+{
+ core_stdc_stdin = stdin;
+ core_stdc_stdout = stdout;
+ core_stdc_stderr = stderr;
+
+#if __MSVCRT_VERSION__ >= 0xE00
+ msvcUsedUCRT = 1;
+#endif
+}
+
+/* Phobos std.stdio module assumes these functions are present at link time,
+ and not absent or macros. */
+#ifdef _fgetc_nolock
+#undef _fgetc_nolock
+
+int
+_fgetc_nolock (FILE *fp)
+{
+ fp->_cnt--;
+ if (fp->_cnt >= 0)
+ {
+ const int c = *fp->_ptr;
+ fp->_ptr++;
+ return c & 0xff;
+ }
+ else
+ return _filbuf (fp);
+}
+
+#endif /* _fgetc_nolock */
+
+#ifdef _fputc_nolock
+#undef _fputc_nolock
+
+int
+_fputc_nolock (int c, FILE *fp)
+{
+ fp->_cnt--;
+ if (fp->_cnt >= 0)
+ {
+ *fp->_ptr = (char) c;
+ fp->_ptr++;
+ return c & 0xff;
+ }
+ else
+ return _flsbuf (c, fp);
+}
+
+#endif /* _fputc_nolock */
+
+#ifdef rewind
+#undef rewind
+
+void
+rewind (FILE *fp)
+{
+ fseek (fp, 0, SEEK_SET);
+ fp->_flag &= ~_IOERR;
+}
+
+#endif /* rewind */
+
+#ifdef clearerr
+#undef clearerr
+
+void
+clearerr (FILE *fp)
+{
+ fp->_flag &= ~(_IOERR | _IOEOF);
+}
+
+#endif /* clearerr */
+
+#ifdef feof
+#undef feof
+
+int
+feof (FILE *fp)
+{
+ return fp->_flag & _IOEOF;
+}
+
+#endif /* feof */
+
+#ifdef ferror
+#undef ferror
+
+int
+ferror (FILE *fp)
+{
+ return fp->_flag & _IOERR;
+}
+
+#endif /* ferror */
+
+#ifdef fileno
+#undef fileno
+
+int
+fileno (FILE *fp)
+{
+ return fp->_file;
+}
+
+#endif /* fileno */
+
+/* Phobos std.stdio module has a dependency on the UCRT library, so provide
+ stubs that forward to the nearest equivalent. */
+#if __MSVCRT_VERSION__ < 0x800
+
+wint_t
+_fgetwc_nolock (FILE *fp)
+{
+ return fgetwc (fp);
+}
+
+wint_t
+_fputwc_nolock (wchar_t c, FILE *fp)
+{
+ return fputwc(c, fp);
+}
+
+#endif /* __MSVCRT_VERSION__ < 0x800*/
diff --git a/libphobos/libdruntime/config/mingw/switchcontext.S b/libphobos/libdruntime/config/mingw/switchcontext.S
index 167cf37..0cb8b01 100644
--- a/libphobos/libdruntime/config/mingw/switchcontext.S
+++ b/libphobos/libdruntime/config/mingw/switchcontext.S
@@ -1,5 +1,5 @@
/* Windows i386 support code for fibers and multithreading.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
This file is part of GCC.
@@ -28,7 +28,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -63,13 +66,15 @@ CSYM(fiber_switchContext):
popq %RCX;
jmp *%RCX;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#elif defined(_X86_)
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -104,6 +109,5 @@ CSYM(fiber_switchContext):
// 'return' to complete switch
ret;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#endif
diff --git a/libphobos/libdruntime/config/mips/switchcontext.S b/libphobos/libdruntime/config/mips/switchcontext.S
index 2e0bd86..8a57db8 100644
--- a/libphobos/libdruntime/config/mips/switchcontext.S
+++ b/libphobos/libdruntime/config/mips/switchcontext.S
@@ -1,5 +1,5 @@
/* MIPS support code for fibers and multithreading.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/libphobos/libdruntime/config/powerpc/switchcontext.S b/libphobos/libdruntime/config/powerpc/switchcontext.S
index 6689217..74395b0 100644
--- a/libphobos/libdruntime/config/powerpc/switchcontext.S
+++ b/libphobos/libdruntime/config/powerpc/switchcontext.S
@@ -1,5 +1,5 @@
/* PowerPC support code for fibers and multithreading.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
This file is part of GCC.
@@ -24,7 +24,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "../common/threadasm.S"
-#if !defined(__PPC64__)
+#if !defined(__PPC64__) && !defined(__MACH__)
/**
* Performs a context switch.
@@ -151,4 +151,278 @@ CSYM(fiber_switchContext):
.cfi_endproc
.size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
-#endif /* !defined(__PPC64__) */
+#elif defined(__MACH__)
+
+/* Implementation for Darwin/macOS preserving callee-saved regs.
+
+ FIXME : There is no unwind frame.
+ FIXME : not sure if we should save the vsave reg (perhaps using the slot we have
+ r11 in at present). */
+
+/* Darwin has a red zone (220 bytes for PPC 288 for PPC64) which we can write
+ to before the stack is updated without worrying about it being clobbered by
+ signals or hardware interrupts.
+
+ The stack will be 16byte aligned on entry with:
+ PPC PPC64
+ SP-> +---------------------------------------+
+ | back chain to caller | 0 0
+ +---------------------------------------+
+ | slot to save CR | 4 8
+ +---------------------------------------+
+ | slot to save LR | 8 16
+ +---------------------------------------+
+ | etc.. etc.. as per C calling conv. | */
+
+# if __PPC64__
+# define LD ld
+# define ST std
+# define STU stdu
+# define SZ 8
+# define MACHINE ppc64
+# define RED_ZONE 288
+# else
+# define LD lwz
+# define ST stw
+# define STU stwu
+# define SZ 4
+# define MACHINE ppc7400
+# define RED_ZONE 220
+# endif
+
+# define SAVE_VECTORS 0
+/**
+ * Performs a context switch.
+ *
+ * r3 - old context pointer
+ * r4 - new context pointer
+ *
+ */
+ .machine MACHINE
+ .text
+ .globl CSYM(fiber_switchContext)
+ .align 2
+CSYM(fiber_switchContext):
+LFB0:
+ /* Get the link reg. */
+ mflr r0
+ /* Get the callee-saved crs (well all of them, actually). */
+ mfcr r12
+
+ /* Save GPRs, we save the static chain here too although it is not clear if we need to. */
+ ST r31, ( -1 * SZ)(r1)
+ ST r30, ( -2 * SZ)(r1)
+ ST r29, ( -3 * SZ)(r1)
+ ST r28, ( -4 * SZ)(r1)
+ ST r27, ( -5 * SZ)(r1)
+ ST r26, ( -6 * SZ)(r1)
+ ST r25, ( -7 * SZ)(r1)
+ ST r24, ( -8 * SZ)(r1)
+ ST r23, ( -9 * SZ)(r1)
+ ST r22, (-10 * SZ)(r1)
+ ST r21, (-11 * SZ)(r1)
+ ST r20, (-12 * SZ)(r1)
+ ST r19, (-13 * SZ)(r1)
+ ST r18, (-14 * SZ)(r1)
+ ST r17, (-15 * SZ)(r1)
+ ST r16, (-16 * SZ)(r1)
+ ST r15, (-17 * SZ)(r1)
+ ST r14, (-18 * SZ)(r1)
+ ST r13, (-19 * SZ)(r1)
+
+ /* Save the lr and cr into the normal function linkage area. */
+ ST r0, 2*SZ(r1)
+ ST r12, SZ(r1)
+
+ /* We update the stack pointer here, since we do not want the GC to
+ scan the floating point registers. We are still 16-byte aligned. */
+ STU r11, (-20 * SZ)(r1)
+
+ /* Update the stack pointer in the old context as per comment above. */
+ ST r1, 0(r3)
+
+ /* Save FPRs - same for PPC and PPC64 */
+ stfd f14, (-18 * 8)(r1)
+ stfd f15, (-17 * 8)(r1)
+ stfd f16, (-16 * 8)(r1)
+ stfd f17, (-15 * 8)(r1)
+ stfd f18, (-14 * 8)(r1)
+ stfd f19, (-13 * 8)(r1)
+ stfd f20, (-12 * 8)(r1)
+ stfd f21, (-11 * 8)(r1)
+ stfd f22, (-10 * 8)(r1)
+ stfd f23, ( -9 * 8)(r1)
+ stfd f24, ( -8 * 8)(r1)
+ stfd f25, ( -7 * 8)(r1)
+ stfd f26, ( -6 * 8)(r1)
+ stfd f27, ( -5 * 8)(r1)
+ stfd f28, ( -4 * 8)(r1)
+ stfd f29, ( -3 * 8)(r1)
+ stfd f30, ( -2 * 8)(r1)
+ stfd f31, ( -1 * 8)(r1)
+
+#if SAVE_VECTORS
+ /* We are still 16byte aligned - so we are ok for vector saves.
+ but the combined size of the vectors (12 x 16) + the FPRs (144) exceeds the
+ red zone size so we need to adjust the stack again - note this means careful
+ ordering is needed on the restore. */
+
+ addi r1, r1, -(12*16+18*8)
+ li r11, 0
+ stvx v20,r11,r1
+ addi r11, r11, 16
+ stvx v21,r11,r1
+ addi r11, r11, 16
+ stvx v22,r11,r1
+ addi r11, r11, 16
+ stvx v23,r11,r1
+ addi r11, r11, 16
+ stvx v24,r11,r1
+ addi r11, r11, 16
+ stvx v25,r11,r1
+ addi r11, r11, 16
+ stvx v26,r11,r1
+ addi r11, r11, 16
+ stvx v27,r11,r1
+ addi r11, r11, 16
+ stvx v28,r11,r1
+ addi r11, r11, 16
+ stvx v29,r11,r1
+ addi r11, r11, 16
+ stvx v30,r11,r1
+ addi r11, r11, 16
+ stvx v31,r11,r1
+
+ /* Now do the same thing in reverse - starting with r4 pointing to
+ the block of GPRs - stage 1 point to the saved vectors and fprs. */
+
+ addi r1, r4, -(12*16+18*8)
+ li r11, 0
+ lvx v20,r11,r1
+ addi r11, r11, 16
+ lvx v21,r11,r1
+ addi r11, r11, 16
+ lvx v22,r11,r1
+ addi r11, r11, 16
+ lvx v23,r11,r1
+ addi r11, r11, 16
+ lvx v24,r11,r1
+ addi r11, r11, 16
+ lvx v25,r11,r1
+ addi r11, r11, 16
+ lvx v26,r11,r1
+ addi r11, r11, 16
+ lvx v27,r11,r1
+ addi r11, r11, 16
+ lvx v28,r11,r1
+ addi r11, r11, 16
+ lvx v29,r11,r1
+ addi r11, r11, 16
+ lvx v30,r11,r1
+ addi r11, r11, 16
+ lvx v31,r11,r1
+#endif
+
+ /* Now it is safe to update the stack pointer since the combined
+ size of the GPRs and FPRs will not exceed the red zone. */
+
+ addi r1, r4, 20 * SZ
+
+ /* Restore FPRs */
+ lfd f14, (-18 * 8)(r4)
+ lfd f15, (-17 * 8)(r4)
+ lfd f16, (-16 * 8)(r4)
+ lfd f17, (-15 * 8)(r4)
+ lfd f18, (-14 * 8)(r4)
+ lfd f19, (-13 * 8)(r4)
+ lfd f20, (-12 * 8)(r4)
+ lfd f21, (-11 * 8)(r4)
+ lfd f22, (-10 * 8)(r4)
+ lfd f23, ( -9 * 8)(r4)
+ lfd f24, ( -8 * 8)(r4)
+ lfd f25, ( -7 * 8)(r4)
+ lfd f26, ( -6 * 8)(r4)
+ lfd f27, ( -5 * 8)(r4)
+ lfd f28, ( -4 * 8)(r4)
+ lfd f29, ( -3 * 8)(r4)
+ lfd f30, ( -2 * 8)(r4)
+ lfd f31, ( -1 * 8)(r4)
+
+ /* Pick up lr and cr */
+ LD r0, 2*SZ(r1)
+ LD r12, SZ(r1)
+
+ /* Restore GPRs */
+ LD r11, (-20 * SZ)(r1)
+ LD r13, (-19 * SZ)(r1)
+ LD r14, (-18 * SZ)(r1)
+ LD r15, (-17 * SZ)(r1)
+ LD r16, (-16 * SZ)(r1)
+ LD r17, (-15 * SZ)(r1)
+ LD r18, (-14 * SZ)(r1)
+ LD r19, (-13 * SZ)(r1)
+ LD r20, (-12 * SZ)(r1)
+ LD r21, (-11 * SZ)(r1)
+ LD r22, (-10 * SZ)(r1)
+ LD r23, ( -9 * SZ)(r1)
+ LD r24, ( -8 * SZ)(r1)
+ LD r25, ( -7 * SZ)(r1)
+ LD r26, ( -6 * SZ)(r1)
+ LD r27, ( -5 * SZ)(r1)
+ LD r28, ( -4 * SZ)(r1)
+ LD r29, ( -3 * SZ)(r1)
+ LD r30, ( -2 * SZ)(r1)
+ LD r31, ( -1 * SZ)(r1)
+
+ /* Set cr and lr */
+ mtcr r12
+ mtlr r0
+
+ /* Return and switch context */
+ blr
+LFE0:
+
+/* Minimal CFI / FDE which does not describe the stacking of the GPRs - but only that
+ the routine has been entered/exited. */
+
+# if __PPC64__
+# define DATA_ALIGN 0x78
+# define ALIGN_SIZE 3
+# define ADDRD .quad
+# else
+# define DATA_ALIGN 0x7c
+# define ALIGN_SIZE 3
+# define ADDRD .long
+# endif
+
+ .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+ .set L$set$0,LECIE1-LSCIE1
+ .long L$set$0 ; Length of Common Information Entry
+LSCIE1:
+ .long 0 ; CIE Identifier Tag
+ .byte 0x3 ; CIE Version
+ .ascii "zR\0" ; CIE Augmentation
+ .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
+ .byte DATA_ALIGN ; sleb128 -4/-8; CIE Data Alignment Factor
+ .byte 0x41 ; uleb128 0x41; CIE RA Column
+ .byte 0x1 ; uleb128 0x1; Augmentation size
+ .byte 0x10 ; FDE Encoding (pcrel)
+ .byte 0xc ; DW_CFA_def_cfa
+ .byte 0x1 ; uleb128 0x1
+ .byte 0 ; uleb128 0
+ .p2align ALIGN_SIZE,0
+LECIE1:
+LSFDE1:
+ .set L$set$1,LEFDE1-LASFDE1
+ .long L$set$1 ; FDE Length
+LASFDE1:
+ .long LASFDE1-EH_frame1 ; FDE CIE offset
+ ADDRD LFB0-. ; FDE initial location
+ .set L$set$2,LFE0-LFB0
+ ADDRD L$set$2 ; FDE address range
+ .byte 0 ; uleb128 0; Augmentation size
+ .p2align ALIGN_SIZE,0
+LEFDE1:
+
+#endif /* defined(__MACH__) */
diff --git a/libphobos/libdruntime/config/s390/get_tls_offset.S b/libphobos/libdruntime/config/s390/get_tls_offset.S
index aaca05c..f7eddd5 100644
--- a/libphobos/libdruntime/config/s390/get_tls_offset.S
+++ b/libphobos/libdruntime/config/s390/get_tls_offset.S
@@ -1,5 +1,5 @@
/* IBM Z support code for TLS offsets.
- Copyright (C) 2020 Free Software Foundation, Inc.
+ Copyright (C) 2020-2021 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/libphobos/libdruntime/config/systemz/get_tls_offset.S b/libphobos/libdruntime/config/systemz/get_tls_offset.S
index e9e6dc7..baac185 100644
--- a/libphobos/libdruntime/config/systemz/get_tls_offset.S
+++ b/libphobos/libdruntime/config/systemz/get_tls_offset.S
@@ -1,5 +1,5 @@
/* IBM Z support code for TLS offsets.
- Copyright (C) 2020 Free Software Foundation, Inc.
+ Copyright (C) 2020-2021 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/libphobos/libdruntime/config/x86/switchcontext.S b/libphobos/libdruntime/config/x86/switchcontext.S
index f2f8efa..9f4befd 100644
--- a/libphobos/libdruntime/config/x86/switchcontext.S
+++ b/libphobos/libdruntime/config/x86/switchcontext.S
@@ -1,5 +1,5 @@
/* i386 support code for fibers and multithreading.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
This file is part of GCC.
@@ -29,7 +29,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# include <cet.h>
#endif
-#if defined(__i386__) && !defined(__CET__)
+#if !defined(__CET__)
+
+# if defined(__ELF__)
+
+# if defined(__i386__)
.text
.globl CSYM(fiber_switchContext)
@@ -63,7 +67,9 @@ CSYM(fiber_switchContext):
.cfi_endproc
.size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
-#elif defined(__x86_64__) && !defined(__ILP32__) && !defined(__CET__)
+# endif /* defined(__ELF__) && defined(__i386__) */
+
+# if defined(__x86_64__) && !defined(__ILP32__)
.text
.globl CSYM(fiber_switchContext)
@@ -98,4 +104,151 @@ CSYM(fiber_switchContext):
.cfi_endproc
.size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
-#endif
+# endif /* defined(__ELF__) && defined(__x86_64__) && !defined(__ILP32__) */
+
+# endif /* defined(__ELF__) */
+
+# if defined(__MACH__)
+
+# if defined(__i386__)
+
+ .text
+ .globl CSYM(fiber_switchContext)
+ .p2align 4
+CSYM(fiber_switchContext):
+LFB0:
+ // save current stack state
+ push %ebp
+ mov %esp, %ebp
+ push %edi
+ push %esi
+ push %ebx
+ push %eax
+
+ // store oldp again with more accurate address
+ mov 8(%ebp), %eax
+ mov %esp, (%eax)
+ // load newp to begin context switch
+ mov 12(%ebp), %esp
+
+ // load saved state from new stack
+ pop %eax
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+
+ // 'return' to complete switch
+ ret
+LFE0:
+
+/* CFI */
+ .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+ .set L$set$0,LECIE1-LSCIE1
+ .long L$set$0 # Length of Common Information Entry
+LSCIE1:
+ .long 0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
+ .byte 0x7c # sleb128 -4; CIE Data Alignment Factor
+ .byte 0x8 # CIE RA Column
+ .byte 0x1 # uleb128 0x1; Augmentation size
+ .byte 0x10 # FDE Encoding (pcrel)
+ .byte 0xc # DW_CFA_def_cfa
+ .byte 0x5 # uleb128 0x5
+ .byte 0x4 # uleb128 0x4
+ .byte 0x88 # DW_CFA_offset, column 0x8
+ .byte 0x1 # uleb128 0x1
+ .p2align 2,0
+LECIE1:
+
+/* minimal FDE - does not record the stack frame changes. */
+LSFDE1:
+ .set L$set$1,LEFDE1-LASFDE1
+ .long L$set$1 # FDE Length
+LASFDE1:
+ .long LASFDE1-EH_frame1 # FDE CIE offset
+ .long LFB0-. # FDE initial location
+ .set L$set$2,LFE0-LFB0
+ .long L$set$2 # FDE address range
+ .byte 0 # uleb128 0; Augmentation size
+ .p2align 2,0
+LEFDE1:
+
+# endif /* defined(__MACH__) && defined(__i386__) */
+
+# if defined(__x86_64__) && !defined(__ILP32__)
+
+ .text
+ .globl CSYM(fiber_switchContext)
+ .p2align 4
+CSYM(fiber_switchContext):
+LFB0:
+ // Save current stack state.save current stack state
+ push %rbp
+ mov %rsp, %rbp
+ push %r15
+ push %r14
+ push %r13
+ push %r12
+ push %rbx
+
+ // store oldp again with more accurate address
+ mov %rsp, (%rdi)
+ // load newp to begin context switch
+ mov %rsi, %rsp
+
+ // load saved state from new stack
+ pop %rbx
+ pop %r12
+ pop %r13
+ pop %r14
+ pop %r15
+ pop %rbp
+
+ // 'return' to complete switch
+ ret
+LFE0:
+
+/* CFI */
+ .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+ .set L$set$0,LECIE1-LSCIE1
+ .long L$set$0 # Length of Common Information Entry
+LSCIE1:
+ .long 0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
+ .byte 0x78 # sleb128 -8; CIE Data Alignment Factor
+ .byte 0x10 # CIE RA Column
+ .byte 0x1 # uleb128 0x1; Augmentation size
+ .byte 0x10 # FDE Encoding (pcrel)
+ .byte 0xc # DW_CFA_def_cfa
+ .byte 0x7 # uleb128 0x7
+ .byte 0x8 # uleb128 0x8
+ .byte 0x90 # DW_CFA_offset, column 0x10
+ .byte 0x1 # uleb128 0x1
+ .p2align 3,0
+LECIE1:
+
+/* minimal FDE - does not record the stack frame changes. */
+LSFDE1:
+ .set L$set$1,LEFDE1-LASFDE1
+ .long L$set$1 # FDE Length
+LASFDE1:
+ .long LASFDE1-EH_frame1 # FDE CIE offset
+ .quad LFB0-. # FDE initial location
+ .set L$set$2,LFE0-LFB0
+ .quad L$set$2 # FDE address range
+ .byte 0 # uleb128 0; Augmentation size
+ .p2align 3,0
+LEFDE1:
+
+# endif /* defined(__MACH__) && defined(__x86_64__) && !defined(__ILP32__) */
+
+# endif /* defined (__MACH__) */
+
+#endif /* !defined(__CET__) */
diff --git a/libphobos/libdruntime/core/bitop.d b/libphobos/libdruntime/core/bitop.d
index 0daee55..25b5cd5 100644
--- a/libphobos/libdruntime/core/bitop.d
+++ b/libphobos/libdruntime/core/bitop.d
@@ -267,7 +267,7 @@ unittest
* (No longer an intrisic - the compiler recognizes the patterns
* in the body.)
*/
-int bt(in size_t* p, size_t bitnum) pure @system
+int bt(const scope size_t* p, size_t bitnum) pure @system
{
static if (size_t.sizeof == 8)
return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;
@@ -495,25 +495,61 @@ struct BitRange
}
/**
+ * Swaps bytes in a 2 byte ushort.
+ * Params:
+ * x = value
+ * Returns:
+ * `x` with bytes swapped
+ */
+pragma(inline, false)
+ushort byteswap(ushort x) pure
+{
+ /* Calling it bswap(ushort) would break existing code that calls bswap(uint).
+ *
+ * This pattern is meant to be recognized by the dmd code generator.
+ * Don't change it without checking that an XCH instruction is still
+ * used to implement it.
+ * Inlining may also throw it off.
+ */
+ return cast(ushort) (((x >> 8) & 0xFF) | ((x << 8) & 0xFF00u));
+}
+
+///
+unittest
+{
+ assert(byteswap(cast(ushort)0xF234) == 0x34F2);
+ static ushort xx = 0xF234;
+ assert(byteswap(xx) == 0x34F2);
+}
+
+/**
* Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes
* byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3
* becomes byte 0.
*/
uint bswap(uint v) pure;
+///
+unittest
+{
+ assert(bswap(0x01020304u) == 0x04030201u);
+ static uint xx = 0x10203040u;
+ assert(bswap(xx) == 0x40302010u);
+}
+
/**
* Swaps bytes in an 8 byte ulong end-to-end, i.e. byte 0 becomes
* byte 7, byte 1 becomes byte 6, etc.
+ * This is meant to be recognized by the compiler as an intrinsic.
*/
-ulong bswap(ulong v) pure
-{
- auto sv = Split64(v);
-
- const temp = sv.lo;
- sv.lo = bswap(sv.hi);
- sv.hi = bswap(temp);
+ulong bswap(ulong v) pure;
- return (cast(ulong) sv.hi << 32) | sv.lo;
+///
+unittest
+{
+ assert(bswap(0x01020304_05060708uL) == 0x08070605_04030201uL);
+ static ulong xx = 0x10203040_50607080uL;
+ assert(bswap(xx) == 0x80706050_40302010uL);
}
version (DigitalMars) version (AnyX86) @system // not pure
@@ -722,57 +758,14 @@ version (DigitalMars) version (AnyX86)
}
-/*************************************
- * Read/write value from/to the memory location indicated by ptr.
- *
- * These functions are recognized by the compiler, and calls to them are guaranteed
- * to not be removed (as dead assignment elimination or presumed to have no effect)
- * or reordered in the same thread.
- *
- * These reordering guarantees are only made with regards to other
- * operations done through these functions; the compiler is free to reorder regular
- * loads/stores with regards to loads/stores done through these functions.
- *
- * This is useful when dealing with memory-mapped I/O (MMIO) where a store can
- * have an effect other than just writing a value, or where sequential loads
- * with no intervening stores can retrieve
- * different values from the same location due to external stores to the location.
- *
- * These functions will, when possible, do the load/store as a single operation. In
- * general, this is possible when the size of the operation is less than or equal to
- * $(D (void*).sizeof), although some targets may support larger operations. If the
- * load/store cannot be done as a single operation, multiple smaller operations will be used.
- *
- * These are not to be conflated with atomic operations. They do not guarantee any
- * atomicity. This may be provided by coincidence as a result of the instructions
- * used on the target, but this should not be relied on for portable programs.
- * Further, no memory fences are implied by these functions.
- * They should not be used for communication between threads.
- * They may be used to guarantee a write or read cycle occurs at a specified address.
- */
-
-ubyte volatileLoad(ubyte * ptr);
-ushort volatileLoad(ushort* ptr); /// ditto
-uint volatileLoad(uint * ptr); /// ditto
-ulong volatileLoad(ulong * ptr); /// ditto
-
-void volatileStore(ubyte * ptr, ubyte value); /// ditto
-void volatileStore(ushort* ptr, ushort value); /// ditto
-void volatileStore(uint * ptr, uint value); /// ditto
-void volatileStore(ulong * ptr, ulong value); /// ditto
-
-@system unittest
+deprecated("volatileLoad has been moved to core.volatile. Use core.volatile.volatileLoad instead.")
{
- alias TT(T...) = T;
+ public import core.volatile : volatileLoad;
+}
- foreach (T; TT!(ubyte, ushort, uint, ulong))
- {
- T u;
- T* p = &u;
- volatileStore(p, 1);
- T r = volatileLoad(p);
- assert(r == u);
- }
+deprecated("volatileStore has been moved to core.volatile. Use core.volatile.volatileStore instead.")
+{
+ public import core.volatile : volatileStore;
}
@@ -954,51 +947,51 @@ version (D_InlineAsm_X86_64)
* Bitwise rotate `value` left (`rol`) or right (`ror`) by
* `count` bit positions.
*/
-pure T rol(T)(in T value, in uint count)
+pure T rol(T)(const T value, const uint count)
if (__traits(isIntegral, T) && __traits(isUnsigned, T))
{
assert(count < 8 * T.sizeof);
- return cast(T) ((value << count) | (value >> (-count & (T.sizeof * 8 - 1))));
+ return cast(T) ((value << count) | (value >> (T.sizeof * 8 - count)));
}
/// ditto
-pure T ror(T)(in T value, in uint count)
+pure T ror(T)(const T value, const uint count)
if (__traits(isIntegral, T) && __traits(isUnsigned, T))
{
assert(count < 8 * T.sizeof);
- return cast(T) ((value >> count) | (value << (-count & (T.sizeof * 8 - 1))));
+ return cast(T) ((value >> count) | (value << (T.sizeof * 8 - count)));
}
/// ditto
-pure T rol(uint count, T)(in T value)
+pure T rol(uint count, T)(const T value)
if (__traits(isIntegral, T) && __traits(isUnsigned, T))
{
static assert(count < 8 * T.sizeof);
- return cast(T) ((value << count) | (value >> (-count & (T.sizeof * 8 - 1))));
+ return cast(T) ((value << count) | (value >> (T.sizeof * 8 - count)));
}
/// ditto
-pure T ror(uint count, T)(in T value)
+pure T ror(uint count, T)(const T value)
if (__traits(isIntegral, T) && __traits(isUnsigned, T))
{
static assert(count < 8 * T.sizeof);
- return cast(T) ((value >> count) | (value << (-count & (T.sizeof * 8 - 1))));
+ return cast(T) ((value >> count) | (value << (T.sizeof * 8 - count)));
}
///
unittest
{
- ubyte a = 0b10101010U;
- ulong b = ulong.max;
+ ubyte a = 0b11110000U;
+ ulong b = ~1UL;
- assert(rol(a, 1) == 0b01010101);
- assert(ror(a, 1) == 0b01010101);
- assert(rol(a, 3) == 0b01010101);
- assert(ror(a, 3) == 0b01010101);
+ assert(rol(a, 1) == 0b11100001);
+ assert(ror(a, 1) == 0b01111000);
+ assert(rol(a, 3) == 0b10000111);
+ assert(ror(a, 3) == 0b00011110);
assert(rol(a, 0) == a);
assert(ror(a, 0) == a);
- assert(rol(b, 63) == ulong.max);
- assert(ror(b, 63) == ulong.max);
+ assert(rol(b, 63) == ~(1UL << 63));
+ assert(ror(b, 63) == ~2UL);
- assert(rol!3(a) == 0b01010101);
- assert(ror!3(a) == 0b01010101);
+ assert(rol!3(a) == 0b10000111);
+ assert(ror!3(a) == 0b00011110);
}
diff --git a/libphobos/libdruntime/core/checkedint.d b/libphobos/libdruntime/core/checkedint.d
index 237c8e4..57209ad 100644
--- a/libphobos/libdruntime/core/checkedint.d
+++ b/libphobos/libdruntime/core/checkedint.d
@@ -47,7 +47,7 @@ pure:
*/
pragma(inline, true)
-int adds(int x, int y, ref bool overflow)
+int adds()(int x, int y, ref bool overflow)
{
long r = cast(long)x + cast(long)y;
if (r < int.min || r > int.max)
@@ -75,7 +75,7 @@ unittest
/// ditto
pragma(inline, true)
-long adds(long x, long y, ref bool overflow)
+long adds()(long x, long y, ref bool overflow)
{
long r = cast(ulong)x + cast(ulong)y;
if (x < 0 && y < 0 && r >= 0 ||
@@ -106,7 +106,7 @@ static if (is(cent))
{
/// ditto
pragma(inline, true)
-cent adds(cent x, cent y, ref bool overflow)
+cent adds()(cent x, cent y, ref bool overflow)
{
cent r = cast(ucent)x + cast(ucent)y;
if (x < 0 && y < 0 && r >= 0 ||
@@ -149,7 +149,7 @@ unittest
*/
pragma(inline, true)
-uint addu(uint x, uint y, ref bool overflow)
+uint addu()(uint x, uint y, ref bool overflow)
{
immutable uint r = x + y;
if (r < x || r < y)
@@ -177,7 +177,7 @@ unittest
/// ditto
pragma(inline, true)
-ulong addu(ulong x, ulong y, ref bool overflow)
+ulong addu()(ulong x, ulong y, ref bool overflow)
{
immutable ulong r = x + y;
if (r < x || r < y)
@@ -207,7 +207,7 @@ static if (is(ucent))
{
/// ditto
pragma(inline, true)
-ucent addu(ucent x, ucent y, ref bool overflow)
+ucent addu()(ucent x, ucent y, ref bool overflow)
{
immutable ucent r = x + y;
if (r < x || r < y)
@@ -249,7 +249,7 @@ unittest
*/
pragma(inline, true)
-int subs(int x, int y, ref bool overflow)
+int subs()(int x, int y, ref bool overflow)
{
immutable long r = cast(long)x - cast(long)y;
if (r < int.min || r > int.max)
@@ -277,7 +277,7 @@ unittest
/// ditto
pragma(inline, true)
-long subs(long x, long y, ref bool overflow)
+long subs()(long x, long y, ref bool overflow)
{
immutable long r = cast(ulong)x - cast(ulong)y;
if (x < 0 && y >= 0 && r >= 0 ||
@@ -310,7 +310,7 @@ static if (is(cent))
{
/// ditto
pragma(inline, true)
-cent subs(cent x, cent y, ref bool overflow)
+cent subs()(cent x, cent y, ref bool overflow)
{
immutable cent r = cast(ucent)x - cast(ucent)y;
if (x < 0 && y >= 0 && r >= 0 ||
@@ -355,7 +355,7 @@ unittest
*/
pragma(inline, true)
-uint subu(uint x, uint y, ref bool overflow)
+uint subu()(uint x, uint y, ref bool overflow)
{
if (x < y)
overflow = true;
@@ -383,7 +383,7 @@ unittest
/// ditto
pragma(inline, true)
-ulong subu(ulong x, ulong y, ref bool overflow)
+ulong subu()(ulong x, ulong y, ref bool overflow)
{
if (x < y)
overflow = true;
@@ -412,7 +412,7 @@ static if (is(ucent))
{
/// ditto
pragma(inline, true)
-ucent subu(ucent x, ucent y, ref bool overflow)
+ucent subu()(ucent x, ucent y, ref bool overflow)
{
if (x < y)
overflow = true;
@@ -450,7 +450,7 @@ unittest
*/
pragma(inline, true)
-int negs(int x, ref bool overflow)
+int negs()(int x, ref bool overflow)
{
if (x == int.min)
overflow = true;
@@ -474,7 +474,7 @@ unittest
/// ditto
pragma(inline, true)
-long negs(long x, ref bool overflow)
+long negs()(long x, ref bool overflow)
{
if (x == long.min)
overflow = true;
@@ -500,7 +500,7 @@ static if (is(cent))
{
/// ditto
pragma(inline, true)
-cent negs(cent x, ref bool overflow)
+cent negs()(cent x, ref bool overflow)
{
if (x == cent.min)
overflow = true;
@@ -538,7 +538,7 @@ unittest
*/
pragma(inline, true)
-int muls(int x, int y, ref bool overflow)
+int muls()(int x, int y, ref bool overflow)
{
long r = cast(long)x * cast(long)y;
if (r < int.min || r > int.max)
@@ -568,11 +568,13 @@ unittest
/// ditto
pragma(inline, true)
-long muls(long x, long y, ref bool overflow)
+long muls()(long x, long y, ref bool overflow)
{
immutable long r = cast(ulong)x * cast(ulong)y;
enum not0or1 = ~1L;
- if ((x & not0or1) && ((r == y)? r : (r / x) != y))
+ if ((x & not0or1) &&
+ ((r == y) ? r != 0
+ : (r == 0x8000_0000_0000_0000 && x == -1L) || ((r / x) != y)))
overflow = true;
return r;
}
@@ -604,7 +606,7 @@ static if (is(cent))
{
/// ditto
pragma(inline, true)
-cent muls(cent x, cent y, ref bool overflow)
+cent muls()(cent x, cent y, ref bool overflow)
{
immutable cent r = cast(ucent)x * cast(ucent)y;
enum not0or1 = ~1L;
@@ -652,7 +654,7 @@ unittest
*/
pragma(inline, true)
-uint mulu(uint x, uint y, ref bool overflow)
+uint mulu()(uint x, uint y, ref bool overflow)
{
immutable ulong r = ulong(x) * ulong(y);
if (r >> 32)
@@ -682,7 +684,7 @@ unittest
/// ditto
pragma(inline, true)
-ulong mulu(ulong x, uint y, ref bool overflow)
+ulong mulu()(ulong x, uint y, ref bool overflow)
{
ulong r = x * y;
if (x >> 32 &&
@@ -693,7 +695,7 @@ ulong mulu(ulong x, uint y, ref bool overflow)
/// ditto
pragma(inline, true)
-ulong mulu(ulong x, ulong y, ref bool overflow)
+ulong mulu()(ulong x, ulong y, ref bool overflow)
{
immutable ulong r = x * y;
if ((x | y) >> 32 &&
@@ -751,7 +753,7 @@ static if (is(ucent))
{
/// ditto
pragma(inline, true)
-ucent mulu(ucent x, ucent y, ref bool overflow)
+ucent mulu()(ucent x, ucent y, ref bool overflow)
{
immutable ucent r = x * y;
if (x && (r / x) != y)
diff --git a/libphobos/libdruntime/core/cpuid.d b/libphobos/libdruntime/core/cpuid.d
index 2ba13b5..e31f776 100644
--- a/libphobos/libdruntime/core/cpuid.d
+++ b/libphobos/libdruntime/core/cpuid.d
@@ -56,6 +56,9 @@
module core.cpuid;
+version (GNU) version = GNU_OR_LDC;
+version (LDC) version = GNU_OR_LDC;
+
@trusted:
nothrow:
@nogc:
@@ -318,10 +321,10 @@ private:
struct CpuFeatures
{
bool probablyIntel; // true = _probably_ an Intel processor, might be faking
- bool probablyAMD; // true = _probably_ an AMD processor
+ bool probablyAMD; // true = _probably_ an AMD or Hygon processor
string processorName;
- char [12] vendorID;
- char [48] processorNameBuffer;
+ char [12] vendorID = 0;
+ char [48] processorNameBuffer = 0;
uint features = 0; // mmx, sse, sse2, hyperthreading, etc
uint miscfeatures = 0; // sse3, etc.
uint extfeatures = 0; // HLE, AVX2, RTM, etc.
@@ -426,7 +429,7 @@ CpuFeatures* getCpuFeatures() @nogc nothrow
}
-version (GNU) {
+version (GNU_OR_LDC) {
version (X86)
enum supportedX86 = true;
else version (X86_64)
@@ -509,12 +512,12 @@ void getcacheinfoCPUID2()
// for old single-core CPUs.
uint numinfos = 1;
do {
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a[0]), "=b" (a[1]), "=c" (a[2]), "=d" (a[3]) : "a" (2);
} else asm pure nothrow @nogc {
mov EAX, 2;
cpuid;
- mov a, EAX;
+ mov a+0, EAX;
mov a+4, EBX;
mov a+8, ECX;
mov a+12, EDX;
@@ -553,7 +556,7 @@ void getcacheinfoCPUID4()
int cachenum = 0;
for (;;) {
uint a, b, number_of_sets;
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=b" (b), "=c" (number_of_sets) : "a" (4), "c" (cachenum) : "edx";
} else asm pure nothrow @nogc {
mov EAX, 4;
@@ -593,7 +596,7 @@ void getcacheinfoCPUID4()
void getAMDcacheinfo()
{
uint dummy, c5, c6, d6;
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (dummy), "=c" (c5) : "a" (0x8000_0005) : "ebx", "edx";
} else asm pure nothrow @nogc {
mov EAX, 0x8000_0005; // L1 cache
@@ -612,7 +615,7 @@ void getAMDcacheinfo()
// AMD K6-III or K6-2+ or later.
ubyte numcores = 1;
if (max_extended_cpuid >= 0x8000_0008) {
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (dummy), "=c" (numcores) : "a" (0x8000_0008) : "ebx", "edx";
} else asm pure nothrow @nogc {
mov EAX, 0x8000_0008;
@@ -623,7 +626,7 @@ void getAMDcacheinfo()
if (numcores>cpuFeatures.maxCores) cpuFeatures.maxCores = numcores;
}
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (dummy), "=c" (c6), "=d" (d6) : "a" (0x8000_0006) : "ebx";
} else asm pure nothrow @nogc {
mov EAX, 0x8000_0006; // L2/L3 cache
@@ -652,7 +655,7 @@ void getCpuInfo0B()
int threadsPerCore;
uint a, b, c, d;
do {
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (0x0B), "c" (level);
} else asm pure nothrow @nogc {
mov EAX, 0x0B;
@@ -684,7 +687,7 @@ void cpuidX86()
uint a, b, c, d;
uint* venptr = cast(uint*)cf.vendorID.ptr;
- version (GNU)
+ version (GNU_OR_LDC)
{
asm pure nothrow @nogc {
"cpuid" : "=a" (max_cpuid), "=b" (venptr[0]), "=d" (venptr[1]), "=c" (venptr[2]) : "a" (0);
@@ -729,9 +732,9 @@ void cpuidX86()
cf.probablyIntel = cf.vendorID == "GenuineIntel";
- cf.probablyAMD = cf.vendorID == "AuthenticAMD";
+ cf.probablyAMD = (cf.vendorID == "AuthenticAMD" || cf.vendorID == "HygonGenuine");
uint apic = 0; // brand index, apic id
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=b" (apic), "=c" (cf.miscfeatures), "=d" (cf.features) : "a" (1);
} else {
asm pure nothrow @nogc {
@@ -754,7 +757,7 @@ void cpuidX86()
if (max_cpuid >= 7)
{
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=b" (cf.extfeatures), "=c" (c) : "a" (7), "c" (0) : "edx";
} else {
uint ext;
@@ -770,8 +773,11 @@ void cpuidX86()
if (cf.miscfeatures & OSXSAVE_BIT)
{
- version (GNU) asm pure nothrow @nogc {
- "xgetbv" : "=a" (a), "=d" (d) : "c" (0);
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
+ /* Old assemblers do not recognize xgetbv, and there is no easy way
+ * to conditionally compile based on the assembler used, so use the
+ * raw .byte sequence instead. */
+ ".byte 0x0f, 0x01, 0xd0" : "=a" (a), "=d" (d) : "c" (0);
} else asm pure nothrow @nogc {
mov ECX, 0;
xgetbv;
@@ -784,7 +790,7 @@ void cpuidX86()
cf.amdfeatures = 0;
cf.amdmiscfeatures = 0;
if (max_extended_cpuid >= 0x8000_0001) {
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=c" (cf.amdmiscfeatures), "=d" (cf.amdfeatures) : "a" (0x8000_0001) : "ebx";
} else {
asm pure nothrow @nogc {
@@ -805,7 +811,7 @@ void cpuidX86()
cf.maxCores = 1;
if (hyperThreadingBit) {
// determine max number of cores for AMD
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=c" (c) : "a" (0x8000_0008) : "ebx", "edx";
} else asm pure nothrow @nogc {
mov EAX, 0x8000_0008;
@@ -818,7 +824,7 @@ void cpuidX86()
if (max_extended_cpuid >= 0x8000_0004) {
uint* pnb = cast(uint*)cf.processorNameBuffer.ptr;
- version (GNU)
+ version (GNU_OR_LDC)
{
asm pure nothrow @nogc {
"cpuid" : "=a" (pnb[0]), "=b" (pnb[1]), "=c" (pnb[ 2]), "=d" (pnb[ 3]) : "a" (0x8000_0002);
@@ -950,7 +956,7 @@ void cpuidX86()
else cf.maxThreads = cf.maxCores;
if (cf.probablyAMD && max_extended_cpuid >= 0x8000_001E) {
- version (GNU) asm pure nothrow @nogc {
+ version (GNU_OR_LDC) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=b" (b) : "a" (0x8000_001E) : "ecx", "edx";
} else {
asm pure nothrow @nogc {
@@ -974,21 +980,18 @@ bool hasCPUID()
else
{
uint flags;
- version (GNU)
+ version (GNU_OR_LDC)
{
// http://wiki.osdev.org/CPUID#Checking_CPUID_availability
- // ASM template supports both AT&T and Intel syntax.
asm nothrow @nogc { "
- pushf{l|d} # Save EFLAGS
- pushf{l|d} # Store EFLAGS
- xor{l $0x00200000, (%%esp)| dword ptr [esp], 0x00200000}
- # Invert the ID bit in stored EFLAGS
- popf{l|d} # Load stored EFLAGS (with ID bit inverted)
- pushf{l|d} # Store EFLAGS again (ID bit may or may not be inverted)
- pop {%%}eax # eax = modified EFLAGS (ID bit may or may not be inverted)
- xor {(%%esp), %%eax|eax, [esp]}
- # eax = whichever bits were changed
- popf{l|d} # Restore original EFLAGS
+ pushfl # Save EFLAGS
+ pushfl # Store EFLAGS
+ xorl $0x00200000, (%%esp) # Invert the ID bit in stored EFLAGS
+ popfl # Load stored EFLAGS (with ID bit inverted)
+ pushfl # Store EFLAGS again (ID bit may or may not be inverted)
+ popl %%eax # eax = modified EFLAGS (ID bit may or may not be inverted)
+ xorl (%%esp), %%eax # eax = whichever bits were changed
+ popfl # Restore original EFLAGS
" : "=a" (flags);
}
}
diff --git a/libphobos/libdruntime/core/internal/abort.d b/libphobos/libdruntime/core/internal/abort.d
index dfa3496..8ee1684 100644
--- a/libphobos/libdruntime/core/internal/abort.d
+++ b/libphobos/libdruntime/core/internal/abort.d
@@ -4,7 +4,7 @@ module core.internal.abort;
* Use instead of assert(0, msg), since this does not print a message for -release compiled
* code, and druntime is -release compiled.
*/
-void abort(string msg, string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe
+void abort(scope string msg, scope string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe
{
import core.stdc.stdlib: c_abort = abort;
// use available OS system calls to print the message to stderr
diff --git a/libphobos/libdruntime/core/internal/attributes.d b/libphobos/libdruntime/core/internal/attributes.d
new file mode 100644
index 0000000..b7253c2
--- /dev/null
+++ b/libphobos/libdruntime/core/internal/attributes.d
@@ -0,0 +1,11 @@
+module core.internal.attributes;
+
+/**
+Used to annotate `unittest`s which need to be tested in a `-betterC` environment.
+
+Such `unittest`s will be compiled and executed without linking druntime in, with
+a `__traits(getUnitTests, mixin(__MODULE__))` style test runner.
+Note that just like any other `unittest` in druntime, they will also be compiled
+and executed without `-betterC`.
+*/
+package(core) enum betterC = 1;
diff --git a/libphobos/libdruntime/core/internal/traits.d b/libphobos/libdruntime/core/internal/traits.d
index e56f016..9f79dd0 100644
--- a/libphobos/libdruntime/core/internal/traits.d
+++ b/libphobos/libdruntime/core/internal/traits.d
@@ -8,10 +8,16 @@
*/
module core.internal.traits;
-/// taken from std.typetuple.TypeTuple
-template TypeTuple(TList...)
+alias AliasSeq(TList...) = TList;
+
+template Fields(T)
{
- alias TypeTuple = TList;
+ static if (is(T == struct) || is(T == union))
+ alias Fields = typeof(T.tupleof[0 .. $ - __traits(isNested, T)]);
+ else static if (is(T == class))
+ alias Fields = typeof(T.tupleof);
+ else
+ alias Fields = AliasSeq!T;
}
T trustedCast(T, U)(auto ref U u) @trusted pure nothrow
@@ -109,17 +115,17 @@ template staticIota(int beg, int end)
{
static if (beg >= end)
{
- alias staticIota = TypeTuple!();
+ alias staticIota = AliasSeq!();
}
else
{
- alias staticIota = TypeTuple!(+beg);
+ alias staticIota = AliasSeq!(+beg);
}
}
else
{
enum mid = beg + (end - beg) / 2;
- alias staticIota = TypeTuple!(staticIota!(beg, mid), staticIota!(mid, end));
+ alias staticIota = AliasSeq!(staticIota!(beg, mid), staticIota!(mid, end));
}
}
@@ -235,24 +241,150 @@ template hasElaborateCopyConstructor(T...)
enum bool hasElaborateCopyConstructor = false;
}
+template hasUnsharedIndirections(T)
+{
+ static if (is(T == immutable))
+ enum hasUnsharedIndirections = false;
+ else static if (is(T == struct) || is(T == union))
+ enum hasUnsharedIndirections = anySatisfy!(.hasUnsharedIndirections, Fields!T);
+ else static if (is(T : E[N], E, size_t N))
+ enum hasUnsharedIndirections = is(E == void) ? false : hasUnsharedIndirections!E;
+ else static if (isFunctionPointer!T)
+ enum hasUnsharedIndirections = false;
+ else static if (isPointer!T)
+ enum hasUnsharedIndirections = !is(T : shared(U)*, U) && !is(T : immutable(U)*, U);
+ else static if (isDynamicArray!T)
+ enum hasUnsharedIndirections = !is(T : shared(V)[], V) && !is(T : immutable(V)[], V);
+ else static if (is(T == class) || is(T == interface))
+ enum hasUnsharedIndirections = !is(T : shared(W), W);
+ else
+ enum hasUnsharedIndirections = isDelegate!T || __traits(isAssociativeArray, T); // TODO: how to handle these?
+}
+
+unittest
+{
+ static struct Foo { shared(int)* val; }
+
+ static assert(!hasUnsharedIndirections!(immutable(char)*));
+ static assert(!hasUnsharedIndirections!(string));
+
+ static assert(!hasUnsharedIndirections!(Foo));
+ static assert( hasUnsharedIndirections!(Foo*));
+ static assert(!hasUnsharedIndirections!(shared(Foo)*));
+ static assert(!hasUnsharedIndirections!(immutable(Foo)*));
+}
+
+enum bool isAggregateType(T) = is(T == struct) || is(T == union) ||
+ is(T == class) || is(T == interface);
+
+enum bool isPointer(T) = is(T == U*, U) && !isAggregateType!T;
+
+enum bool isDynamicArray(T) = is(DynamicArrayTypeOf!T) && !isAggregateType!T;
+
+template OriginalType(T)
+{
+ template Impl(T)
+ {
+ static if (is(T U == enum)) alias Impl = OriginalType!U;
+ else alias Impl = T;
+ }
+
+ alias OriginalType = ModifyTypePreservingTQ!(Impl, T);
+}
+
+template DynamicArrayTypeOf(T)
+{
+ static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT))
+ alias X = DynamicArrayTypeOf!AT;
+ else
+ alias X = OriginalType!T;
+
+ static if (is(Unqual!X : E[], E) && !is(typeof({ enum n = X.length; })))
+ alias DynamicArrayTypeOf = X;
+ else
+ static assert(0, T.stringof ~ " is not a dynamic array");
+}
+
+private template AliasThisTypeOf(T)
+ if (isAggregateType!T)
+{
+ alias members = __traits(getAliasThis, T);
+
+ static if (members.length == 1)
+ alias AliasThisTypeOf = typeof(__traits(getMember, T.init, members[0]));
+ else
+ static assert(0, T.stringof~" does not have alias this type");
+}
+
+template isFunctionPointer(T...)
+ if (T.length == 1)
+{
+ static if (is(T[0] U) || is(typeof(T[0]) U))
+ {
+ static if (is(U F : F*) && is(F == function))
+ enum bool isFunctionPointer = true;
+ else
+ enum bool isFunctionPointer = false;
+ }
+ else
+ enum bool isFunctionPointer = false;
+}
+
+template isDelegate(T...)
+ if (T.length == 1)
+{
+ static if (is(typeof(& T[0]) U : U*) && is(typeof(& T[0]) U == delegate))
+ {
+ // T is a (nested) function symbol.
+ enum bool isDelegate = true;
+ }
+ else static if (is(T[0] W) || is(typeof(T[0]) W))
+ {
+ // T is an expression or a type. Take the type of it and examine.
+ enum bool isDelegate = is(W == delegate);
+ }
+ else
+ enum bool isDelegate = false;
+}
+
// std.meta.Filter
template Filter(alias pred, TList...)
{
static if (TList.length == 0)
{
- alias Filter = TypeTuple!();
+ alias Filter = AliasSeq!();
}
else static if (TList.length == 1)
{
static if (pred!(TList[0]))
- alias Filter = TypeTuple!(TList[0]);
+ alias Filter = AliasSeq!(TList[0]);
else
- alias Filter = TypeTuple!();
+ alias Filter = AliasSeq!();
+ }
+ /* The next case speeds up compilation by reducing
+ * the number of Filter instantiations
+ */
+ else static if (TList.length == 2)
+ {
+ static if (pred!(TList[0]))
+ {
+ static if (pred!(TList[1]))
+ alias Filter = AliasSeq!(TList[0], TList[1]);
+ else
+ alias Filter = AliasSeq!(TList[0]);
+ }
+ else
+ {
+ static if (pred!(TList[1]))
+ alias Filter = AliasSeq!(TList[1]);
+ else
+ alias Filter = AliasSeq!();
+ }
}
else
{
alias Filter =
- TypeTuple!(
+ AliasSeq!(
Filter!(pred, TList[ 0 .. $/2]),
Filter!(pred, TList[$/2 .. $ ]));
}
diff --git a/libphobos/libdruntime/core/simd.d b/libphobos/libdruntime/core/simd.d
index 32e2aaf..11a4711 100644
--- a/libphobos/libdruntime/core/simd.d
+++ b/libphobos/libdruntime/core/simd.d
@@ -5,9 +5,10 @@
*
* Source: $(DRUNTIMESRC core/_simd.d)
*
- * Copyright: Copyright Digital Mars 2012.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: $(WEB digitalmars.com, Walter Bright),
+ * Copyright: Copyright Digital Mars 2012-2020
+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ * Authors: $(HTTP digitalmars.com, Walter Bright),
+ * Source: $(DRUNTIMESRC core/_simd.d)
*/
module core.simd;
@@ -38,470 +39,523 @@ template Vector(T)
/* Handy aliases
*/
-static if (is(Vector!(void[8]))) alias Vector!(void[8]) void8; ///
-static if (is(Vector!(double[1]))) alias Vector!(double[1]) double1; ///
-static if (is(Vector!(float[2]))) alias Vector!(float[2]) float2; ///
-static if (is(Vector!(byte[8]))) alias Vector!(byte[8]) byte8; ///
-static if (is(Vector!(ubyte[8]))) alias Vector!(ubyte[8]) ubyte8; ///
-static if (is(Vector!(short[4]))) alias Vector!(short[4]) short4; ///
-static if (is(Vector!(ushort[4]))) alias Vector!(ushort[4]) ushort4; ///
-static if (is(Vector!(int[2]))) alias Vector!(int[2]) int2; ///
-static if (is(Vector!(uint[2]))) alias Vector!(uint[2]) uint2; ///
-static if (is(Vector!(long[1]))) alias Vector!(long[1]) long1; ///
-static if (is(Vector!(ulong[1]))) alias Vector!(ulong[1]) ulong1; ///
-
-static if (is(Vector!(void[16]))) alias Vector!(void[16]) void16; ///
-static if (is(Vector!(double[2]))) alias Vector!(double[2]) double2; ///
-static if (is(Vector!(float[4]))) alias Vector!(float[4]) float4; ///
-static if (is(Vector!(byte[16]))) alias Vector!(byte[16]) byte16; ///
-static if (is(Vector!(ubyte[16]))) alias Vector!(ubyte[16]) ubyte16; ///
-static if (is(Vector!(short[8]))) alias Vector!(short[8]) short8; ///
-static if (is(Vector!(ushort[8]))) alias Vector!(ushort[8]) ushort8; ///
-static if (is(Vector!(int[4]))) alias Vector!(int[4]) int4; ///
-static if (is(Vector!(uint[4]))) alias Vector!(uint[4]) uint4; ///
-static if (is(Vector!(long[2]))) alias Vector!(long[2]) long2; ///
-static if (is(Vector!(ulong[2]))) alias Vector!(ulong[2]) ulong2; ///
-
-static if (is(Vector!(void[32]))) alias Vector!(void[32]) void32; ///
-static if (is(Vector!(double[4]))) alias Vector!(double[4]) double4; ///
-static if (is(Vector!(float[8]))) alias Vector!(float[8]) float8; ///
-static if (is(Vector!(byte[32]))) alias Vector!(byte[32]) byte32; ///
-static if (is(Vector!(ubyte[32]))) alias Vector!(ubyte[32]) ubyte32; ///
-static if (is(Vector!(short[16]))) alias Vector!(short[16]) short16; ///
-static if (is(Vector!(ushort[16]))) alias Vector!(ushort[16]) ushort16; ///
-static if (is(Vector!(int[8]))) alias Vector!(int[8]) int8; ///
-static if (is(Vector!(uint[8]))) alias Vector!(uint[8]) uint8; ///
-static if (is(Vector!(long[4]))) alias Vector!(long[4]) long4; ///
-static if (is(Vector!(ulong[4]))) alias Vector!(ulong[4]) ulong4; ///
+static if (is(Vector!(void[8]))) alias Vector!(void[8]) void8; ///
+static if (is(Vector!(double[1]))) alias Vector!(double[1]) double1; ///
+static if (is(Vector!(float[2]))) alias Vector!(float[2]) float2; ///
+static if (is(Vector!(byte[8]))) alias Vector!(byte[8]) byte8; ///
+static if (is(Vector!(ubyte[8]))) alias Vector!(ubyte[8]) ubyte8; ///
+static if (is(Vector!(short[4]))) alias Vector!(short[4]) short4; ///
+static if (is(Vector!(ushort[4]))) alias Vector!(ushort[4]) ushort4; ///
+static if (is(Vector!(int[2]))) alias Vector!(int[2]) int2; ///
+static if (is(Vector!(uint[2]))) alias Vector!(uint[2]) uint2; ///
+static if (is(Vector!(long[1]))) alias Vector!(long[1]) long1; ///
+static if (is(Vector!(ulong[1]))) alias Vector!(ulong[1]) ulong1; ///
+
+static if (is(Vector!(void[16]))) alias Vector!(void[16]) void16; ///
+static if (is(Vector!(double[2]))) alias Vector!(double[2]) double2; ///
+static if (is(Vector!(float[4]))) alias Vector!(float[4]) float4; ///
+static if (is(Vector!(byte[16]))) alias Vector!(byte[16]) byte16; ///
+static if (is(Vector!(ubyte[16]))) alias Vector!(ubyte[16]) ubyte16; ///
+static if (is(Vector!(short[8]))) alias Vector!(short[8]) short8; ///
+static if (is(Vector!(ushort[8]))) alias Vector!(ushort[8]) ushort8; ///
+static if (is(Vector!(int[4]))) alias Vector!(int[4]) int4; ///
+static if (is(Vector!(uint[4]))) alias Vector!(uint[4]) uint4; ///
+static if (is(Vector!(long[2]))) alias Vector!(long[2]) long2; ///
+static if (is(Vector!(ulong[2]))) alias Vector!(ulong[2]) ulong2; ///
+
+static if (is(Vector!(void[32]))) alias Vector!(void[32]) void32; ///
+static if (is(Vector!(double[4]))) alias Vector!(double[4]) double4; ///
+static if (is(Vector!(float[8]))) alias Vector!(float[8]) float8; ///
+static if (is(Vector!(byte[32]))) alias Vector!(byte[32]) byte32; ///
+static if (is(Vector!(ubyte[32]))) alias Vector!(ubyte[32]) ubyte32; ///
+static if (is(Vector!(short[16]))) alias Vector!(short[16]) short16; ///
+static if (is(Vector!(ushort[16]))) alias Vector!(ushort[16]) ushort16; ///
+static if (is(Vector!(int[8]))) alias Vector!(int[8]) int8; ///
+static if (is(Vector!(uint[8]))) alias Vector!(uint[8]) uint8; ///
+static if (is(Vector!(long[4]))) alias Vector!(long[4]) long4; ///
+static if (is(Vector!(ulong[4]))) alias Vector!(ulong[4]) ulong4; ///
+
+static if (is(Vector!(void[64]))) alias Vector!(void[64]) void64; ///
+static if (is(Vector!(double[8]))) alias Vector!(double[8]) double8; ///
+static if (is(Vector!(float[16]))) alias Vector!(float[16]) float16; ///
+static if (is(Vector!(byte[64]))) alias Vector!(byte[64]) byte64; ///
+static if (is(Vector!(ubyte[64]))) alias Vector!(ubyte[64]) ubyte64; ///
+static if (is(Vector!(short[32]))) alias Vector!(short[32]) short32; ///
+static if (is(Vector!(ushort[32]))) alias Vector!(ushort[32]) ushort32; ///
+static if (is(Vector!(int[16]))) alias Vector!(int[16]) int16; ///
+static if (is(Vector!(uint[16]))) alias Vector!(uint[16]) uint16; ///
+static if (is(Vector!(long[8]))) alias Vector!(long[8]) long8; ///
+static if (is(Vector!(ulong[8]))) alias Vector!(ulong[8]) ulong8; ///
version (D_SIMD)
{
- /** XMM opcodes that conform to the following:
- *
- * opcode xmm1,xmm2/mem
- *
- * and do not have side effects (i.e. do not write to memory).
- */
- enum XMM
- {
- ADDSS = 0xF30F58,
- ADDSD = 0xF20F58,
- ADDPS = 0x000F58,
- ADDPD = 0x660F58,
- PADDB = 0x660FFC,
- PADDW = 0x660FFD,
- PADDD = 0x660FFE,
- PADDQ = 0x660FD4,
-
- SUBSS = 0xF30F5C,
- SUBSD = 0xF20F5C,
- SUBPS = 0x000F5C,
- SUBPD = 0x660F5C,
- PSUBB = 0x660FF8,
- PSUBW = 0x660FF9,
- PSUBD = 0x660FFA,
- PSUBQ = 0x660FFB,
-
- MULSS = 0xF30F59,
- MULSD = 0xF20F59,
- MULPS = 0x000F59,
- MULPD = 0x660F59,
- PMULLW = 0x660FD5,
-
- DIVSS = 0xF30F5E,
- DIVSD = 0xF20F5E,
- DIVPS = 0x000F5E,
- DIVPD = 0x660F5E,
-
- PAND = 0x660FDB,
- POR = 0x660FEB,
-
- UCOMISS = 0x000F2E,
- UCOMISD = 0x660F2E,
-
- XORPS = 0x000F57,
- XORPD = 0x660F57,
-
- // Use STO and LOD instead of MOV to distinguish the direction
- STOSS = 0xF30F11,
- STOSD = 0xF20F11,
- STOAPS = 0x000F29,
- STOAPD = 0x660F29,
- STODQA = 0x660F7F,
- STOD = 0x660F7E, // MOVD reg/mem64, xmm 66 0F 7E /r
- STOQ = 0x660FD6,
-
- LODSS = 0xF30F10,
- LODSD = 0xF20F10,
- LODAPS = 0x000F28,
- LODAPD = 0x660F28,
- LODDQA = 0x660F6F,
- LODD = 0x660F6E, // MOVD xmm, reg/mem64 66 0F 6E /r
- LODQ = 0xF30F7E,
-
- LODDQU = 0xF30F6F, // MOVDQU xmm1, xmm2/mem128 F3 0F 6F /r
- STODQU = 0xF30F7F, // MOVDQU xmm1/mem128, xmm2 F3 0F 7F /r
- MOVDQ2Q = 0xF20FD6, // MOVDQ2Q mmx, xmm F2 0F D6 /r
- MOVHLPS = 0x0F12, // MOVHLPS xmm1, xmm2 0F 12 /r
- LODHPD = 0x660F16,
- STOHPD = 0x660F17, // MOVHPD mem64, xmm 66 0F 17 /r
- LODHPS = 0x0F16,
- STOHPS = 0x0F17,
- MOVLHPS = 0x0F16,
- LODLPD = 0x660F12,
- STOLPD = 0x660F13,
- LODLPS = 0x0F12,
- STOLPS = 0x0F13,
- MOVMSKPD = 0x660F50,
- MOVMSKPS = 0x0F50,
- MOVNTDQ = 0x660FE7,
- MOVNTI = 0x0FC3,
- MOVNTPD = 0x660F2B,
- MOVNTPS = 0x0F2B,
- MOVNTQ = 0x0FE7,
- MOVQ2DQ = 0xF30FD6,
- LODUPD = 0x660F10,
- STOUPD = 0x660F11,
- LODUPS = 0x0F10,
- STOUPS = 0x0F11,
-
- PACKSSDW = 0x660F6B,
- PACKSSWB = 0x660F63,
- PACKUSWB = 0x660F67,
- PADDSB = 0x660FEC,
- PADDSW = 0x660FED,
- PADDUSB = 0x660FDC,
- PADDUSW = 0x660FDD,
- PANDN = 0x660FDF,
- PCMPEQB = 0x660F74,
- PCMPEQD = 0x660F76,
- PCMPEQW = 0x660F75,
- PCMPGTB = 0x660F64,
- PCMPGTD = 0x660F66,
- PCMPGTW = 0x660F65,
- PMADDWD = 0x660FF5,
- PSLLW = 0x660FF1,
- PSLLD = 0x660FF2,
- PSLLQ = 0x660FF3,
- PSRAW = 0x660FE1,
- PSRAD = 0x660FE2,
- PSRLW = 0x660FD1,
- PSRLD = 0x660FD2,
- PSRLQ = 0x660FD3,
- PSUBSB = 0x660FE8,
- PSUBSW = 0x660FE9,
- PSUBUSB = 0x660FD8,
- PSUBUSW = 0x660FD9,
- PUNPCKHBW = 0x660F68,
- PUNPCKHDQ = 0x660F6A,
- PUNPCKHWD = 0x660F69,
- PUNPCKLBW = 0x660F60,
- PUNPCKLDQ = 0x660F62,
- PUNPCKLWD = 0x660F61,
- PXOR = 0x660FEF,
- ANDPD = 0x660F54,
- ANDPS = 0x0F54,
- ANDNPD = 0x660F55,
- ANDNPS = 0x0F55,
- CMPPS = 0x0FC2,
- CMPPD = 0x660FC2,
- CMPSD = 0xF20FC2,
- CMPSS = 0xF30FC2,
- COMISD = 0x660F2F,
- COMISS = 0x0F2F,
- CVTDQ2PD = 0xF30FE6,
- CVTDQ2PS = 0x0F5B,
- CVTPD2DQ = 0xF20FE6,
- CVTPD2PI = 0x660F2D,
- CVTPD2PS = 0x660F5A,
- CVTPI2PD = 0x660F2A,
- CVTPI2PS = 0x0F2A,
- CVTPS2DQ = 0x660F5B,
- CVTPS2PD = 0x0F5A,
- CVTPS2PI = 0x0F2D,
- CVTSD2SI = 0xF20F2D,
- CVTSD2SS = 0xF20F5A,
- CVTSI2SD = 0xF20F2A,
- CVTSI2SS = 0xF30F2A,
- CVTSS2SD = 0xF30F5A,
- CVTSS2SI = 0xF30F2D,
- CVTTPD2PI = 0x660F2C,
- CVTTPD2DQ = 0x660FE6,
- CVTTPS2DQ = 0xF30F5B,
- CVTTPS2PI = 0x0F2C,
- CVTTSD2SI = 0xF20F2C,
- CVTTSS2SI = 0xF30F2C,
- MASKMOVDQU = 0x660FF7,
- MASKMOVQ = 0x0FF7,
- MAXPD = 0x660F5F,
- MAXPS = 0x0F5F,
- MAXSD = 0xF20F5F,
- MAXSS = 0xF30F5F,
- MINPD = 0x660F5D,
- MINPS = 0x0F5D,
- MINSD = 0xF20F5D,
- MINSS = 0xF30F5D,
- ORPD = 0x660F56,
- ORPS = 0x0F56,
- PAVGB = 0x660FE0,
- PAVGW = 0x660FE3,
- PMAXSW = 0x660FEE,
- //PINSRW = 0x660FC4,
- PMAXUB = 0x660FDE,
- PMINSW = 0x660FEA,
- PMINUB = 0x660FDA,
- //PMOVMSKB = 0x660FD7,
- PMULHUW = 0x660FE4,
- PMULHW = 0x660FE5,
- PMULUDQ = 0x660FF4,
- PSADBW = 0x660FF6,
- PUNPCKHQDQ = 0x660F6D,
- PUNPCKLQDQ = 0x660F6C,
- RCPPS = 0x0F53,
- RCPSS = 0xF30F53,
- RSQRTPS = 0x0F52,
- RSQRTSS = 0xF30F52,
- SQRTPD = 0x660F51,
- SHUFPD = 0x660FC6,
- SHUFPS = 0x0FC6,
- SQRTPS = 0x0F51,
- SQRTSD = 0xF20F51,
- SQRTSS = 0xF30F51,
- UNPCKHPD = 0x660F15,
- UNPCKHPS = 0x0F15,
- UNPCKLPD = 0x660F14,
- UNPCKLPS = 0x0F14,
-
- PSHUFD = 0x660F70,
- PSHUFHW = 0xF30F70,
- PSHUFLW = 0xF20F70,
- PSHUFW = 0x0F70,
- PSLLDQ = 0x07660F73,
- PSRLDQ = 0x03660F73,
-
- //PREFETCH = 0x0F18,
-
-// SSE3 Pentium 4 (Prescott)
-
- ADDSUBPD = 0x660FD0,
- ADDSUBPS = 0xF20FD0,
- HADDPD = 0x660F7C,
- HADDPS = 0xF20F7C,
- HSUBPD = 0x660F7D,
- HSUBPS = 0xF20F7D,
- MOVDDUP = 0xF20F12,
- MOVSHDUP = 0xF30F16,
- MOVSLDUP = 0xF30F12,
- LDDQU = 0xF20FF0,
- MONITOR = 0x0F01C8,
- MWAIT = 0x0F01C9,
-
-// SSSE3
- PALIGNR = 0x660F3A0F,
- PHADDD = 0x660F3802,
- PHADDW = 0x660F3801,
- PHADDSW = 0x660F3803,
- PABSB = 0x660F381C,
- PABSD = 0x660F381E,
- PABSW = 0x660F381D,
- PSIGNB = 0x660F3808,
- PSIGND = 0x660F380A,
- PSIGNW = 0x660F3809,
- PSHUFB = 0x660F3800,
- PMADDUBSW = 0x660F3804,
- PMULHRSW = 0x660F380B,
- PHSUBD = 0x660F3806,
- PHSUBW = 0x660F3805,
- PHSUBSW = 0x660F3807,
-
-// SSE4.1
-
- BLENDPD = 0x660F3A0D,
- BLENDPS = 0x660F3A0C,
- BLENDVPD = 0x660F3815,
- BLENDVPS = 0x660F3814,
- DPPD = 0x660F3A41,
- DPPS = 0x660F3A40,
- EXTRACTPS = 0x660F3A17,
- INSERTPS = 0x660F3A21,
- MPSADBW = 0x660F3A42,
- PBLENDVB = 0x660F3810,
- PBLENDW = 0x660F3A0E,
- PEXTRD = 0x660F3A16,
- PEXTRQ = 0x660F3A16,
- PINSRB = 0x660F3A20,
- PINSRD = 0x660F3A22,
- PINSRQ = 0x660F3A22,
-
- MOVNTDQA = 0x660F382A,
- PACKUSDW = 0x660F382B,
- PCMPEQQ = 0x660F3829,
- PEXTRB = 0x660F3A14,
- PHMINPOSUW = 0x660F3841,
- PMAXSB = 0x660F383C,
- PMAXSD = 0x660F383D,
- PMAXUD = 0x660F383F,
- PMAXUW = 0x660F383E,
- PMINSB = 0x660F3838,
- PMINSD = 0x660F3839,
- PMINUD = 0x660F383B,
- PMINUW = 0x660F383A,
- PMOVSXBW = 0x660F3820,
- PMOVSXBD = 0x660F3821,
- PMOVSXBQ = 0x660F3822,
- PMOVSXWD = 0x660F3823,
- PMOVSXWQ = 0x660F3824,
- PMOVSXDQ = 0x660F3825,
- PMOVZXBW = 0x660F3830,
- PMOVZXBD = 0x660F3831,
- PMOVZXBQ = 0x660F3832,
- PMOVZXWD = 0x660F3833,
- PMOVZXWQ = 0x660F3834,
- PMOVZXDQ = 0x660F3835,
- PMULDQ = 0x660F3828,
- PMULLD = 0x660F3840,
- PTEST = 0x660F3817,
-
- ROUNDPD = 0x660F3A09,
- ROUNDPS = 0x660F3A08,
- ROUNDSD = 0x660F3A0B,
- ROUNDSS = 0x660F3A0A,
-
-// SSE4.2
- PCMPESTRI = 0x660F3A61,
- PCMPESTRM = 0x660F3A60,
- PCMPISTRI = 0x660F3A63,
- PCMPISTRM = 0x660F3A62,
- PCMPGTQ = 0x660F3837,
- //CRC32
-
-// SSE4a (AMD only)
- // EXTRQ,INSERTQ,MOVNTSD,MOVNTSS
-
-// POPCNT and LZCNT (have their own CPUID bits)
- POPCNT = 0xF30FB8,
- // LZCNT
- }
-
- /**
- * Generate two operand instruction with XMM 128 bit operands.
- *
- * This is a compiler magic function - it doesn't behave like
- * regular D functions.
- *
- * Parameters:
- * opcode any of the XMM opcodes; it must be a compile time constant
- * op1 first operand
- * op2 second operand
- * Returns:
- * result of opcode
- */
- pure @safe void16 __simd(XMM opcode, void16 op1, void16 op2);
-
- /**
- * Unary SIMD instructions.
- */
- pure @safe void16 __simd(XMM opcode, void16 op1);
- pure @safe void16 __simd(XMM opcode, double d); ///
- pure @safe void16 __simd(XMM opcode, float f); ///
-
- /****
- * For instructions:
- * CMPPD, CMPSS, CMPSD, CMPPS,
- * PSHUFD, PSHUFHW, PSHUFLW,
- * BLENDPD, BLENDPS, DPPD, DPPS,
- * MPSADBW, PBLENDW,
- * ROUNDPD, ROUNDPS, ROUNDSD, ROUNDSS
- * Parameters:
- * opcode any of the above XMM opcodes; it must be a compile time constant
- * op1 first operand
- * op2 second operand
- * imm8 third operand; must be a compile time constant
- * Returns:
- * result of opcode
- */
- pure @safe void16 __simd(XMM opcode, void16 op1, void16 op2, ubyte imm8);
-
- /***
- * For instructions with the imm8 version:
- * PSLLD, PSLLQ, PSLLW, PSRAD, PSRAW, PSRLD, PSRLQ, PSRLW,
- * PSRLDQ, PSLLDQ
- * Parameters:
- * opcode any of the XMM opcodes; it must be a compile time constant
- * op1 first operand
- * imm8 second operand; must be a compile time constant
- * Returns:
- * result of opcode
- */
- pure @safe void16 __simd_ib(XMM opcode, void16 op1, ubyte imm8);
-
- /*****
- * For "store" operations of the form:
- * op1 op= op2
- * Returns:
- * op2
- * These cannot be marked as pure, as semantic() doesn't check them.
- */
- @safe void16 __simd_sto(XMM opcode, void16 op1, void16 op2);
- @safe void16 __simd_sto(XMM opcode, double op1, void16 op2); ///
- @safe void16 __simd_sto(XMM opcode, float op1, void16 op2); ///
-
- /* The following use overloading to ensure correct typing.
- * Compile with inlining on for best performance.
- */
-
- pure @safe short8 pcmpeq()(short8 v1, short8 v2)
- {
- return __simd(XMM.PCMPEQW, v1, v2);
- }
-
- pure @safe ushort8 pcmpeq()(ushort8 v1, ushort8 v2)
- {
- return __simd(XMM.PCMPEQW, v1, v2);
- }
-
- /*********************
- * Emit prefetch instruction.
- * Params:
- * address = address to be prefetched
- * writeFetch = true for write fetch, false for read fetch
- * locality = 0..3 (0 meaning least local, 3 meaning most local)
- * Note:
- * The Intel mappings are:
- * $(TABLE
- * $(THEAD writeFetch, locality, Instruction)
- * $(TROW false, 0, prefetchnta)
- * $(TROW false, 1, prefetch2)
- * $(TROW false, 2, prefetch1)
- * $(TROW false, 3, prefetch0)
- * $(TROW false, 0, prefetchw)
- * $(TROW false, 1, prefetchw)
- * $(TROW false, 2, prefetchw)
- * $(TROW false, 3, prefetchw)
- * )
- */
- void prefetch(bool writeFetch, ubyte locality)(const(void)* address)
- {
+ /** XMM opcodes that conform to the following:
+ *
+ * opcode xmm1,xmm2/mem
+ *
+ * and do not have side effects (i.e. do not write to memory).
+ */
+ enum XMM
+ {
+ ADDSS = 0xF30F58,
+ ADDSD = 0xF20F58,
+ ADDPS = 0x000F58,
+ ADDPD = 0x660F58,
+ PADDB = 0x660FFC,
+ PADDW = 0x660FFD,
+ PADDD = 0x660FFE,
+ PADDQ = 0x660FD4,
+
+ SUBSS = 0xF30F5C,
+ SUBSD = 0xF20F5C,
+ SUBPS = 0x000F5C,
+ SUBPD = 0x660F5C,
+ PSUBB = 0x660FF8,
+ PSUBW = 0x660FF9,
+ PSUBD = 0x660FFA,
+ PSUBQ = 0x660FFB,
+
+ MULSS = 0xF30F59,
+ MULSD = 0xF20F59,
+ MULPS = 0x000F59,
+ MULPD = 0x660F59,
+ PMULLW = 0x660FD5,
+
+ DIVSS = 0xF30F5E,
+ DIVSD = 0xF20F5E,
+ DIVPS = 0x000F5E,
+ DIVPD = 0x660F5E,
+
+ PAND = 0x660FDB,
+ POR = 0x660FEB,
+
+ UCOMISS = 0x000F2E,
+ UCOMISD = 0x660F2E,
+
+ XORPS = 0x000F57,
+ XORPD = 0x660F57,
+
+ // Use STO and LOD instead of MOV to distinguish the direction
+ // (Destination is first operand, Source is second operand)
+ STOSS = 0xF30F11, /// MOVSS xmm1/m32, xmm2
+ STOSD = 0xF20F11, /// MOVSD xmm1/m64, xmm2
+ STOAPS = 0x000F29, /// MOVAPS xmm2/m128, xmm1
+ STOAPD = 0x660F29, /// MOVAPD xmm2/m128, xmm1
+ STODQA = 0x660F7F, /// MOVDQA xmm2/m128, xmm1
+ STOD = 0x660F7E, /// MOVD reg/mem64, xmm 66 0F 7E /r
+ STOQ = 0x660FD6, /// MOVQ xmm2/m64, xmm1
+
+ LODSS = 0xF30F10, /// MOVSS xmm1, xmm2/m32
+ LODSD = 0xF20F10, /// MOVSD xmm1, xmm2/m64
+ LODAPS = 0x000F28, /// MOVAPS xmm1, xmm2/m128
+ LODAPD = 0x660F28, /// MOVAPD xmm1, xmm2/m128
+ LODDQA = 0x660F6F, /// MOVDQA xmm1, xmm2/m128
+ LODD = 0x660F6E, /// MOVD xmm, reg/mem64 66 0F 6E /r
+ LODQ = 0xF30F7E, /// MOVQ xmm1, xmm2/m64
+
+ LODDQU = 0xF30F6F, /// MOVDQU xmm1, xmm2/mem128 F3 0F 6F /r
+ STODQU = 0xF30F7F, /// MOVDQU xmm1/mem128, xmm2 F3 0F 7F /r
+ MOVDQ2Q = 0xF20FD6, /// MOVDQ2Q mmx, xmm F2 0F D6 /r
+ MOVHLPS = 0x0F12, /// MOVHLPS xmm1, xmm2 0F 12 /r
+ LODHPD = 0x660F16, /// MOVHPD xmm1, m64
+ STOHPD = 0x660F17, /// MOVHPD mem64, xmm1 66 0F 17 /r
+ LODHPS = 0x0F16, /// MOVHPS xmm1, m64
+ STOHPS = 0x0F17, /// MOVHPS m64, xmm1
+ MOVLHPS = 0x0F16, /// MOVLHPS xmm1, xmm2
+ LODLPD = 0x660F12, /// MOVLPD xmm1, m64
+ STOLPD = 0x660F13, /// MOVLPD m64, xmm1
+ LODLPS = 0x0F12, /// MOVLPS xmm1, m64
+ STOLPS = 0x0F13, /// MOVLPS m64, xmm1
+ MOVMSKPD = 0x660F50, /// MOVMSKPD reg, xmm
+ MOVMSKPS = 0x0F50, /// MOVMSKPS reg, xmm
+ MOVNTDQ = 0x660FE7, /// MOVNTDQ m128, xmm1
+ MOVNTI = 0x0FC3, /// MOVNTI m32, r32
+ MOVNTPD = 0x660F2B, /// MOVNTPD m128, xmm1
+ MOVNTPS = 0x0F2B, /// MOVNTPS m128, xmm1
+ MOVNTQ = 0x0FE7, /// MOVNTQ m64, mm
+ MOVQ2DQ = 0xF30FD6, /// MOVQ2DQ
+ LODUPD = 0x660F10, /// MOVUPD xmm1, xmm2/m128
+ STOUPD = 0x660F11, /// MOVUPD xmm2/m128, xmm1
+ LODUPS = 0x0F10, /// MOVUPS xmm1, xmm2/m128
+ STOUPS = 0x0F11, /// MOVUPS xmm2/m128, xmm1
+
+ PACKSSDW = 0x660F6B,
+ PACKSSWB = 0x660F63,
+ PACKUSWB = 0x660F67,
+ PADDSB = 0x660FEC,
+ PADDSW = 0x660FED,
+ PADDUSB = 0x660FDC,
+ PADDUSW = 0x660FDD,
+ PANDN = 0x660FDF,
+ PCMPEQB = 0x660F74,
+ PCMPEQD = 0x660F76,
+ PCMPEQW = 0x660F75,
+ PCMPGTB = 0x660F64,
+ PCMPGTD = 0x660F66,
+ PCMPGTW = 0x660F65,
+ PMADDWD = 0x660FF5,
+ PSLLW = 0x660FF1,
+ PSLLD = 0x660FF2,
+ PSLLQ = 0x660FF3,
+ PSRAW = 0x660FE1,
+ PSRAD = 0x660FE2,
+ PSRLW = 0x660FD1,
+ PSRLD = 0x660FD2,
+ PSRLQ = 0x660FD3,
+ PSUBSB = 0x660FE8,
+ PSUBSW = 0x660FE9,
+ PSUBUSB = 0x660FD8,
+ PSUBUSW = 0x660FD9,
+ PUNPCKHBW = 0x660F68,
+ PUNPCKHDQ = 0x660F6A,
+ PUNPCKHWD = 0x660F69,
+ PUNPCKLBW = 0x660F60,
+ PUNPCKLDQ = 0x660F62,
+ PUNPCKLWD = 0x660F61,
+ PXOR = 0x660FEF,
+ ANDPD = 0x660F54,
+ ANDPS = 0x0F54,
+ ANDNPD = 0x660F55,
+ ANDNPS = 0x0F55,
+ CMPPS = 0x0FC2,
+ CMPPD = 0x660FC2,
+ CMPSD = 0xF20FC2,
+ CMPSS = 0xF30FC2,
+ COMISD = 0x660F2F,
+ COMISS = 0x0F2F,
+ CVTDQ2PD = 0xF30FE6,
+ CVTDQ2PS = 0x0F5B,
+ CVTPD2DQ = 0xF20FE6,
+ CVTPD2PI = 0x660F2D,
+ CVTPD2PS = 0x660F5A,
+ CVTPI2PD = 0x660F2A,
+ CVTPI2PS = 0x0F2A,
+ CVTPS2DQ = 0x660F5B,
+ CVTPS2PD = 0x0F5A,
+ CVTPS2PI = 0x0F2D,
+ CVTSD2SI = 0xF20F2D,
+ CVTSD2SS = 0xF20F5A,
+ CVTSI2SD = 0xF20F2A,
+ CVTSI2SS = 0xF30F2A,
+ CVTSS2SD = 0xF30F5A,
+ CVTSS2SI = 0xF30F2D,
+ CVTTPD2PI = 0x660F2C,
+ CVTTPD2DQ = 0x660FE6,
+ CVTTPS2DQ = 0xF30F5B,
+ CVTTPS2PI = 0x0F2C,
+ CVTTSD2SI = 0xF20F2C,
+ CVTTSS2SI = 0xF30F2C,
+ MASKMOVDQU = 0x660FF7,
+ MASKMOVQ = 0x0FF7,
+ MAXPD = 0x660F5F,
+ MAXPS = 0x0F5F,
+ MAXSD = 0xF20F5F,
+ MAXSS = 0xF30F5F,
+ MINPD = 0x660F5D,
+ MINPS = 0x0F5D,
+ MINSD = 0xF20F5D,
+ MINSS = 0xF30F5D,
+ ORPD = 0x660F56,
+ ORPS = 0x0F56,
+ PAVGB = 0x660FE0,
+ PAVGW = 0x660FE3,
+ PMAXSW = 0x660FEE,
+ //PINSRW = 0x660FC4,
+ PMAXUB = 0x660FDE,
+ PMINSW = 0x660FEA,
+ PMINUB = 0x660FDA,
+ //PMOVMSKB = 0x660FD7,
+ PMULHUW = 0x660FE4,
+ PMULHW = 0x660FE5,
+ PMULUDQ = 0x660FF4,
+ PSADBW = 0x660FF6,
+ PUNPCKHQDQ = 0x660F6D,
+ PUNPCKLQDQ = 0x660F6C,
+ RCPPS = 0x0F53,
+ RCPSS = 0xF30F53,
+ RSQRTPS = 0x0F52,
+ RSQRTSS = 0xF30F52,
+ SQRTPD = 0x660F51,
+ SHUFPD = 0x660FC6,
+ SHUFPS = 0x0FC6,
+ SQRTPS = 0x0F51,
+ SQRTSD = 0xF20F51,
+ SQRTSS = 0xF30F51,
+ UNPCKHPD = 0x660F15,
+ UNPCKHPS = 0x0F15,
+ UNPCKLPD = 0x660F14,
+ UNPCKLPS = 0x0F14,
+
+ PSHUFD = 0x660F70,
+ PSHUFHW = 0xF30F70,
+ PSHUFLW = 0xF20F70,
+ PSHUFW = 0x0F70,
+ PSLLDQ = 0x07660F73,
+ PSRLDQ = 0x03660F73,
+
+ //PREFETCH = 0x0F18,
+
+ // SSE3 Pentium 4 (Prescott)
+
+ ADDSUBPD = 0x660FD0,
+ ADDSUBPS = 0xF20FD0,
+ HADDPD = 0x660F7C,
+ HADDPS = 0xF20F7C,
+ HSUBPD = 0x660F7D,
+ HSUBPS = 0xF20F7D,
+ MOVDDUP = 0xF20F12,
+ MOVSHDUP = 0xF30F16,
+ MOVSLDUP = 0xF30F12,
+ LDDQU = 0xF20FF0,
+ MONITOR = 0x0F01C8,
+ MWAIT = 0x0F01C9,
+
+ // SSSE3
+ PALIGNR = 0x660F3A0F,
+ PHADDD = 0x660F3802,
+ PHADDW = 0x660F3801,
+ PHADDSW = 0x660F3803,
+ PABSB = 0x660F381C,
+ PABSD = 0x660F381E,
+ PABSW = 0x660F381D,
+ PSIGNB = 0x660F3808,
+ PSIGND = 0x660F380A,
+ PSIGNW = 0x660F3809,
+ PSHUFB = 0x660F3800,
+ PMADDUBSW = 0x660F3804,
+ PMULHRSW = 0x660F380B,
+ PHSUBD = 0x660F3806,
+ PHSUBW = 0x660F3805,
+ PHSUBSW = 0x660F3807,
+
+ // SSE4.1
+
+ BLENDPD = 0x660F3A0D,
+ BLENDPS = 0x660F3A0C,
+ BLENDVPD = 0x660F3815,
+ BLENDVPS = 0x660F3814,
+ DPPD = 0x660F3A41,
+ DPPS = 0x660F3A40,
+ EXTRACTPS = 0x660F3A17,
+ INSERTPS = 0x660F3A21,
+ MPSADBW = 0x660F3A42,
+ PBLENDVB = 0x660F3810,
+ PBLENDW = 0x660F3A0E,
+ PEXTRD = 0x660F3A16,
+ PEXTRQ = 0x660F3A16,
+ PINSRB = 0x660F3A20,
+ PINSRD = 0x660F3A22,
+ PINSRQ = 0x660F3A22,
+
+ MOVNTDQA = 0x660F382A,
+ PACKUSDW = 0x660F382B,
+ PCMPEQQ = 0x660F3829,
+ PEXTRB = 0x660F3A14,
+ PHMINPOSUW = 0x660F3841,
+ PMAXSB = 0x660F383C,
+ PMAXSD = 0x660F383D,
+ PMAXUD = 0x660F383F,
+ PMAXUW = 0x660F383E,
+ PMINSB = 0x660F3838,
+ PMINSD = 0x660F3839,
+ PMINUD = 0x660F383B,
+ PMINUW = 0x660F383A,
+ PMOVSXBW = 0x660F3820,
+ PMOVSXBD = 0x660F3821,
+ PMOVSXBQ = 0x660F3822,
+ PMOVSXWD = 0x660F3823,
+ PMOVSXWQ = 0x660F3824,
+ PMOVSXDQ = 0x660F3825,
+ PMOVZXBW = 0x660F3830,
+ PMOVZXBD = 0x660F3831,
+ PMOVZXBQ = 0x660F3832,
+ PMOVZXWD = 0x660F3833,
+ PMOVZXWQ = 0x660F3834,
+ PMOVZXDQ = 0x660F3835,
+ PMULDQ = 0x660F3828,
+ PMULLD = 0x660F3840,
+ PTEST = 0x660F3817,
+
+ ROUNDPD = 0x660F3A09,
+ ROUNDPS = 0x660F3A08,
+ ROUNDSD = 0x660F3A0B,
+ ROUNDSS = 0x660F3A0A,
+
+ // SSE4.2
+ PCMPESTRI = 0x660F3A61,
+ PCMPESTRM = 0x660F3A60,
+ PCMPISTRI = 0x660F3A63,
+ PCMPISTRM = 0x660F3A62,
+ PCMPGTQ = 0x660F3837,
+ //CRC32
+
+ // SSE4a (AMD only)
+ // EXTRQ,INSERTQ,MOVNTSD,MOVNTSS
+
+ // POPCNT and LZCNT (have their own CPUID bits)
+ POPCNT = 0xF30FB8,
+ // LZCNT
+ }
+
+ /**
+ * Generate two operand instruction with XMM 128 bit operands.
+ *
+ * This is a compiler magic function - it doesn't behave like
+ * regular D functions.
+ *
+ * Parameters:
+ * opcode = any of the XMM opcodes; it must be a compile time constant
+ * op1 = first operand
+ * op2 = second operand
+ * Returns:
+ * result of opcode
+ */
+ pure @safe void16 __simd(XMM opcode, void16 op1, void16 op2);
+
+ ///
+ unittest
+ {
+ float4 a;
+ a = cast(float4)__simd(XMM.PXOR, a, a);
+ }
+
+ /**
+ * Unary SIMD instructions.
+ */
+ pure @safe void16 __simd(XMM opcode, void16 op1);
+ pure @safe void16 __simd(XMM opcode, double d); ///
+ pure @safe void16 __simd(XMM opcode, float f); ///
+
+ ///
+ unittest
+ {
+ float4 a;
+ a = cast(float4)__simd(XMM.LODSS, a);
+ }
+
+ /****
+ * For instructions:
+ * CMPPD, CMPSS, CMPSD, CMPPS,
+ * PSHUFD, PSHUFHW, PSHUFLW,
+ * BLENDPD, BLENDPS, DPPD, DPPS,
+ * MPSADBW, PBLENDW,
+ * ROUNDPD, ROUNDPS, ROUNDSD, ROUNDSS
+ * Parameters:
+ * opcode = any of the above XMM opcodes; it must be a compile time constant
+ * op1 = first operand
+ * op2 = second operand
+ * imm8 = third operand; must be a compile time constant
+ * Returns:
+ * result of opcode
+ */
+ pure @safe void16 __simd(XMM opcode, void16 op1, void16 op2, ubyte imm8);
+
+ ///
+ unittest
+ {
+ float4 a;
+ a = cast(float4)__simd(XMM.CMPPD, a, a, 0x7A);
+ }
+
+ /***
+ * For instructions with the imm8 version:
+ * PSLLD, PSLLQ, PSLLW, PSRAD, PSRAW, PSRLD, PSRLQ, PSRLW,
+ * PSRLDQ, PSLLDQ
+ * Parameters:
+ * opcode = any of the XMM opcodes; it must be a compile time constant
+ * op1 = first operand
+ * imm8 = second operand; must be a compile time constant
+ * Returns:
+ * result of opcode
+ */
+ pure @safe void16 __simd_ib(XMM opcode, void16 op1, ubyte imm8);
+
+ ///
+ unittest
+ {
+ float4 a;
+ a = cast(float4) __simd_ib(XMM.PSRLQ, a, 0x7A);
+ }
+
+ /*****
+ * For "store" operations of the form:
+ * op1 op= op2
+ * Returns:
+ * op2
+ * These cannot be marked as pure, as semantic() doesn't check them.
+ */
+ @safe void16 __simd_sto(XMM opcode, void16 op1, void16 op2);
+ @safe void16 __simd_sto(XMM opcode, double op1, void16 op2); ///
+ @safe void16 __simd_sto(XMM opcode, float op1, void16 op2); ///
+
+ ///
+ unittest
+ {
+ void16 a;
+ float f = 1;
+ double d = 1;
+
+ cast(void)__simd_sto(XMM.STOUPS, a, a);
+ cast(void)__simd_sto(XMM.STOUPS, f, a);
+ cast(void)__simd_sto(XMM.STOUPS, d, a);
+ }
+
+ /* The following use overloading to ensure correct typing.
+ * Compile with inlining on for best performance.
+ */
+
+ pure @safe short8 pcmpeq()(short8 v1, short8 v2)
+ {
+ return cast(short8)__simd(XMM.PCMPEQW, v1, v2);
+ }
+
+ pure @safe ushort8 pcmpeq()(ushort8 v1, ushort8 v2)
+ {
+ return cast(ushort8)__simd(XMM.PCMPEQW, v1, v2);
+ }
+
+ /*********************
+ * Emit prefetch instruction.
+ * Params:
+ * address = address to be prefetched
+ * writeFetch = true for write fetch, false for read fetch
+ * locality = 0..3 (0 meaning least local, 3 meaning most local)
+ * Note:
+ * The Intel mappings are:
+ * $(TABLE
+ * $(THEAD writeFetch, locality, Instruction)
+ * $(TROW false, 0, prefetchnta)
+ * $(TROW false, 1, prefetch2)
+ * $(TROW false, 2, prefetch1)
+ * $(TROW false, 3, prefetch0)
+ * $(TROW true, 0, prefetchw)
+ * $(TROW true, 1, prefetchw)
+ * $(TROW true, 2, prefetchw)
+ * $(TROW true, 3, prefetchw)
+ * )
+ */
+ void prefetch(bool writeFetch, ubyte locality)(const(void)* address)
+ {
static if (writeFetch)
__prefetch(address, 4);
else static if (locality < 4)
__prefetch(address, 3 - locality);
else
static assert(0, "0..3 expected for locality");
- }
+ }
- private void __prefetch(const(void*) address, ubyte encoding);
+ private void __prefetch(const(void*) address, ubyte encoding);
- /*************************************
- * Load unaligned vector from address.
- * This is a compiler intrinsic.
- * Params:
- * p = pointer to vector
- * Returns:
- * vector
- */
+ /*************************************
+ * Load unaligned vector from address.
+ * This is a compiler intrinsic.
+ * Params:
+ * p = pointer to vector
+ * Returns:
+ * vector
+ */
- V loadUnaligned(V)(const V* p)
+ V loadUnaligned(V)(const V* p)
if (is(V == void16) ||
is(V == byte16) ||
is(V == ubyte16) ||
@@ -510,8 +564,10 @@ version (D_SIMD)
is(V == int4) ||
is(V == uint4) ||
is(V == long2) ||
- is(V == ulong2))
- {
+ is(V == ulong2) ||
+ is(V == double2) ||
+ is(V == float4))
+ {
pragma(inline, true);
static if (is(V == double2))
return cast(V)__simd(XMM.LODUPD, *cast(const void16*)p);
@@ -519,19 +575,63 @@ version (D_SIMD)
return cast(V)__simd(XMM.LODUPS, *cast(const void16*)p);
else
return cast(V)__simd(XMM.LODDQU, *cast(const void16*)p);
- }
-
- /*************************************
- * Store vector to unaligned address.
- * This is a compiler intrinsic.
- * Params:
- * p = pointer to vector
- * value = value to store
- * Returns:
- * value
- */
-
- V storeUnaligned(V)(V* p, V value)
+ }
+
+ @system
+ unittest
+ {
+ // Memory to load into the vector:
+ // Should have enough data to test all 16-byte alignments, and still
+ // have room for a 16-byte vector
+ ubyte[32] data;
+ foreach (i; 0..data.length)
+ {
+ data[i] = cast(ubyte)i;
+ }
+
+ // to test all alignments from 1 ~ 16
+ foreach (i; 0..16)
+ {
+ ubyte* d = &data[i];
+
+ void test(T)()
+ {
+ // load the data
+ T v = loadUnaligned(cast(T*)d);
+
+ // check that the data was loaded correctly
+ ubyte* ptrToV = cast(ubyte*)&v;
+ foreach (j; 0..T.sizeof)
+ {
+ assert(ptrToV[j] == d[j]);
+ }
+ }
+
+ test!void16();
+ test!byte16();
+ test!ubyte16();
+ test!short8();
+ test!ushort8();
+ test!int4();
+ test!uint4();
+ test!long2();
+ test!ulong2();
+ test!double2();
+ test!float4();
+ }
+ }
+
+ /*************************************
+ * Store vector to unaligned address.
+ * This is a compiler intrinsic.
+ * Params:
+ * p = pointer to vector
+ * value = value to store
+ * Returns:
+ * value
+ */
+
+ V storeUnaligned(V)(V* p, V value)
if (is(V == void16) ||
is(V == byte16) ||
is(V == ubyte16) ||
@@ -540,8 +640,10 @@ version (D_SIMD)
is(V == int4) ||
is(V == uint4) ||
is(V == long2) ||
- is(V == ulong2))
- {
+ is(V == ulong2) ||
+ is(V == double2) ||
+ is(V == float4))
+ {
pragma(inline, true);
static if (is(V == double2))
return cast(V)__simd_sto(XMM.STOUPD, *cast(void16*)p, value);
@@ -549,5 +651,53 @@ version (D_SIMD)
return cast(V)__simd_sto(XMM.STOUPS, *cast(void16*)p, value);
else
return cast(V)__simd_sto(XMM.STODQU, *cast(void16*)p, value);
- }
+ }
+
+ @system
+ unittest
+ {
+ // Memory to store the vector to:
+ // Should have enough data to test all 16-byte alignments, and still
+ // have room for a 16-byte vector
+ ubyte[32] data;
+
+ // to test all alignments from 1 ~ 16
+ foreach (i; 0..16)
+ {
+ ubyte* d = &data[i];
+
+ void test(T)()
+ {
+ T v;
+
+ // populate v` with data
+ ubyte* ptrToV = cast(ubyte*)&v;
+ foreach (j; 0..T.sizeof)
+ {
+ ptrToV[j] = cast(ubyte)j;
+ }
+
+ // store `v` to location pointed to by `d`
+ storeUnaligned(cast(T*)d, v);
+
+ // check that the the data was stored correctly
+ foreach (j; 0..T.sizeof)
+ {
+ assert(ptrToV[j] == d[j]);
+ }
+ }
+
+ test!void16();
+ test!byte16();
+ test!ubyte16();
+ test!short8();
+ test!ushort8();
+ test!int4();
+ test!uint4();
+ test!long2();
+ test!ulong2();
+ test!double2();
+ test!float4();
+ }
+ }
}
diff --git a/libphobos/libdruntime/core/stdc/complex.d b/libphobos/libdruntime/core/stdc/complex.d
index dae35f2..b84651f 100644
--- a/libphobos/libdruntime/core/stdc/complex.d
+++ b/libphobos/libdruntime/core/stdc/complex.d
@@ -19,159 +19,97 @@ extern (C):
nothrow:
@nogc:
-///
+// @@@DEPRECATED_2.105@@@
+deprecated:
alias creal complex;
-///
alias ireal imaginary;
-///
cdouble cacos(cdouble z);
-///
cfloat cacosf(cfloat z);
-///
creal cacosl(creal z);
-///
cdouble casin(cdouble z);
-///
cfloat casinf(cfloat z);
-///
creal casinl(creal z);
-///
cdouble catan(cdouble z);
-///
cfloat catanf(cfloat z);
-///
creal catanl(creal z);
-///
cdouble ccos(cdouble z);
-///
cfloat ccosf(cfloat z);
-///
creal ccosl(creal z);
-///
cdouble csin(cdouble z);
-///
cfloat csinf(cfloat z);
-///
creal csinl(creal z);
-///
cdouble ctan(cdouble z);
-///
cfloat ctanf(cfloat z);
-///
creal ctanl(creal z);
-///
cdouble cacosh(cdouble z);
-///
cfloat cacoshf(cfloat z);
-///
creal cacoshl(creal z);
-///
cdouble casinh(cdouble z);
-///
cfloat casinhf(cfloat z);
-///
creal casinhl(creal z);
-///
cdouble catanh(cdouble z);
-///
cfloat catanhf(cfloat z);
-///
creal catanhl(creal z);
-///
cdouble ccosh(cdouble z);
-///
cfloat ccoshf(cfloat z);
-///
creal ccoshl(creal z);
-///
cdouble csinh(cdouble z);
-///
cfloat csinhf(cfloat z);
-///
creal csinhl(creal z);
-///
cdouble ctanh(cdouble z);
-///
cfloat ctanhf(cfloat z);
-///
creal ctanhl(creal z);
-///
cdouble cexp(cdouble z);
-///
cfloat cexpf(cfloat z);
-///
creal cexpl(creal z);
-///
cdouble clog(cdouble z);
-///
cfloat clogf(cfloat z);
-///
creal clogl(creal z);
-///
double cabs(cdouble z);
- ///
float cabsf(cfloat z);
- ///
real cabsl(creal z);
- ///
cdouble cpow(cdouble x, cdouble y);
-///
cfloat cpowf(cfloat x, cfloat y);
-///
creal cpowl(creal x, creal y);
-///
cdouble csqrt(cdouble z);
-///
cfloat csqrtf(cfloat z);
-///
creal csqrtl(creal z);
-///
double carg(cdouble z);
- ///
float cargf(cfloat z);
- ///
real cargl(creal z);
- ///
- double cimag(cdouble z);
- ///
- float cimagf(cfloat z);
- ///
- real cimagl(creal z);
+pragma(inline, true) double cimag(cdouble z) { return z.im; }
+pragma(inline, true) float cimagf(cfloat z) { return z.im; }
+pragma(inline, true) real cimagl(creal z) { return z.im; }
- ///
cdouble conj(cdouble z);
-///
cfloat conjf(cfloat z);
-///
creal conjl(creal z);
-///
cdouble cproj(cdouble z);
-///
cfloat cprojf(cfloat z);
-///
creal cprojl(creal z);
-// double creal(cdouble z);
-///
- float crealf(cfloat z);
- ///
- real creall(creal z);
+// Note: `creal` is a keyword in D and so this function is inaccessible, use `creald` instead
+//pragma(inline, true) double creal(cdouble z) { return z.re; }
+
+pragma(inline, true) double creald(cdouble z) { return z.re; }
+pragma(inline, true) float crealf(cfloat z) { return z.re; }
+pragma(inline, true) real creall(creal z) { return z.re; }
diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d
index cdb987f..44bb707 100644
--- a/libphobos/libdruntime/core/stdc/config.d
+++ b/libphobos/libdruntime/core/stdc/config.d
@@ -34,6 +34,7 @@ version (StdDdoc)
alias ddoc_long = int;
alias ddoc_ulong = uint;
}
+ struct ddoc_complex(T) { T re; T im; };
}
/***
@@ -89,6 +90,24 @@ version (StdDdoc)
* C++ compiler's `ptrdiff_t` type.
*/
alias cpp_ptrdiff_t = ptrdiff_t;
+
+ /***
+ * Used for a complex floating point type that corresponds in size and ABI to the associated
+ * C compiler's `_Complex float` type.
+ */
+ alias c_complex_float = ddoc_complex!float;
+
+ /***
+ * Used for a complex floating point type that corresponds in size and ABI to the associated
+ * C compiler's `_Complex double` type.
+ */
+ alias c_complex_double = ddoc_complex!double;
+
+ /***
+ * Used for a complex floating point type that corresponds in size and ABI to the associated
+ * C compiler's `_Complex long double` type.
+ */
+ alias c_complex_real = ddoc_complex!real;
}
else
{
@@ -167,7 +186,18 @@ else version (Posix)
}
}
-version (CRuntime_Microsoft)
+version (GNU)
+ alias c_long_double = real;
+else version (LDC)
+ alias c_long_double = real; // 64-bit real for MSVC targets
+else version (SDC)
+{
+ version (X86)
+ alias c_long_double = real;
+ else version (X86_64)
+ alias c_long_double = real;
+}
+else version (CRuntime_Microsoft)
{
/* long double is 64 bits, not 80 bits, but is mangled differently
* than double. To distinguish double from long double, create a wrapper to represent
@@ -203,17 +233,6 @@ else version (DigitalMars)
alias real c_long_double;
}
}
-else version (GNU)
- alias real c_long_double;
-else version (LDC)
- alias real c_long_double;
-else version (SDC)
-{
- version (X86)
- alias real c_long_double;
- else version (X86_64)
- alias real c_long_double;
-}
static assert(is(c_long_double), "c_long_double needs to be declared for this platform/architecture.");
@@ -230,4 +249,19 @@ else
alias cpp_size_t = size_t;
alias cpp_ptrdiff_t = ptrdiff_t;
}
+
+// ABI layout of native complex types.
+private struct _Complex(T)
+{
+ T re;
+ T im;
+}
+
+enum __c_complex_float : _Complex!float;
+enum __c_complex_double : _Complex!double;
+enum __c_complex_real : _Complex!c_long_double;
+
+alias c_complex_float = __c_complex_float;
+alias c_complex_double = __c_complex_double;
+alias c_complex_real = __c_complex_real;
}
diff --git a/libphobos/libdruntime/core/stdc/errno.d b/libphobos/libdruntime/core/stdc/errno.d
index 767ed24..57bc15d 100644
--- a/libphobos/libdruntime/core/stdc/errno.d
+++ b/libphobos/libdruntime/core/stdc/errno.d
@@ -156,15 +156,9 @@ else version (Haiku)
else
{
///
- @property int errno() { return getErrno(); }
+ extern(C) pragma(mangle, "getErrno") @property int errno();
///
- @property int errno(int n) { return setErrno(n); }
-
- extern (C)
- {
- private int getErrno(); // for internal use
- private int setErrno(int); // for internal use
- }
+ extern(C) pragma(mangle, "setErrno") @property int errno(int n);
}
extern (C):
@@ -1532,7 +1526,11 @@ else version (OpenBSD)
enum EIDRM = 89; /// Identifier removed
enum ENOMSG = 90; /// No message of desired type
enum ENOTSUP = 91; /// Not supported
- enum ELAST = 91; /// Must be equal largest errno
+ enum EBADMSG = 92; /// Bad message
+ enum ENOTRECOVERABLE = 93; /// State not recoverable
+ enum EOWNERDEAD = 94; /// Previous owner died
+ enum EPROTO = 95; /// Protocol error
+ enum ELAST = 95; /// Must be equal largest errno
}
else version (DragonFlyBSD)
{
@@ -1639,128 +1637,128 @@ else version (DragonFlyBSD)
}
else version (Solaris)
{
- enum EPERM = 1 /** Not super-user */;
- enum ENOENT = 2 /** No such file or directory */;
- enum ESRCH = 3 /** No such process */;
- enum EINTR = 4 /** interrupted system call */;
- enum EIO = 5 /** I/O error */;
- enum ENXIO = 6 /** No such device or address */;
- enum E2BIG = 7 /** Arg list too long */;
- enum ENOEXEC = 8 /** Exec format error */;
- enum EBADF = 9 /** Bad file number */;
- enum ECHILD = 10 /** No children */;
- enum EAGAIN = 11 /** Resource temporarily unavailable */;
- enum ENOMEM = 12 /** Not enough core */;
- enum EACCES = 13 /** Permission denied */;
- enum EFAULT = 14 /** Bad address */;
- enum ENOTBLK = 15 /** Block device required */;
- enum EBUSY = 16 /** Mount device busy */;
- enum EEXIST = 17 /** File exists */;
- enum EXDEV = 18 /** Cross-device link */;
- enum ENODEV = 19 /** No such device */;
- enum ENOTDIR = 20 /** Not a directory */;
- enum EISDIR = 21 /** Is a directory */;
- enum EINVAL = 22 /** Invalid argument */;
- enum ENFILE = 23 /** File table overflow */;
- enum EMFILE = 24 /** Too many open files */;
- enum ENOTTY = 25 /** Inappropriate ioctl for device */;
- enum ETXTBSY = 26 /** Text file busy */;
- enum EFBIG = 27 /** File too large */;
- enum ENOSPC = 28 /** No space left on device */;
- enum ESPIPE = 29 /** Illegal seek */;
- enum EROFS = 30 /** Read only file system */;
- enum EMLINK = 31 /** Too many links */;
- enum EPIPE = 32 /** Broken pipe */;
- enum EDOM = 33 /** Math arg out of domain of func */;
- enum ERANGE = 34 /** Math result not representable */;
- enum ENOMSG = 35 /** No message of desired type */;
- enum EIDRM = 36 /** Identifier removed */;
- enum ECHRNG = 37 /** Channel number out of range */;
- enum EL2NSYNC = 38 /** Level 2 not synchronized */;
- enum EL3HLT = 39 /** Level 3 halted */;
- enum EL3RST = 40 /** Level 3 reset */;
- enum ELNRNG = 41 /** Link number out of range */;
- enum EUNATCH = 42 /** Protocol driver not attached */;
- enum ENOCSI = 43 /** No CSI structure available */;
- enum EL2HLT = 44 /** Level 2 halted */;
- enum EDEADLK = 45 /** Deadlock condition. */;
- enum ENOLCK = 46 /** No record locks available. */;
- enum ECANCELED = 47 /** Operation canceled */;
- enum ENOTSUP = 48 /** Operation not supported */;
- enum EDQUOT = 49 /** Disc quota exceeded */;
- enum EBADE = 50 /** invalid exchange */;
- enum EBADR = 51 /** invalid request descriptor */;
- enum EXFULL = 52 /** exchange full */;
- enum ENOANO = 53 /** no anode */;
- enum EBADRQC = 54 /** invalid request code */;
- enum EBADSLT = 55 /** invalid slot */;
- enum EDEADLOCK = 56 /** file locking deadlock error */;
- enum EBFONT = 57 /** bad font file fmt */;
- enum EOWNERDEAD = 58 /** process died with the lock */;
- enum ENOTRECOVERABLE = 59 /** lock is not recoverable */;
- enum ENOSTR = 60 /** Device not a stream */;
- enum ENODATA = 61 /** no data (for no delay io) */;
- enum ETIME = 62 /** timer expired */;
- enum ENOSR = 63 /** out of streams resources */;
- enum ENONET = 64 /** Machine is not on the network */;
- enum ENOPKG = 65 /** Package not installed */;
- enum EREMOTE = 66 /** The object is remote */;
- enum ENOLINK = 67 /** the link has been severed */;
- enum EADV = 68 /** advertise error */;
- enum ESRMNT = 69 /** srmount error */;
- enum ECOMM = 70 /** Communication error on send */;
- enum EPROTO = 71 /** Protocol error */;
- enum ELOCKUNMAPPED = 72 /** locked lock was unmapped */;
- enum ENOTACTIVE = 73 /** Facility is not active */;
- enum EMULTIHOP = 74 /** multihop attempted */;
- enum EBADMSG = 77 /** trying to read unreadable message */;
- enum ENAMETOOLONG = 78 /** path name is too long */;
- enum EOVERFLOW = 79 /** value too large to be stored in data type */;
- enum ENOTUNIQ = 80 /** given log. name not unique */;
- enum EBADFD = 81 /** f.d. invalid for this operation */;
- enum EREMCHG = 82 /** Remote address changed */;
- enum ELIBACC = 83 /** Can't access a needed shared lib. */;
- enum ELIBBAD = 84 /** Accessing a corrupted shared lib. */;
- enum ELIBSCN = 85 /** .lib section in a.out corrupted. */;
- enum ELIBMAX = 86 /** Attempting to link in too many libs. */;
- enum ELIBEXEC = 87 /** Attempting to exec a shared library. */;
- enum EILSEQ = 88 /** Illegal byte sequence. */;
- enum ENOSYS = 89 /** Unsupported file system operation */;
- enum ELOOP = 90 /** Symbolic link loop */;
- enum ERESTART = 91 /** Restartable system call */;
- enum ESTRPIPE = 92 /** if pipe/FIFO, don't sleep in stream head */;
- enum ENOTEMPTY = 93 /** directory not empty */;
- enum EUSERS = 94 /** Too many users (for UFS) */;
- enum ENOTSOCK = 95 /** Socket operation on non-socket */;
- enum EDESTADDRREQ = 96 /** Destination address required */;
- enum EMSGSIZE = 97 /** Message too long */;
- enum EPROTOTYPE = 98 /** Protocol wrong type for socket */;
- enum ENOPROTOOPT = 99 /** Protocol not available */;
- enum EPROTONOSUPPORT = 120 /** Protocol not supported */;
- enum ESOCKTNOSUPPORT = 121 /** Socket type not supported */;
- enum EOPNOTSUPP = 122 /** Operation not supported on socket */;
- enum EPFNOSUPPORT = 123 /** Protocol family not supported */;
- enum EAFNOSUPPORT = 124 /** Address family not supported by the protocol family */;
- enum EADDRINUSE = 125 /** Address already in use */;
- enum EADDRNOTAVAIL = 126 /** Can't assign requested address */;
- enum ENETDOWN = 127 /** Network is down */;
- enum ENETUNREACH = 128 /** Network is unreachable */;
- enum ENETRESET = 129 /** Network dropped connection because of reset */;
- enum ECONNABORTED = 130 /** Software caused connection abort */;
- enum ECONNRESET = 131 /** Connection reset by peer */;
- enum ENOBUFS = 132 /** No buffer space available */;
- enum EISCONN = 133 /** Socket is already connected */;
- enum ENOTCONN = 134 /** Socket is not connected */;
- enum ESHUTDOWN = 143 /** Can't send after socket shutdown */;
- enum ETOOMANYREFS = 144 /** Too many references: can't splice */;
- enum ETIMEDOUT = 145 /** Connection timed out */;
- enum ECONNREFUSED = 146 /** Connection refused */;
- enum EHOSTDOWN = 147 /** Host is down */;
- enum EHOSTUNREACH = 148 /** No route to host */;
- enum EWOULDBLOCK = EAGAIN; /** Resource temporarily unavailable */;
- enum EALREADY = 149 /** operation already in progress */;
- enum EINPROGRESS = 150 /** operation now in progress */;
- enum ESTALE = 151 /** Stale NFS file handle */;
+ enum EPERM = 1; /// Not super-user
+ enum ENOENT = 2; /// No such file or directory
+ enum ESRCH = 3; /// No such process
+ enum EINTR = 4; /// interrupted system call
+ enum EIO = 5; /// I/O error
+ enum ENXIO = 6; /// No such device or address
+ enum E2BIG = 7; /// Arg list too long
+ enum ENOEXEC = 8; /// Exec format error
+ enum EBADF = 9; /// Bad file number
+ enum ECHILD = 10; /// No children
+ enum EAGAIN = 11; /// Resource temporarily unavailable
+ enum ENOMEM = 12; /// Not enough core
+ enum EACCES = 13; /// Permission denied
+ enum EFAULT = 14; /// Bad address
+ enum ENOTBLK = 15; /// Block device required
+ enum EBUSY = 16; /// Mount device busy
+ enum EEXIST = 17; /// File exists
+ enum EXDEV = 18; /// Cross-device link
+ enum ENODEV = 19; /// No such device
+ enum ENOTDIR = 20; /// Not a directory
+ enum EISDIR = 21; /// Is a directory
+ enum EINVAL = 22; /// Invalid argument
+ enum ENFILE = 23; /// File table overflow
+ enum EMFILE = 24; /// Too many open files
+ enum ENOTTY = 25; /// Inappropriate ioctl for device
+ enum ETXTBSY = 26; /// Text file busy
+ enum EFBIG = 27; /// File too large
+ enum ENOSPC = 28; /// No space left on device
+ enum ESPIPE = 29; /// Illegal seek
+ enum EROFS = 30; /// Read only file system
+ enum EMLINK = 31; /// Too many links
+ enum EPIPE = 32; /// Broken pipe
+ enum EDOM = 33; /// Math arg out of domain of func
+ enum ERANGE = 34; /// Math result not representable
+ enum ENOMSG = 35; /// No message of desired type
+ enum EIDRM = 36; /// Identifier removed
+ enum ECHRNG = 37; /// Channel number out of range
+ enum EL2NSYNC = 38; /// Level 2 not synchronized
+ enum EL3HLT = 39; /// Level 3 halted
+ enum EL3RST = 40; /// Level 3 reset
+ enum ELNRNG = 41; /// Link number out of range
+ enum EUNATCH = 42; /// Protocol driver not attached
+ enum ENOCSI = 43; /// No CSI structure available
+ enum EL2HLT = 44; /// Level 2 halted
+ enum EDEADLK = 45; /// Deadlock condition.
+ enum ENOLCK = 46; /// No record locks available.
+ enum ECANCELED = 47; /// Operation canceled
+ enum ENOTSUP = 48; /// Operation not supported
+ enum EDQUOT = 49; /// Disc quota exceeded
+ enum EBADE = 50; /// invalid exchange
+ enum EBADR = 51; /// invalid request descriptor
+ enum EXFULL = 52; /// exchange full
+ enum ENOANO = 53; /// no anode
+ enum EBADRQC = 54; /// invalid request code
+ enum EBADSLT = 55; /// invalid slot
+ enum EDEADLOCK = 56; /// file locking deadlock error
+ enum EBFONT = 57; /// bad font file fmt
+ enum EOWNERDEAD = 58; /// process died with the lock
+ enum ENOTRECOVERABLE = 59; /// lock is not recoverable
+ enum ENOSTR = 60; /// Device not a stream
+ enum ENODATA = 61; /// no data (for no delay io)
+ enum ETIME = 62; /// timer expired
+ enum ENOSR = 63; /// out of streams resources
+ enum ENONET = 64; /// Machine is not on the network
+ enum ENOPKG = 65; /// Package not installed
+ enum EREMOTE = 66; /// The object is remote
+ enum ENOLINK = 67; /// the link has been severed
+ enum EADV = 68; /// advertise error
+ enum ESRMNT = 69; /// srmount error
+ enum ECOMM = 70; /// Communication error on send
+ enum EPROTO = 71; /// Protocol error
+ enum ELOCKUNMAPPED = 72; /// locked lock was unmapped
+ enum ENOTACTIVE = 73; /// Facility is not active
+ enum EMULTIHOP = 74; /// multihop attempted
+ enum EBADMSG = 77; /// trying to read unreadable message
+ enum ENAMETOOLONG = 78; /// path name is too long
+ enum EOVERFLOW = 79; /// value too large to be stored in data type
+ enum ENOTUNIQ = 80; /// given log. name not unique
+ enum EBADFD = 81; /// f.d. invalid for this operation
+ enum EREMCHG = 82; /// Remote address changed
+ enum ELIBACC = 83; /// Can't access a needed shared lib.
+ enum ELIBBAD = 84; /// Accessing a corrupted shared lib.
+ enum ELIBSCN = 85; /// .lib section in a.out corrupted.
+ enum ELIBMAX = 86; /// Attempting to link in too many libs.
+ enum ELIBEXEC = 87; /// Attempting to exec a shared library.
+ enum EILSEQ = 88; /// Illegal byte sequence.
+ enum ENOSYS = 89; /// Unsupported file system operation
+ enum ELOOP = 90; /// Symbolic link loop
+ enum ERESTART = 91; /// Restartable system call
+ enum ESTRPIPE = 92; /// if pipe/FIFO, don't sleep in stream head
+ enum ENOTEMPTY = 93; /// directory not empty
+ enum EUSERS = 94; /// Too many users (for UFS)
+ enum ENOTSOCK = 95; /// Socket operation on non-socket
+ enum EDESTADDRREQ = 96; /// Destination address required
+ enum EMSGSIZE = 97; /// Message too long
+ enum EPROTOTYPE = 98; /// Protocol wrong type for socket
+ enum ENOPROTOOPT = 99; /// Protocol not available
+ enum EPROTONOSUPPORT = 120; /// Protocol not supported
+ enum ESOCKTNOSUPPORT = 121; /// Socket type not supported
+ enum EOPNOTSUPP = 122; /// Operation not supported on socket
+ enum EPFNOSUPPORT = 123; /// Protocol family not supported
+ enum EAFNOSUPPORT = 124; /// Address family not supported by the protocol family
+ enum EADDRINUSE = 125; /// Address already in use
+ enum EADDRNOTAVAIL = 126; /// Can't assign requested address
+ enum ENETDOWN = 127; /// Network is down
+ enum ENETUNREACH = 128; /// Network is unreachable
+ enum ENETRESET = 129; /// Network dropped connection because of reset
+ enum ECONNABORTED = 130; /// Software caused connection abort
+ enum ECONNRESET = 131; /// Connection reset by peer
+ enum ENOBUFS = 132; /// No buffer space available
+ enum EISCONN = 133; /// Socket is already connected
+ enum ENOTCONN = 134; /// Socket is not connected
+ enum ESHUTDOWN = 143; /// Can't send after socket shutdown
+ enum ETOOMANYREFS = 144; /// Too many references: can't splice
+ enum ETIMEDOUT = 145; /// Connection timed out
+ enum ECONNREFUSED = 146; /// Connection refused
+ enum EHOSTDOWN = 147; /// Host is down
+ enum EHOSTUNREACH = 148; /// No route to host
+ enum EWOULDBLOCK = EAGAIN; /// Resource temporarily unavailable
+ enum EALREADY = 149; /// operation already in progress
+ enum EINPROGRESS = 150; /// operation now in progress
+ enum ESTALE = 151; /// Stale NFS file handle
}
else version (Haiku)
{
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
index e5d2519..3002c02 100644
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -149,10 +149,10 @@ version (GNUFP)
alias fexcept_t = uint;
}
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h
- else version (SPARC64)
+ else version (SPARC_Any)
{
- alias fenv_t = ulong;
- alias fexcept_t = ulong;
+ alias fenv_t = c_ulong;
+ alias fexcept_t = c_ulong;
}
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h
else version (IBMZ_Any)
@@ -237,7 +237,7 @@ else version (NetBSD)
uint status; /* Status word register */
uint tag; /* Tag word register */
uint[4] others; /* EIP, Pointer Selector, etc */
- };
+ }
_x87 x87;
uint mxcsr; /* Control and status register */
@@ -256,10 +256,10 @@ else version (NetBSD)
ushort tag; /* Tag word register */
ushort unused3;
uint[4] others; /* EIP, Pointer Selector, etc */
- };
+ }
_x87 x87;
uint mxcsr; /* Control and status register */
- };
+ }
}
@@ -291,7 +291,7 @@ else version (DragonFlyBSD)
uint status;
uint tag;
uint[4] others;
- };
+ }
_x87 x87;
uint mxcsr;
@@ -877,7 +877,7 @@ int feholdexcept(fenv_t* envp);
///
int fegetexceptflag(fexcept_t* flagp, int excepts);
///
-int fesetexceptflag(in fexcept_t* flagp, int excepts);
+int fesetexceptflag(const scope fexcept_t* flagp, int excepts);
///
int fegetround();
@@ -887,7 +887,7 @@ int fesetround(int round);
///
int fegetenv(fenv_t* envp);
///
-int fesetenv(in fenv_t* envp);
+int fesetenv(const scope fenv_t* envp);
// MS define feraiseexcept() and feupdateenv() inline.
version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only
@@ -925,7 +925,7 @@ version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only
}
///
- int feupdateenv()(in fenv_t* envp)
+ int feupdateenv()(const scope fenv_t* envp)
{
int excepts = fetestexcept(FE_ALL_EXCEPT);
return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0);
@@ -936,5 +936,5 @@ else
///
int feraiseexcept(int excepts);
///
- int feupdateenv(in fenv_t* envp);
+ int feupdateenv(const scope fenv_t* envp);
}
diff --git a/libphobos/libdruntime/core/stdc/inttypes.d b/libphobos/libdruntime/core/stdc/inttypes.d
index d74ee79..7f30e38 100644
--- a/libphobos/libdruntime/core/stdc/inttypes.d
+++ b/libphobos/libdruntime/core/stdc/inttypes.d
@@ -434,10 +434,10 @@ intmax_t imaxabs(intmax_t j);
///
imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);
///
-intmax_t strtoimax(in char* nptr, char** endptr, int base);
+intmax_t strtoimax(const scope char* nptr, char** endptr, int base);
///
-uintmax_t strtoumax(in char* nptr, char** endptr, int base);
+uintmax_t strtoumax(const scope char* nptr, char** endptr, int base);
///
-intmax_t wcstoimax(in wchar_t* nptr, wchar_t** endptr, int base);
+intmax_t wcstoimax(const scope wchar_t* nptr, wchar_t** endptr, int base);
///
-uintmax_t wcstoumax(in wchar_t* nptr, wchar_t** endptr, int base);
+uintmax_t wcstoumax(const scope wchar_t* nptr, wchar_t** endptr, int base);
diff --git a/libphobos/libdruntime/core/stdc/limits.d b/libphobos/libdruntime/core/stdc/limits.d
index 3ab7ed1..f3f8800 100644
--- a/libphobos/libdruntime/core/stdc/limits.d
+++ b/libphobos/libdruntime/core/stdc/limits.d
@@ -23,7 +23,7 @@ else version (TVOS)
else version (WatchOS)
version = Darwin;
-private import core.stdc.config;
+import core.stdc.config;
extern (C):
@trusted: // Constants only.
diff --git a/libphobos/libdruntime/core/stdc/locale.d b/libphobos/libdruntime/core/stdc/locale.d
index 3ba348ad..4b8d5c8 100644
--- a/libphobos/libdruntime/core/stdc/locale.d
+++ b/libphobos/libdruntime/core/stdc/locale.d
@@ -287,6 +287,6 @@ else
}
///
-@system char* setlocale(int category, in char* locale);
+@system char* setlocale(int category, const scope char* locale);
///
lconv* localeconv();
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 4929789..2de6e57 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -13,7 +13,7 @@
module core.stdc.math;
-private import core.stdc.config;
+import core.stdc.config;
version (OSX)
version = Darwin;
@@ -319,16 +319,12 @@ version (CRuntime_DigitalMars)
{
//int fpclassify(real-floating x);
///
- pure int fpclassify(float x) { return __fpclassify_f(x); }
+ extern(C) pragma(mangle, "__fpclassify_f") pure int fpclassify(float x);
///
- pure int fpclassify(double x) { return __fpclassify_d(x); }
+ extern(C) pragma(mangle, "__fpclassify_d") pure int fpclassify(double x);
///
- pure int fpclassify(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __fpclassify_d(x)
- : __fpclassify_ld(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify_d" : "__fpclassify_ld")
+ pure int fpclassify(real x);
//int isfinite(real-floating x);
///
@@ -428,98 +424,177 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o
pure int _fpclass(double x);
}
+ version (MinGW)
+ {
enum
{
///
- FP_SUBNORMAL = -2,
+ FP_NAN = 0x0100,
///
- FP_NORMAL = -1,
+ FP_NORMAL = 0x0400,
///
- FP_ZERO = 0,
+ FP_INFINITE = FP_NAN | FP_NORMAL,
///
- FP_INFINITE = 1,
+ FP_ZERO = 0x0400,
///
- FP_NAN = 2,
+ FP_SUBNORMAL = FP_NORMAL | FP_ZERO
}
- pure private short _fdclass(float x);
- pure private short _dclass(double x);
+ pure int __fpclassifyf(float x);
+ pure int __fpclassify(double x);
+ pure int __fpclassifyl(real x);
- pure private int _fdsign(float x);
- pure private int _dsign(double x);
+ pure int __isnanf(float x);
+ pure int __isnan(double x);
+ pure int __isnanl(real x);
- extern(D)
- {
- //int fpclassify(real-floating x);
- ///
- pure int fpclassify()(float x) { return _fdclass(x); }
- ///
- pure int fpclassify()(double x) { return _dclass(x); }
- ///
- pure int fpclassify()(real x)
+ pure int __signbitf(float x);
+ pure int __signbit(double x);
+ pure int __signbitl(real x);
+
+ extern (D)
{
- static if (real.sizeof == double.sizeof)
- return _dclass(cast(double) x);
- else
- static assert(false, "fpclassify(real) not supported by MS C runtime");
- }
+ //int fpclassify(real-floating x);
+ ///
+ extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
+ ///
+ extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x);
+ ///
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
+ pure int fpclassify(real x);
- //int isfinite(real-floating x);
- ///
- pure int isfinite()(float x) { return fpclassify(x) <= 0; }
- ///
- pure int isfinite()(double x) { return fpclassify(x) <= 0; }
- ///
- pure int isfinite()(real x) { return fpclassify(x) <= 0; }
+ //int isfinite(real-floating x);
+ ///
+ pure int isfinite(float x) { return (fpclassify(x) & FP_NORMAL) == 0; }
+ ///
+ pure int isfinite(double x) { return (fpclassify(x) & FP_NORMAL) == 0; }
+ ///
+ pure int isfinite(real x) { return (fpclassify(x) & FP_NORMAL) == 0; }
- //int isinf(real-floating x);
- ///
- pure int isinf()(float x) { return fpclassify(x) == FP_INFINITE; }
- ///
- pure int isinf()(double x) { return fpclassify(x) == FP_INFINITE; }
- ///
- pure int isinf()(real x) { return fpclassify(x) == FP_INFINITE; }
+ //int isinf(real-floating x);
+ ///
+ pure int isinf(float x) { return fpclassify(x) == FP_INFINITE; }
+ ///
+ pure int isinf(double x) { return fpclassify(x) == FP_INFINITE; }
+ ///
+ pure int isinf(real x) { return fpclassify(x) == FP_INFINITE; }
- //int isnan(real-floating x);
- version (none) // requires MSVCRT 12+ (VS 2013)
- {
+ //int isnan(real-floating x);
+ ///
+ extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
+ ///
+ extern(C) pragma(mangle, "__isnan") pure int isnan(double x);
+ ///
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
+ pure int isnan(real x);
+
+ //int isnormal(real-floating x);
+ ///
+ int isnormal(float x) { return fpclassify(x) == FP_NORMAL; }
+ ///
+ int isnormal(double x) { return fpclassify(x) == FP_NORMAL; }
+ ///
+ int isnormal(real x) { return fpclassify(x) == FP_NORMAL; }
+
+ //int signbit(real-floating x);
///
- pure int isnan(float x) { return fpclassify(x) == FP_NAN; }
+ extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
///
- pure int isnan(double x) { return fpclassify(x) == FP_NAN; }
+ extern(C) pragma(mangle, "__signbit") pure int signbit(double x);
///
- pure int isnan(real x) { return fpclassify(x) == FP_NAN; }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
+ int signbit(real x);
}
- else // for backward compatibility with older runtimes
+ }
+ else
+ {
+ enum
{
///
- pure int isnan(float x) { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
+ FP_SUBNORMAL = -2,
+ ///
+ FP_NORMAL = -1,
+ ///
+ FP_ZERO = 0,
///
- pure int isnan(double x) { return _isnan(x); }
+ FP_INFINITE = 1,
///
- pure int isnan(real x) { return _isnan(cast(double) x); }
+ FP_NAN = 2,
}
- //int isnormal(real-floating x);
- ///
- pure int isnormal()(float x) { return fpclassify(x) == FP_NORMAL; }
- ///
- pure int isnormal()(double x) { return fpclassify(x) == FP_NORMAL; }
- ///
- pure int isnormal()(real x) { return fpclassify(x) == FP_NORMAL; }
-
- //int signbit(real-floating x);
- ///
- pure int signbit()(float x) { return _fdsign(x); }
- ///
- pure int signbit()(double x) { return _dsign(x); }
- ///
- pure int signbit()(real x)
+ extern(D)
{
- static if (real.sizeof == double.sizeof)
- return _dsign(cast(double) x);
- else
- return (cast(short*)&(x))[4] & 0x8000;
+ //int fpclassify(real-floating x);
+ ///
+ extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x);
+ ///
+ extern(C) pragma(mangle, "_dclass") pure int fpclassify(double x);
+ ///
+ pure int fpclassify()(real x)
+ {
+ static if (real.sizeof == double.sizeof)
+ return fpclassify(cast(double) x);
+ else
+ static assert(false, "fpclassify(real) not supported by MS C runtime");
+ }
+
+ //int isfinite(real-floating x);
+ ///
+ pure int isfinite()(float x) { return fpclassify(x) <= 0; }
+ ///
+ pure int isfinite()(double x) { return fpclassify(x) <= 0; }
+ ///
+ pure int isfinite()(real x) { return fpclassify(x) <= 0; }
+
+ //int isinf(real-floating x);
+ ///
+ pure int isinf()(float x) { return fpclassify(x) == FP_INFINITE; }
+ ///
+ pure int isinf()(double x) { return fpclassify(x) == FP_INFINITE; }
+ ///
+ pure int isinf()(real x) { return fpclassify(x) == FP_INFINITE; }
+
+ //int isnan(real-floating x);
+ version (none) // requires MSVCRT 12+ (VS 2013)
+ {
+ ///
+ pure int isnan(float x) { return fpclassify(x) == FP_NAN; }
+ ///
+ pure int isnan(double x) { return fpclassify(x) == FP_NAN; }
+ ///
+ pure int isnan(real x) { return fpclassify(x) == FP_NAN; }
+ }
+ else // for backward compatibility with older runtimes
+ {
+ ///
+ pure int isnan(float x) { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
+ ///
+ extern(C) pragma(mangle, "_isnan") pure int isnan(double x);
+ ///
+ pure int isnan(real x) { return _isnan(cast(double) x); }
+ }
+
+ //int isnormal(real-floating x);
+ ///
+ pure int isnormal()(float x) { return fpclassify(x) == FP_NORMAL; }
+ ///
+ pure int isnormal()(double x) { return fpclassify(x) == FP_NORMAL; }
+ ///
+ pure int isnormal()(real x) { return fpclassify(x) == FP_NORMAL; }
+
+ //int signbit(real-floating x);
+ ///
+ extern(C) pragma(mangle, "_fdsign") pure int signbit(float x);
+ ///
+ extern(C) pragma(mangle, "_dsign") pure int signbit(double x);
+ ///
+ pure int signbit()(real x)
+ {
+ static if (real.sizeof == double.sizeof)
+ return signbit(cast(double) x);
+ else
+ return (cast(short*)&(x))[4] & 0x8000;
+ }
}
}
}
@@ -573,55 +648,39 @@ else version (CRuntime_Glibc)
{
//int fpclassify(real-floating x);
///
- pure int fpclassify(float x) { return __fpclassifyf(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
///
- pure int fpclassify(double x) { return __fpclassify(x); }
+ extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x);
///
- pure int fpclassify(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __fpclassify(x)
- : __fpclassifyl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
+ pure int fpclassify(real x);
//int isfinite(real-floating x);
///
- pure int isfinite(float x) { return __finitef(x); }
+ extern(C) pragma(mangle, "__finitef") pure int isfinite(float x);
///
- pure int isfinite(double x) { return __finite(x); }
+ extern(C) pragma(mangle, "__finite") pure int isfinite(double x);
///
- pure int isfinite(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __finite(x)
- : __finitel(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__finite" : "__finitel")
+ pure int isfinite(real x);
//int isinf(real-floating x);
///
- pure int isinf(float x) { return __isinff(x); }
+ extern(C) pragma(mangle, "__isinff") pure int isinf(float x);
///
- pure int isinf(double x) { return __isinf(x); }
+ extern(C) pragma(mangle, "__isinf") pure int isinf(double x);
///
- pure int isinf(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __isinf(x)
- : __isinfl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isinf" : "__isinfl")
+ pure int isinf(real x);
//int isnan(real-floating x);
///
- pure int isnan(float x) { return __isnanf(x); }
+ extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
///
- pure int isnan(double x) { return __isnan(x); }
+ extern(C) pragma(mangle, "__isnan") pure int isnan(double x);
///
- pure int isnan(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __isnan(x)
- : __isnanl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
+ pure int isnan(real x);
//int isnormal(real-floating x);
///
@@ -633,16 +692,12 @@ else version (CRuntime_Glibc)
//int signbit(real-floating x);
///
- pure int signbit(float x) { return __signbitf(x); }
+ extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
///
- pure int signbit(double x) { return __signbit(x); }
+ extern(C) pragma(mangle, "__signbit") pure int signbit(double x);
///
- pure int signbit(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __signbit(x)
- : __signbitl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
+ pure int signbit(real x);
}
}
else version (CRuntime_Musl)
@@ -685,16 +740,12 @@ else version (CRuntime_Musl)
{
//int fpclassify(real-floating x);
///
- int fpclassify(float x) { return __fpclassifyf(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") int fpclassify(float x);
///
- int fpclassify(double x) { return __fpclassify(x); }
+ extern(C) pragma(mangle, "__fpclassify") int fpclassify(double x);
///
- int fpclassify(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __fpclassify(x)
- : __fpclassifyl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
+ int fpclassify(real x);
private uint __FLOAT_BITS(float __f)
{
union __u_t {
@@ -765,16 +816,12 @@ else version (CRuntime_Musl)
//int signbit(real-floating x);
///
- int signbit(float x) { return __signbitf(x); }
+ extern(C) pragma(mangle, "__signbitf") int signbit(float x);
///
- int signbit(double x) { return __signbit(x); }
+ extern(C) pragma(mangle, "__signbit") int signbit(double x);
///
- int signbit(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __signbit(x)
- : __signbitl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
+ int signbit(real x);
}
}
else version (CRuntime_UClibc)
@@ -826,146 +873,37 @@ else version (CRuntime_UClibc)
extern (D)
{
///
- int fpclassify(float x) { return __fpclassifyf(x); }
- ///
- int fpclassify(double x) { return __fpclassify(x); }
- ///
- int fpclassify(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __fpclassify(x)
- : __fpclassifyl(x);
- }
-
- ///
- int isfinite(float x) { return __finitef(x); }
- ///
- int isfinite(double x) { return __finite(x); }
- ///
- int isfinite(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __finite(x)
- : __finitel(x);
- }
-
- ///
- int isinf(float x) { return __isinff(x); }
- ///
- int isinf(double x) { return __isinf(x); }
- ///
- int isinf(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __isinf(x)
- : __isinfl(x);
- }
-
- ///
- int isnan(float x) { return __isnanf(x); }
- ///
- int isnan(double x) { return __isnan(x); }
- ///
- int isnan(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __isnan(x)
- : __isnanl(x);
- }
-
- ///
- int isnormal(float x) { return fpclassify(x) == FP_NORMAL; }
- ///
- int isnormal(double x) { return fpclassify(x) == FP_NORMAL; }
- ///
- int isnormal(real x) { return fpclassify(x) == FP_NORMAL; }
-
- ///
- int signbit(float x) { return __signbitf(x); }
- ///
- int signbit(double x) { return __signbit(x); }
- ///
- int signbit(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __signbit(x)
- : __signbitl(x);
- }
- }
-}
-else version (MinGW)
-{
- enum
- {
- ///
- FP_NAN = 0x0100,
- ///
- FP_NORMAL = 0x0400,
- ///
- FP_INFINITE = FP_NAN | FP_NORMAL,
- ///
- FP_ZERO = 0x0400,
- ///
- FP_SUBNORMAL = FP_NORMAL | FP_ZERO
- }
-
- pure int __fpclassifyf(float x);
- pure int __fpclassify(double x);
- pure int __fpclassifyl(real x);
-
- pure int __isnanf(float x);
- pure int __isnan(double x);
- pure int __isnanl(real x);
-
- pure int __signbitf(float x);
- pure int __signbit(double x);
- pure int __signbitl(real x);
-
- extern (D)
- {
- //int fpclassify(real-floating x);
- ///
- pure int fpclassify(float x) { return __fpclassifyf(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") int fpclassify(float x);
///
- pure int fpclassify(double x) { return __fpclassify(x); }
+ extern(C) pragma(mangle, "__fpclassify") int fpclassify(double x);
///
- pure int fpclassify(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __fpclassify(x)
- : __fpclassifyl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
+ int fpclassify(real x);
- //int isfinite(real-floating x);
///
- pure int isfinite(float x) { return (fpclassify(x) & FP_NORMAL) == 0; }
+ extern(C) pragma(mangle, "__finitef") int isfinite(float x);
///
- pure int isfinite(double x) { return (fpclassify(x) & FP_NORMAL) == 0; }
+ extern(C) pragma(mangle, "__finite") int isfinite(double x);
///
- pure int isfinite(real x) { return (fpclassify(x) & FP_NORMAL) == 0; }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__finite" : "__finitel")
+ int isfinite(real x);
- //int isinf(real-floating x);
///
- pure int isinf(float x) { return fpclassify(x) == FP_INFINITE; }
+ extern(C) pragma(mangle, "__isinff") int isinf(float x);
///
- pure int isinf(double x) { return fpclassify(x) == FP_INFINITE; }
+ extern(C) pragma(mangle, "__isinf") int isinf(double x);
///
- pure int isinf(real x) { return fpclassify(x) == FP_INFINITE; }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isinf" : "__isinfl")
+ int isinf(real x);
- //int isnan(real-floating x);
///
- pure int isnan(float x) { return __isnanf(x); }
+ extern(C) pragma(mangle, "__isnanf") int isnan(float x);
///
- pure int isnan(double x) { return __isnan(x); }
+ extern(C) pragma(mangle, "__isnan") int isnan(double x);
///
- pure int isnan(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __isnan(x)
- : __isnanl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
+ int isnan(real x);
- //int isnormal(real-floating x);
///
int isnormal(float x) { return fpclassify(x) == FP_NORMAL; }
///
@@ -973,18 +911,13 @@ else version (MinGW)
///
int isnormal(real x) { return fpclassify(x) == FP_NORMAL; }
- //int signbit(real-floating x);
///
- int signbit(float x) { return __signbitf(x); }
+ extern(C) pragma(mangle, "__signbitf") int signbit(float x);
///
- int signbit(double x) { return __signbit(x); }
+ extern(C) pragma(mangle, "__signbit") int signbit(double x);
///
- int signbit(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __signbit(x)
- : __signbitl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
+ int signbit(real x);
}
}
else version (Darwin)
@@ -1037,14 +970,25 @@ else version (Darwin)
// other Darwins
version (OSX)
{
- pure int __fpclassify(real x);
- pure int __isfinite(real x);
- pure int __isinf(real x);
- pure int __isnan(real x);
- alias __fpclassifyl = __fpclassify;
- alias __isfinitel = __isfinite;
- alias __isinfl = __isinf;
- alias __isnanl = __isnan;
+ version (AArch64)
+ {
+ // Available in macOS ARM
+ pure int __fpclassifyl(real x);
+ pure int __isfinitel(real x);
+ pure int __isinfl(real x);
+ pure int __isnanl(real x);
+ }
+ else
+ {
+ pure int __fpclassify(real x);
+ pure int __isfinite(real x);
+ pure int __isinf(real x);
+ pure int __isnan(real x);
+ alias __fpclassifyl = __fpclassify;
+ alias __isfinitel = __isfinite;
+ alias __isinfl = __isinf;
+ alias __isnanl = __isnan;
+ }
}
else
{
@@ -1059,35 +1003,35 @@ else version (Darwin)
{
//int fpclassify(real-floating x);
///
- pure int fpclassify(float x) { return __fpclassifyf(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
///
- pure int fpclassify(double x) { return __fpclassifyd(x); }
+ extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x);
///
- pure int fpclassify(real x) { return __fpclassifyl(x); }
+ extern(C) pragma(mangle, __fpclassifyl.mangleof) pure int fpclassify(real x);
//int isfinite(real-floating x);
///
- pure int isfinite(float x) { return __isfinitef(x); }
+ extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x);
///
- pure int isfinite(double x) { return __isfinited(x); }
+ extern(C) pragma(mangle, "__isfinited") pure int isfinite(double x);
///
- pure int isfinite(real x) { return __isfinitel(x); }
+ extern(C) pragma(mangle, __isfinitel.mangleof) pure int isfinite(real x);
//int isinf(real-floating x);
///
- pure int isinf(float x) { return __isinff(x); }
+ extern(C) pragma(mangle, "__isinff") pure int isinf(float x);
///
- pure int isinf(double x) { return __isinfd(x); }
+ extern(C) pragma(mangle, "__isinfd") pure int isinf(double x);
///
- pure int isinf(real x) { return __isinfl(x); }
+ extern(C) pragma(mangle, __isinfl.mangleof) pure int isinf(real x);
//int isnan(real-floating x);
///
- pure int isnan(float x) { return __isnanf(x); }
+ extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
///
- pure int isnan(double x) { return __isnand(x); }
+ extern(C) pragma(mangle, "__isnand") pure int isnan(double x);
///
- pure int isnan(real x) { return __isnanl(x); }
+ extern(C) pragma(mangle, __isnanl.mangleof) pure int isnan(real x);
//int isnormal(real-floating x);
///
@@ -1099,11 +1043,11 @@ else version (Darwin)
//int signbit(real-floating x);
///
- pure int signbit(float x) { return __signbitf(x); }
+ extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
///
- pure int signbit(double x) { return __signbitd(x); }
+ extern(C) pragma(mangle, "__signbitd") pure int signbit(double x);
///
- pure int signbit(real x) { return __signbitl(x); }
+ extern(C) pragma(mangle, "__signbitl") pure int signbit(real x);
}
}
else version (FreeBSD)
@@ -1152,27 +1096,27 @@ else version (FreeBSD)
{
//int fpclassify(real-floating x);
///
- pure int fpclassify(float x) { return __fpclassifyf(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
///
- pure int fpclassify(double x) { return __fpclassifyd(x); }
+ extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x);
///
- pure int fpclassify(real x) { return __fpclassifyl(x); }
+ extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x);
//int isfinite(real-floating x);
///
- pure int isfinite(float x) { return __isfinitef(x); }
+ extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x);
///
- pure int isfinite(double x) { return __isfinite(x); }
+ extern(C) pragma(mangle, "__isfinite") pure int isfinite(double x);
///
- pure int isfinite(real x) { return __isfinitel(x); }
+ extern(C) pragma(mangle, "__isfinitel") pure int isfinite(real x);
//int isinf(real-floating x);
///
- pure int isinf(float x) { return __isinff(x); }
+ extern(C) pragma(mangle, "__isinff") pure int isinf(float x);
///
pure int isinf(double x) { return __isinfl(x); }
///
- pure int isinf(real x) { return __isinfl(x); }
+ extern(C) pragma(mangle, "__isinfl") pure int isinf(real x);
//int isnan(real-floating x);
///
@@ -1180,21 +1124,21 @@ else version (FreeBSD)
///
pure int isnan(double x) { return __isnanl(x); }
///
- pure int isnan(real x) { return __isnanl(x); }
+ extern(C) pragma(mangle, "__isnanl") pure int isnan(real x);
//int isnormal(real-floating x);
///
- pure int isnormal(float x) { return __isnormalf(x); }
+ extern(C) pragma(mangle, "__isnormalf") pure int isnormal(float x);
///
- pure int isnormal(double x) { return __isnormal(x); }
+ extern(C) pragma(mangle, "__isnormal") pure int isnormal(double x);
///
- pure int isnormal(real x) { return __isnormall(x); }
+ extern(C) pragma(mangle, "__isnormall") pure int isnormal(real x);
//int signbit(real-floating x);
///
- pure int signbit(float x) { return __signbitf(x); }
+ extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
///
- pure int signbit(double x) { return __signbit(x); }
+ extern(C) pragma(mangle, "__signbit") pure int signbit(double x);
///
pure int signbit(real x) { return __signbit(x); }
}
@@ -1225,7 +1169,7 @@ else version (OpenBSD)
FP_FAST_FMAL = 1,
}
- pure int __fpclassifyd(double);
+ pure int __fpclassify(double);
pure int __fpclassifyf(float);
pure int __fpclassifyl(real);
pure int __isfinitef(float);
@@ -1245,27 +1189,27 @@ else version (OpenBSD)
{
//int fpclassify(real-floating x);
///
- pure int fpclassify(float x) { return __fpclassifyf(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
///
- pure int fpclassify(double x) { return __fpclassifyd(x); }
+ extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x);
///
- pure int fpclassify(real x) { return __fpclassifyl(x); }
+ extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x);
//int isfinite(real-floating x);
///
- pure int isfinite(float x) { return __isfinitef(x); }
+ extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x);
///
- pure int isfinite(double x) { return __isfinite(x); }
+ extern(C) pragma(mangle, "__isfinite") pure int isfinite(double x);
///
- pure int isfinite(real x) { return __isfinitel(x); }
+ extern(C) pragma(mangle, "__isfinitel") pure int isfinite(real x);
//int isinf(real-floating x);
///
- pure int isinf(float x) { return __isinff(x); }
+ extern(C) pragma(mangle, "__isinff") pure int isinf(float x);
///
pure int isinf(double x) { return __isinfl(x); }
///
- pure int isinf(real x) { return __isinfl(x); }
+ extern(C) pragma(mangle, "__isinfl") pure int isinf(real x);
//int isnan(real-floating x);
///
@@ -1273,21 +1217,21 @@ else version (OpenBSD)
///
pure int isnan(double x) { return __isnanl(x); }
///
- pure int isnan(real x) { return __isnanl(x); }
+ extern(C) pragma(mangle, "__isnanl") pure int isnan(real x);
//int isnormal(real-floating x);
///
- pure int isnormal(float x) { return __isnormalf(x); }
+ extern(C) pragma(mangle, "__isnormalf") pure int isnormal(float x);
///
- pure int isnormal(double x) { return __isnormal(x); }
+ extern(C) pragma(mangle, "__isnormal") pure int isnormal(double x);
///
- pure int isnormal(real x) { return __isnormall(x); }
+ extern(C) pragma(mangle, "__isnormall") pure int isnormal(real x);
//int signbit(real-floating x);
///
- pure int signbit(float x) { return __signbitf(x); }
+ extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
///
- pure int signbit(double x) { return __signbit(x); }
+ extern(C) pragma(mangle, "__signbit") pure int signbit(double x);
///
pure int signbit(real x) { return __signbit(x); }
}
@@ -1326,16 +1270,12 @@ else version (NetBSD)
{
//int fpclassify(real-floating x);
///
- pure int fpclassify(float x) { return __fpclassifyf(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
///
- pure int fpclassify(double x) { return __fpclassifyd(x); }
+ extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x);
///
- pure int fpclassify(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __fpclassifyd(x)
- : __fpclassifyl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassifyd" : "__fpclassifyl")
+ pure int fpclassify(real x);
//int isfinite(real-floating x);
///
@@ -1422,29 +1362,29 @@ else version (DragonFlyBSD)
extern (D)
{
- pure int fpclassify(float x) { return __fpclassifyf(x); }
- pure int fpclassify(double x) { return __fpclassifyd(x); }
- pure int fpclassify(real x) { return __fpclassifyl(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
+ extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x);
+ extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x);
- pure int isfinite(float x) { return __isfinitef(x); }
- pure int isfinite(double x) { return __isfinite(x); }
- pure int isfinite(real x) { return __isfinitel(x); }
+ extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x);
+ extern(C) pragma(mangle, "__isfinite") pure int isfinite(double x);
+ extern(C) pragma(mangle, "__isfinitel") pure int isfinite(real x);
- pure int isinf(float x) { return __isinff(x); }
- pure int isinf(double x) { return __isinf(x); }
- pure int isinf(real x) { return __isinfl(x); }
+ extern(C) pragma(mangle, "__isinff") pure int isinf(float x);
+ extern(C) pragma(mangle, "__isinf") pure int isinf(double x);
+ extern(C) pragma(mangle, "__isinfl") pure int isinf(real x);
- pure int isnan(float x) { return __isnanf(x); }
- pure int isnan(double x) { return __isnan(x); }
- pure int isnan(real x) { return __isnanl(x); }
+ extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
+ extern(C) pragma(mangle, "__isnan") pure int isnan(double x);
+ extern(C) pragma(mangle, "__isnanl") pure int isnan(real x);
- pure int isnormal(float x) { return __isnormalf(x); }
- pure int isnormal(double x) { return __isnormal(x); }
- pure int isnormal(real x) { return __isnormall(x); }
+ extern(C) pragma(mangle, "__isnormalf") pure int isnormal(float x);
+ extern(C) pragma(mangle, "__isnormal") pure int isnormal(double x);
+ extern(C) pragma(mangle, "__isnormall") pure int isnormal(real x);
- pure int signbit(float x) { return __signbitf(x); }
- pure int signbit(double x) { return __signbit(x); }
- pure int signbit(real x) { return __signbitl(x); }
+ extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
+ extern(C) pragma(mangle, "__signbit") pure int signbit(double x);
+ extern(C) pragma(mangle, "__signbitl") pure int signbit(real x);
}
}
else version (Solaris)
@@ -1457,16 +1397,12 @@ else version (Solaris)
{
//int isnan(real-floating x);
///
- pure int isnan(float x) { return __isnanf(x); }
+ extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
///
- pure int isnan(double x) { return __isnan(x); }
+ extern(C) pragma(mangle, "__isnan") pure int isnan(double x);
///
- pure int isnan(real x)
- {
- return (real.sizeof == double.sizeof)
- ? __isnan(x)
- : __isnanl(x);
- }
+ extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
+ pure int isnan(real x);
}
}
else version (CRuntime_Bionic)
@@ -1516,49 +1452,49 @@ else version (CRuntime_Bionic)
{
//int fpclassify(real-floating x);
///
- pure int fpclassify(float x) { return __fpclassifyf(x); }
+ extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
///
- pure int fpclassify(double x) { return __fpclassifyd(x); }
+ extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x);
///
- pure int fpclassify(real x) { return __fpclassifyl(x); }
+ extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x);
//int isfinite(real-floating x);
///
- pure int isfinite(float x) { return __isfinitef(x); }
+ extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x);
///
- pure int isfinite(double x) { return __isfinite(x); }
+ extern(C) pragma(mangle, "__isfinite") pure int isfinite(double x);
///
- pure int isfinite(real x) { return __isfinitel(x); }
+ extern(C) pragma(mangle, "__isfinitel") pure int isfinite(real x);
//int isinf(real-floating x);
///
- pure int isinf(float x) { return __isinff(x); }
+ extern(C) pragma(mangle, "__isinff") pure int isinf(float x);
///
- pure int isinf(double x) { return __isinf(x); }
+ extern(C) pragma(mangle, "__isinf") pure int isinf(double x);
///
- pure int isinf(real x) { return __isinfl(x); }
+ extern(C) pragma(mangle, "__isinfl") pure int isinf(real x);
//int isnan(real-floating x);
///
- pure int isnan(float x) { return isnanf(x); }
+ extern(C) pragma(mangle, "isnanf") pure int isnan(float x);
///
- pure int isnan(real x) { return __isnanl(x); }
+ extern(C) pragma(mangle, "__isnanl") pure int isnan(real x);
//int isnormal(real-floating x);
///
- pure int isnormal(float x) { return __isnormalf(x); }
+ extern(C) pragma(mangle, "__isnormalf") pure int isnormal(float x);
///
- pure int isnormal(double x) { return __isnormal(x); }
+ extern(C) pragma(mangle, "__isnormal") pure int isnormal(double x);
///
- pure int isnormal(real x) { return __isnormall(x); }
+ extern(C) pragma(mangle, "__isnormall") pure int isnormal(real x);
//int signbit(real-floating x);
///
- pure int signbit(float x) { return __signbitf(x); }
+ extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
///
- pure int signbit(double x) { return __signbit(x); }
+ extern(C) pragma(mangle, "__signbit") pure int signbit(double x);
///
- pure int signbit(real x) { return __signbitl(x); }
+ extern(C) pragma(mangle, "__signbitl") pure int signbit(real x);
}
}
@@ -1830,14 +1766,12 @@ version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only
///
extern(D) pure real fabsl()(real x) { return fabs(cast(double) x); }
- private double _hypot(double x, double y);
- private float _hypotf(float x, float y);
///
- extern(D) double hypot(double x, double y) { return _hypot(x, y); }
+ extern(C) pragma(mangle, "_hypot") double hypot(double x, double y);
///
- extern(D) float hypotf(float x, float y) { return _hypotf(x, y); }
+ extern(C) pragma(mangle, "_hypotf") float hypotf(float x, float y);
///
- extern(D) real hypotl(real x, real y) { return _hypot(cast(double) x, cast(double) y); }
+ extern(D) real hypotl(real x, real y) { return hypot(cast(double) x, cast(double) y); }
///
double pow(double x, double y);
@@ -2028,464 +1962,406 @@ version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only
///
extern(D) pure real fmal()(real x, real y, real z) { return fma(cast(double) x, cast(double) y, cast(double) z); }
}
-/* NOTE: freebsd < 8-CURRENT doesn't appear to support *l, but we can
- * approximate.
- * A lot of them were added in 8.0-RELEASE, and so a lot of these workarounds
- * should then be removed.
- */
-// NOTE: FreeBSD 8.0-RELEASE doesn't support log2* nor these *l functions:
-// acoshl, asinhl, atanhl, coshl, sinhl, tanhl, cbrtl, powl, expl,
-// expm1l, logl, log1pl, log10l, erfcl, erfl, lgammal, tgammal;
-// but we can approximate.
else version (FreeBSD)
{
- version (none) // < 8-CURRENT
- {
- extern (D)
- {
- real acosl(real x) { return acos(x); }
- real asinl(real x) { return asin(x); }
- pure real atanl(real x) { return atan(x); }
- real atan2l(real y, real x) { return atan2(y, x); }
- pure real cosl(real x) { return cos(x); }
- pure real sinl(real x) { return sin(x); }
- pure real tanl(real x) { return tan(x); }
- real exp2l(real x) { return exp2(x); }
- pure real frexpl(real value, int* exp) { return frexp(value, exp); }
- int ilogbl(real x) { return ilogb(x); }
- real ldexpl(real x, int exp) { return ldexp(x, exp); }
- real logbl(real x) { return logb(x); }
- //real modfl(real value, real *iptr); // nontrivial conversion
- real scalbnl(real x, int n) { return scalbn(x, n); }
- real scalblnl(real x, c_long n) { return scalbln(x, n); }
- pure real fabsl(real x) { return fabs(x); }
- real hypotl(real x, real y) { return hypot(x, y); }
- real sqrtl(real x) { return sqrt(x); }
- pure real ceill(real x) { return ceil(x); }
- pure real floorl(real x) { return floor(x); }
- pure real nearbyintl(real x) { return nearbyint(x); }
- pure real rintl(real x) { return rint(x); }
- c_long lrintl(real x) { return lrint(x); }
- pure real roundl(real x) { return round(x); }
- c_long lroundl(real x) { return lround(x); }
- long llroundl(real x) { return llround(x); }
- pure real truncl(real x) { return trunc(x); }
- real fmodl(real x, real y) { return fmod(x, y); }
- real remainderl(real x, real y) { return remainder(x, y); }
- real remquol(real x, real y, int* quo) { return remquo(x, y, quo); }
- pure real copysignl(real x, real y) { return copysign(x, y); }
- //pure double nan(char* tagp);
- //pure float nanf(char* tagp);
- //pure real nanl(char* tagp);
- real nextafterl(real x, real y) { return nextafter(x, y); }
- real nexttowardl(real x, real y) { return nexttoward(x, y); }
- real fdiml(real x, real y) { return fdim(x, y); }
- pure real fmaxl(real x, real y) { return fmax(x, y); }
- pure real fminl(real x, real y) { return fmin(x, y); }
- pure real fmal(real x, real y, real z) { return fma(x, y, z); }
- }
- }
- else
- {
- ///
- real acosl(real x);
- ///
- real asinl(real x);
- ///
- pure real atanl(real x);
- ///
- real atan2l(real y, real x);
- ///
- pure real cosl(real x);
- ///
- pure real sinl(real x);
- ///
- pure real tanl(real x);
- ///
- real exp2l(real x);
- ///
- pure real frexpl(real value, int* exp);
- ///
- int ilogbl(real x);
- ///
- real ldexpl(real x, int exp);
- ///
- real logbl(real x);
- ///
- pure real modfl(real value, real *iptr);
- ///
- real scalbnl(real x, int n);
- ///
- real scalblnl(real x, c_long n);
///
- pure real fabsl(real x);
- ///
- real hypotl(real x, real y);
- ///
- real sqrtl(real x);
- ///
- pure real ceill(real x);
- ///
- pure real floorl(real x);
- ///
- pure real nearbyintl(real x);
- ///
- pure real rintl(real x);
- ///
- c_long lrintl(real x);
- ///
- pure real roundl(real x);
- ///
- c_long lroundl(real x);
- ///
- long llroundl(real x);
- ///
- pure real truncl(real x);
- ///
- real fmodl(real x, real y);
- ///
- real remainderl(real x, real y);
- ///
- real remquol(real x, real y, int* quo);
- ///
- pure real copysignl(real x, real y);
- ///
- pure double nan(char* tagp);
- ///
- pure float nanf(char* tagp);
- ///
- pure real nanl(char* tagp);
- ///
- real nextafterl(real x, real y);
- ///
- real nexttowardl(real x, real y);
- ///
- real fdiml(real x, real y);
- ///
- pure real fmaxl(real x, real y);
- ///
- pure real fminl(real x, real y);
- ///
- pure real fmal(real x, real y, real z);
- }
- ///
double acos(double x);
///
float acosf(float x);
+ ///
+ real acosl(real x); // since 8.0
///
double asin(double x);
///
float asinf(float x);
+ ///
+ real asinl(real x); // since 8.0
///
pure double atan(double x);
///
pure float atanf(float x);
+ ///
+ pure real atanl(real x); // since 8.0
///
double atan2(double y, double x);
///
float atan2f(float y, float x);
+ ///
+ real atan2l(real y, real x); // since 8.0
///
pure double cos(double x);
///
pure float cosf(float x);
+ ///
+ pure real cosl(real x); // since 8.0
///
pure double sin(double x);
///
pure float sinf(float x);
+ ///
+ pure real sinl(real x); // since 8.0
///
pure double tan(double x);
///
pure float tanf(float x);
+ ///
+ pure real tanl(real x); // since 8.0
///
double acosh(double x);
///
float acoshf(float x);
///
- extern(D) real acoshl(real x) { return acosh(x); }
+ real acoshl(real x); // since 10.0
///
pure double asinh(double x);
///
pure float asinhf(float x);
///
- extern(D) pure real asinhl(real x) { return asinh(x); }
+ pure real asinhl(real x); // since 10.0
///
double atanh(double x);
///
float atanhf(float x);
///
- extern(D) real atanhl(real x) { return atanh(x); }
+ real atanhl(real x); // since 10.0
///
double cosh(double x);
///
float coshf(float x);
///
- extern(D) real coshl(real x) { return cosh(x); }
+ real coshl(real x); // since 10.1
///
double sinh(double x);
///
float sinhf(float x);
///
- extern(D) real sinhl(real x) { return sinh(x); }
+ real sinhl(real x); // since 10.1
///
pure double tanh(double x);
///
pure float tanhf(float x);
///
- extern(D) pure real tanhl(real x) { return tanh(x); }
+ pure real tanhl(real x); // since 10.1
///
double exp(double x);
///
float expf(float x);
///
- extern(D) real expl(real x) { return exp(x); }
+ real expl(real x); // since 10.0
///
double exp2(double x);
///
float exp2f(float x);
+ ///
+ real exp2l(real x); // since 8.0
///
double expm1(double x);
///
float expm1f(float x);
///
- extern(D) real expm1l(real x) { return expm1(x); }
+ real expm1l(real x); // since 10.0
///
pure double frexp(double value, int* exp);
///
pure float frexpf(float value, int* exp);
+ ///
+ pure real frexpl(real value, int* exp); // since 6.0
///
int ilogb(double x);
///
int ilogbf(float x);
+ ///
+ int ilogbl(real x); // since 5.4
///
double ldexp(double x, int exp);
///
float ldexpf(float x, int exp);
+ ///
+ real ldexpl(real x, int exp); // since 6.0
///
double log(double x);
///
float logf(float x);
///
- extern(D) real logl(real x) { return log(x); }
+ real logl(real x); // since 10.0
///
double log10(double x);
///
float log10f(float x);
///
- extern(D) real log10l(real x) { return log10(x); }
+ real log10l(real x); // since 10.0
///
double log1p(double x);
///
float log1pf(float x);
///
- extern(D) real log1pl(real x) { return log1p(x); }
+ real log1pl(real x); // since 10.0
- private enum real ONE_LN2 = 1 / 0x1.62e42fefa39ef358p-1L;
///
- extern(D) double log2(double x) { return log(x) * ONE_LN2; }
+ double log2(double x); // since 8.3
///
- extern(D) float log2f(float x) { return logf(x) * ONE_LN2; }
+ float log2f(float x); // since 8.3
///
- extern(D) real log2l(real x) { return logl(x) * ONE_LN2; }
+ real log2l(real x); // since 10.0
///
double logb(double x);
///
float logbf(float x);
+ ///
+ real logbl(real x); // since 8.0
///
pure double modf(double value, double* iptr);
///
pure float modff(float value, float* iptr);
+ ///
+ pure real modfl(real value, real *iptr); // since 8.0
///
double scalbn(double x, int n);
///
float scalbnf(float x, int n);
+ ///
+ real scalbnl(real x, int n); // since 6.0
///
double scalbln(double x, c_long n);
///
float scalblnf(float x, c_long n);
+ ///
+ real scalblnl(real x, c_long n); // since 6.0
///
pure double cbrt(double x);
///
pure float cbrtf(float x);
///
- extern(D) pure real cbrtl(real x) { return cbrt(x); }
+ pure real cbrtl(real x); // since 9.0
///
pure double fabs(double x);
///
pure float fabsf(float x);
+ ///
+ pure real fabsl(real x); // since 5.3
///
double hypot(double x, double y);
///
float hypotf(float x, float y);
+ ///
+ real hypotl(real x, real y); // since 8.0
///
double pow(double x, double y);
///
float powf(float x, float y);
///
- extern(D) real powl(real x, real y) { return pow(x, y); }
+ real powl(real x, real y); // since 10.4
///
double sqrt(double x);
///
float sqrtf(float x);
+ ///
+ real sqrtl(real x); // since 8.0
///
pure double erf(double x);
///
pure float erff(float x);
///
- extern(D) pure real erfl(real x) { return erf(x); }
+ pure real erfl(real x); // since 10.1
///
double erfc(double x);
///
float erfcf(float x);
///
- extern(D) real erfcl(real x) { return erfc(x); }
+ real erfcl(real x); // since 10.1
///
double lgamma(double x);
///
float lgammaf(float x);
///
- extern(D) real lgammal(real x) { return lgamma(x); }
+ real lgammal(real x); // since 10.2
///
double tgamma(double x);
///
float tgammaf(float x);
///
- extern(D) real tgammal(real x) { return tgamma(x); }
+ real tgammal(real x); // since 11.2
///
pure double ceil(double x);
///
pure float ceilf(float x);
+ ///
+ pure real ceill(real x); // since 5.4
///
pure double floor(double x);
///
pure float floorf(float x);
+ ///
+ pure real floorl(real x); // since 5.4
///
pure double nearbyint(double x);
///
pure float nearbyintf(float x);
+ ///
+ pure real nearbyintl(real x); // since 8.0
///
pure double rint(double x);
///
pure float rintf(float x);
+ ///
+ pure real rintl(real x); // since 8.0
///
c_long lrint(double x);
///
c_long lrintf(float x);
+ ///
+ c_long lrintl(real x); // since 8.0
///
long llrint(double x);
///
long llrintf(float x);
///
- extern(D) long llrintl(real x) { return llrint(x); }
+ long llrintl(real x); // since 8.0
///
pure double round(double x);
///
pure float roundf(float x);
+ ///
+ pure real roundl(real x); // since 6.0
///
c_long lround(double x);
///
c_long lroundf(float x);
+ ///
+ c_long lroundl(real x); // since 6.0
///
long llround(double x);
///
long llroundf(float x);
+ ///
+ long llroundl(real x); // since 6.0
///
pure double trunc(double x);
///
pure float truncf(float x);
+ ///
+ pure real truncl(real x); // since 6.0
///
double fmod(double x, double y);
///
float fmodf(float x, float y);
+ ///
+ real fmodl(real x, real y); // since 8.0
///
double remainder(double x, double y);
///
float remainderf(float x, float y);
+ ///
+ real remainderl(real x, real y); // since 8.0
///
double remquo(double x, double y, int* quo);
///
float remquof(float x, float y, int* quo);
+ ///
+ real remquol(real x, real y, int* quo); // since 8.0
///
pure double copysign(double x, double y);
///
pure float copysignf(float x, float y);
+ ///
+ pure real copysignl(real x, real y); // since 5.3
+
+ ///
+ pure double nan(const char*); // since 8.0
+ ///
+ pure float nanf(const char*); // since 8.0
+ ///
+ pure real nanl(const char*); // since 8.0
///
double nextafter(double x, double y);
///
float nextafterf(float x, float y);
+ ///
+ real nextafterl(real x, real y); // since 6.0
///
double nexttoward(double x, real y);
///
float nexttowardf(float x, real y);
+ ///
+ real nexttowardl(real x, real y); // since 6.0
///
double fdim(double x, double y);
///
float fdimf(float x, float y);
+ ///
+ real fdiml(real x, real y); // since 5.3
///
pure double fmax(double x, double y);
///
pure float fmaxf(float x, float y);
+ ///
+ pure real fmaxl(real x, real y); // since 5.3
///
pure double fmin(double x, double y);
///
pure float fminf(float x, float y);
+ ///
+ pure real fminl(real x, real y); // since 5.3
///
pure double fma(double x, double y, double z);
///
pure float fmaf(float x, float y, float z);
+ ///
+ pure real fmal(real x, real y, real z); // since 6.0
}
else version (NetBSD)
{
diff --git a/libphobos/libdruntime/core/stdc/stdarg.d b/libphobos/libdruntime/core/stdc/stdarg.d
index 586fe20..9a67f2e 100644
--- a/libphobos/libdruntime/core/stdc/stdarg.d
+++ b/libphobos/libdruntime/core/stdc/stdarg.d
@@ -3,525 +3,332 @@
*
* $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdarg.h.html, _stdarg.h)
*
- * Copyright: Copyright Digital Mars 2000 - 2009.
+ * Copyright: Copyright Digital Mars 2000 - 2020.
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Walter Bright, Hauke Duden
* Standards: ISO/IEC 9899:1999 (E)
* Source: $(DRUNTIMESRC core/stdc/_stdarg.d)
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module core.stdc.stdarg;
@system:
-//@nogc: // Not yet, need to make TypeInfo's member functions @nogc first
+@nogc:
nothrow:
+version (X86_64)
+{
+ version (Windows) { /* different ABI */ }
+ else version = SysV_x64;
+}
+
version (GNU)
{
import gcc.builtins;
- alias __builtin_va_list __gnuc_va_list;
-
-
- /*********************
- * The argument pointer type.
- */
- alias __gnuc_va_list va_list;
-
-
- /**********
- * Initialize ap.
- * parmn should be the last named parameter.
- */
- void va_start(T)(out va_list ap, ref T parmn);
-
+}
+else version (SysV_x64)
+{
+ static import core.internal.vararg.sysv_x64;
- /************
- * Retrieve and return the next value that is type T.
- */
- T va_arg(T)(ref va_list ap);
+ version (DigitalMars)
+ {
+ align(16) struct __va_argsave_t
+ {
+ size_t[6] regs; // RDI,RSI,RDX,RCX,R8,R9
+ real[8] fpregs; // XMM0..XMM7
+ __va_list va;
+ }
+ }
+}
+version (ARM) version = ARM_Any;
+version (AArch64) version = ARM_Any;
+version (MIPS32) version = MIPS_Any;
+version (MIPS64) version = MIPS_Any;
+version (PPC) version = PPC_Any;
+version (PPC64) version = PPC_Any;
- /*************
- * Retrieve and store through parmn the next value that is of type T.
- */
- void va_arg(T)(ref va_list ap, ref T parmn);
+version (GNU)
+{
+ // Uses gcc.builtins
+}
+else version (ARM_Any)
+{
+ // Darwin uses a simpler varargs implementation
+ version (OSX) {}
+ else version (iOS) {}
+ else version (TVOS) {}
+ else version (WatchOS) {}
+ else:
+
+ version (ARM)
+ {
+ version = AAPCS32;
+ }
+ else version (AArch64)
+ {
+ version = AAPCS64;
+ static import core.internal.vararg.aarch64;
+ }
+}
- /***********************
- * End use of ap.
- */
- alias __builtin_va_end va_end;
+T alignUp(size_t alignment = size_t.sizeof, T)(T base) pure
+{
+ enum mask = alignment - 1;
+ static assert(alignment > 0 && (alignment & mask) == 0, "alignment must be a power of 2");
+ auto b = cast(size_t) base;
+ b = (b + mask) & ~mask;
+ return cast(T) b;
+}
+unittest
+{
+ assert(1.alignUp == size_t.sizeof);
+ assert(31.alignUp!16 == 32);
+ assert(32.alignUp!16 == 32);
+ assert(33.alignUp!16 == 48);
+ assert((-9).alignUp!8 == -8);
+}
- /***********************
- * Make a copy of ap.
- */
- alias __builtin_va_copy va_copy;
-}
-else version (X86)
+version (BigEndian)
{
- /*********************
- * The argument pointer type.
- */
- alias char* va_list;
-
- /**********
- * Initialize ap.
- * For 32 bit code, parmn should be the last named parameter.
- * For 64 bit code, parmn should be __va_argsave.
- */
- void va_start(T)(out va_list ap, ref T parmn)
+ // Adjusts a size_t-aligned pointer for types smaller than size_t.
+ T* adjustForBigEndian(T)(T* p, size_t size) pure
{
- ap = cast(va_list)( cast(void*) &parmn + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );
+ return size >= size_t.sizeof ? p :
+ cast(T*) ((cast(void*) p) + (size_t.sizeof - size));
}
+}
- /************
- * Retrieve and return the next value that is type T.
- * Should use the other va_arg instead, as this won't work for 64 bit code.
- */
- T va_arg(T)(ref va_list ap)
- {
- T arg = *cast(T*) ap;
- ap = cast(va_list)( cast(void*) ap + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );
- return arg;
- }
- /************
- * Retrieve and return the next value that is type T.
- * This is the preferred version.
- */
- void va_arg(T)(ref va_list ap, ref T parmn)
- {
- parmn = *cast(T*)ap;
- ap = cast(va_list)(cast(void*)ap + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1)));
- }
+/**
+ * The argument pointer type.
+ */
+version (GNU)
+{
+ alias va_list = __gnuc_va_list;
+ alias __gnuc_va_list = __builtin_va_list;
+}
+else version (SysV_x64)
+{
+ alias va_list = core.internal.vararg.sysv_x64.va_list;
+ public import core.internal.vararg.sysv_x64 : __va_list, __va_list_tag;
+}
+else version (AAPCS32)
+{
+ alias va_list = __va_list;
- /*************
- * Retrieve and store through parmn the next value that is of TypeInfo ti.
- * Used when the static type is not known.
- */
- void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
+ // need std::__va_list for C++ mangling compatibility (AAPCS32 section 8.1.4)
+ extern (C++, std) struct __va_list
{
- // Wait until everyone updates to get TypeInfo.talign
- //auto talign = ti.talign;
- //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1);
- auto p = ap;
- auto tsize = ti.tsize;
- ap = cast(va_list)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
- parmn[0..tsize] = p[0..tsize];
+ void* __ap;
}
+}
+else version (AAPCS64)
+{
+ alias va_list = core.internal.vararg.aarch64.va_list;
+}
+else
+{
+ alias va_list = char*; // incl. unknown platforms
+}
- /***********************
- * End use of ap.
- */
- void va_end(va_list ap)
+
+/**
+ * Initialize ap.
+ * parmn should be the last named parameter.
+ */
+version (GNU)
+{
+ void va_start(T)(out va_list ap, ref T parmn);
+}
+else version (LDC)
+{
+ pragma(LDC_va_start)
+ void va_start(T)(out va_list ap, ref T parmn) @nogc;
+}
+else version (DigitalMars)
+{
+ version (X86)
{
+ void va_start(T)(out va_list ap, ref T parmn)
+ {
+ ap = cast(va_list) ((cast(void*) &parmn) + T.sizeof.alignUp);
+ }
}
-
- ///
- void va_copy(out va_list dest, va_list src)
+ else
{
- dest = src;
+ void va_start(T)(out va_list ap, ref T parmn); // intrinsic; parmn should be __va_argsave for non-Windows x86_64 targets
}
}
-else version (Windows) // Win64
-{ /* Win64 is characterized by all arguments fitting into a register size.
- * Smaller ones are padded out to register size, and larger ones are passed by
- * reference.
- */
- /*********************
- * The argument pointer type.
- */
- alias char* va_list;
- /**********
- * Initialize ap.
- * parmn should be the last named parameter.
- */
- void va_start(T)(out va_list ap, ref T parmn); // Compiler intrinsic
-
- /************
- * Retrieve and return the next value that is type T.
- */
- T va_arg(T)(ref va_list ap)
+/**
+ * Retrieve and return the next value that is of type T.
+ */
+version (GNU)
+ T va_arg(T)(ref va_list ap); // intrinsic
+else
+T va_arg(T)(ref va_list ap)
+{
+ version (X86)
{
- static if (T.sizeof > size_t.sizeof)
- T arg = **cast(T**)ap;
- else
- T arg = *cast(T*)ap;
- ap = cast(va_list)(cast(void*)ap + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
- return arg;
+ auto p = cast(T*) ap;
+ ap += T.sizeof.alignUp;
+ return *p;
}
-
- /************
- * Retrieve and return the next value that is type T.
- * This is the preferred version.
- */
- void va_arg(T)(ref va_list ap, ref T parmn)
+ else version (Win64)
{
- static if (T.sizeof > size_t.sizeof)
- parmn = **cast(T**)ap;
+ // LDC passes slices as 2 separate 64-bit values, not as 128-bit struct
+ version (LDC) enum isLDC = true;
+ else enum isLDC = false;
+ static if (isLDC && is(T == E[], E))
+ {
+ auto p = cast(T*) ap;
+ ap += T.sizeof;
+ return *p;
+ }
else
- parmn = *cast(T*)ap;
- ap = cast(va_list)(cast(void*)ap + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
- }
-
- /*************
- * Retrieve and store through parmn the next value that is of TypeInfo ti.
- * Used when the static type is not known.
- */
- void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
- {
- // Wait until everyone updates to get TypeInfo.talign
- //auto talign = ti.talign;
- //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1);
- auto p = ap;
- auto tsize = ti.tsize;
- ap = cast(va_list)(cast(size_t)p + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
- void* q = (tsize > size_t.sizeof) ? *cast(void**)p : p;
- parmn[0..tsize] = q[0..tsize];
+ {
+ // passed indirectly by value if > 64 bits or of a size that is not a power of 2
+ static if (T.sizeof > size_t.sizeof || (T.sizeof & (T.sizeof - 1)) != 0)
+ auto p = *cast(T**) ap;
+ else
+ auto p = cast(T*) ap;
+ ap += size_t.sizeof;
+ return *p;
+ }
}
-
- /***********************
- * End use of ap.
- */
- void va_end(va_list ap)
+ else version (SysV_x64)
{
+ return core.internal.vararg.sysv_x64.va_arg!T(ap);
}
-
- ///
- void va_copy(out va_list dest, va_list src)
+ else version (AAPCS32)
{
- dest = src;
+ // AAPCS32 section 6.5 B.5: type with alignment >= 8 is 8-byte aligned
+ // instead of normal 4-byte alignment (APCS doesn't do this).
+ if (T.alignof >= 8)
+ ap.__ap = ap.__ap.alignUp!8;
+ auto p = cast(T*) ap.__ap;
+ version (BigEndian)
+ static if (T.sizeof < size_t.sizeof)
+ p = adjustForBigEndian(p, T.sizeof);
+ ap.__ap += T.sizeof.alignUp;
+ return *p;
}
-}
-else version (X86_64)
-{
- // Determine if type is a vector type
- template isVectorType(T)
+ else version (AAPCS64)
{
- enum isVectorType = false;
+ return core.internal.vararg.aarch64.va_arg!T(ap);
}
-
- template isVectorType(T : __vector(T[N]), size_t N)
+ else version (ARM_Any)
{
- enum isVectorType = true;
+ auto p = cast(T*) ap;
+ version (BigEndian)
+ static if (T.sizeof < size_t.sizeof)
+ p = adjustForBigEndian(p, T.sizeof);
+ ap += T.sizeof.alignUp;
+ return *p;
}
-
- // Layout of this struct must match __gnuc_va_list for C ABI compatibility
- struct __va_list_tag
+ else version (PPC_Any)
{
- uint offset_regs = 6 * 8; // no regs
- uint offset_fpregs = 6 * 8 + 8 * 16; // no fp regs
- void* stack_args;
- void* reg_args;
+ /*
+ * The rules are described in the 64bit PowerPC ELF ABI Supplement 1.9,
+ * available here:
+ * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#PARAM-PASS
+ */
+
+ // Chapter 3.1.4 and 3.2.3: alignment may require the va_list pointer to first
+ // be aligned before accessing a value
+ if (T.alignof >= 8)
+ ap = ap.alignUp!8;
+ auto p = cast(T*) ap;
+ version (BigEndian)
+ static if (T.sizeof < size_t.sizeof)
+ p = adjustForBigEndian(p, T.sizeof);
+ ap += T.sizeof.alignUp;
+ return *p;
}
- alias __va_list = __va_list_tag;
-
- align(16) struct __va_argsave_t
+ else version (MIPS_Any)
{
- size_t[6] regs; // RDI,RSI,RDX,RCX,R8,R9
- real[8] fpregs; // XMM0..XMM7
- __va_list va;
+ auto p = cast(T*) ap;
+ version (BigEndian)
+ static if (T.sizeof < size_t.sizeof)
+ p = adjustForBigEndian(p, T.sizeof);
+ ap += T.sizeof.alignUp;
+ return *p;
}
+ else
+ static assert(0, "Unsupported platform");
+}
- /*
- * Making it an array of 1 causes va_list to be passed as a pointer in
- * function argument lists
- */
- alias va_list = __va_list*;
-
- ///
- void va_start(T)(out va_list ap, ref T parmn); // Compiler intrinsic
- ///
- T va_arg(T)(va_list ap)
- { T a;
- va_arg(ap, a);
- return a;
- }
+/**
+ * Retrieve and store in parmn the next value that is of type T.
+ */
+version (GNU)
+ void va_arg(T)(ref va_list ap, ref T parmn); // intrinsic
+else
+void va_arg(T)(ref va_list ap, ref T parmn)
+{
+ parmn = va_arg!T(ap);
+}
- ///
- void va_arg(T)(va_list apx, ref T parmn)
- {
- __va_list* ap = cast(__va_list*)apx;
- static if (is(T U == __argTypes))
- {
- static if (U.length == 0 || T.sizeof > 16 || (U[0].sizeof > 8 && !isVectorType!(U[0])))
- { // Always passed in memory
- // The arg may have more strict alignment than the stack
- auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1);
- ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
- parmn = *cast(T*)p;
- }
- else static if (U.length == 1)
- { // Arg is passed in one register
- alias U[0] T1;
- static if (is(T1 == double) || is(T1 == float) || isVectorType!(T1))
- { // Passed in XMM register
- if (ap.offset_fpregs < (6 * 8 + 16 * 8))
- {
- parmn = *cast(T*)(ap.reg_args + ap.offset_fpregs);
- ap.offset_fpregs += 16;
- }
- else
- {
- parmn = *cast(T*)ap.stack_args;
- ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
- }
- }
- else
- { // Passed in regular register
- if (ap.offset_regs < 6 * 8 && T.sizeof <= 8)
- {
- parmn = *cast(T*)(ap.reg_args + ap.offset_regs);
- ap.offset_regs += 8;
- }
- else
- {
- auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1);
- ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
- parmn = *cast(T*)p;
- }
- }
- }
- else static if (U.length == 2)
- { // Arg is passed in two registers
- alias U[0] T1;
- alias U[1] T2;
- auto p = cast(void*)&parmn + 8;
- // Both must be in registers, or both on stack, hence 4 cases
+/**
+ * End use of ap.
+ */
+version (GNU)
+{
+ alias va_end = __builtin_va_end;
+}
+else version (LDC)
+{
+ pragma(LDC_va_end)
+ void va_end(va_list ap);
+}
+else version (DigitalMars)
+{
+ void va_end(va_list ap) {}
+}
- static if ((is(T1 == double) || is(T1 == float)) &&
- (is(T2 == double) || is(T2 == float)))
- {
- if (ap.offset_fpregs < (6 * 8 + 16 * 8) - 16)
- {
- *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_fpregs);
- *cast(T2*)p = *cast(T2*)(ap.reg_args + ap.offset_fpregs + 16);
- ap.offset_fpregs += 32;
- }
- else
- {
- *cast(T1*)&parmn = *cast(T1*)ap.stack_args;
- ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
- *cast(T2*)p = *cast(T2*)ap.stack_args;
- ap.stack_args += (T2.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
- }
- }
- else static if (is(T1 == double) || is(T1 == float))
- {
- void* a = void;
- if (ap.offset_fpregs < (6 * 8 + 16 * 8) &&
- ap.offset_regs < 6 * 8 && T2.sizeof <= 8)
- {
- *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_fpregs);
- ap.offset_fpregs += 16;
- a = ap.reg_args + ap.offset_regs;
- ap.offset_regs += 8;
- }
- else
- {
- *cast(T1*)&parmn = *cast(T1*)ap.stack_args;
- ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
- a = ap.stack_args;
- ap.stack_args += 8;
- }
- // Be careful not to go past the size of the actual argument
- const sz2 = T.sizeof - 8;
- p[0..sz2] = a[0..sz2];
- }
- else static if (is(T2 == double) || is(T2 == float))
- {
- if (ap.offset_regs < 6 * 8 && T1.sizeof <= 8 &&
- ap.offset_fpregs < (6 * 8 + 16 * 8))
- {
- *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_regs);
- ap.offset_regs += 8;
- *cast(T2*)p = *cast(T2*)(ap.reg_args + ap.offset_fpregs);
- ap.offset_fpregs += 16;
- }
- else
- {
- *cast(T1*)&parmn = *cast(T1*)ap.stack_args;
- ap.stack_args += 8;
- *cast(T2*)p = *cast(T2*)ap.stack_args;
- ap.stack_args += (T2.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
- }
- }
- else // both in regular registers
- {
- void* a = void;
- if (ap.offset_regs < 5 * 8 && T1.sizeof <= 8 && T2.sizeof <= 8)
- {
- *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_regs);
- ap.offset_regs += 8;
- a = ap.reg_args + ap.offset_regs;
- ap.offset_regs += 8;
- }
- else
- {
- *cast(T1*)&parmn = *cast(T1*)ap.stack_args;
- ap.stack_args += 8;
- a = ap.stack_args;
- ap.stack_args += 8;
- }
- // Be careful not to go past the size of the actual argument
- const sz2 = T.sizeof - 8;
- p[0..sz2] = a[0..sz2];
- }
- }
- else
- {
- static assert(false);
- }
- }
- else
- {
- static assert(false, "not a valid argument type for va_arg");
- }
- }
- ///
- void va_arg()(va_list apx, TypeInfo ti, void* parmn)
+/**
+ * Make a copy of ap.
+ */
+version (GNU)
+{
+ alias va_copy = __builtin_va_copy;
+}
+else version (LDC)
+{
+ pragma(LDC_va_copy)
+ void va_copy(out va_list dest, va_list src);
+}
+else version (DigitalMars)
+{
+ version (SysV_x64)
{
- __va_list* ap = cast(__va_list*)apx;
- TypeInfo arg1, arg2;
- if (!ti.argTypes(arg1, arg2))
+ void va_copy(out va_list dest, va_list src, void* storage = alloca(__va_list_tag.sizeof))
{
- bool inXMMregister(TypeInfo arg) pure nothrow @safe
- {
- return (arg.flags & 2) != 0;
- }
-
- TypeInfo_Vector v1 = arg1 ? cast(TypeInfo_Vector)arg1 : null;
- if (arg1 && (arg1.tsize <= 8 || v1))
- { // Arg is passed in one register
- auto tsize = arg1.tsize;
- void* p;
- bool stack = false;
- auto offset_fpregs_save = ap.offset_fpregs;
- auto offset_regs_save = ap.offset_regs;
- L1:
- if (inXMMregister(arg1) || v1)
- { // Passed in XMM register
- if (ap.offset_fpregs < (6 * 8 + 16 * 8) && !stack)
- {
- p = ap.reg_args + ap.offset_fpregs;
- ap.offset_fpregs += 16;
- }
- else
- {
- p = ap.stack_args;
- ap.stack_args += (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
- stack = true;
- }
- }
- else
- { // Passed in regular register
- if (ap.offset_regs < 6 * 8 && !stack)
- {
- p = ap.reg_args + ap.offset_regs;
- ap.offset_regs += 8;
- }
- else
- {
- p = ap.stack_args;
- ap.stack_args += 8;
- stack = true;
- }
- }
- parmn[0..tsize] = p[0..tsize];
-
- if (arg2)
- {
- if (inXMMregister(arg2))
- { // Passed in XMM register
- if (ap.offset_fpregs < (6 * 8 + 16 * 8) && !stack)
- {
- p = ap.reg_args + ap.offset_fpregs;
- ap.offset_fpregs += 16;
- }
- else
- {
- if (!stack)
- { // arg1 is really on the stack, so rewind and redo
- ap.offset_fpregs = offset_fpregs_save;
- ap.offset_regs = offset_regs_save;
- stack = true;
- goto L1;
- }
- p = ap.stack_args;
- ap.stack_args += (arg2.tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
- }
- }
- else
- { // Passed in regular register
- if (ap.offset_regs < 6 * 8 && !stack)
- {
- p = ap.reg_args + ap.offset_regs;
- ap.offset_regs += 8;
- }
- else
- {
- if (!stack)
- { // arg1 is really on the stack, so rewind and redo
- ap.offset_fpregs = offset_fpregs_save;
- ap.offset_regs = offset_regs_save;
- stack = true;
- goto L1;
- }
- p = ap.stack_args;
- ap.stack_args += 8;
- }
- }
- auto sz = ti.tsize - 8;
- (parmn + 8)[0..sz] = p[0..sz];
- }
- }
- else
- { // Always passed in memory
- // The arg may have more strict alignment than the stack
- auto talign = ti.talign;
- auto tsize = ti.tsize;
- auto p = cast(void*)((cast(size_t)ap.stack_args + talign - 1) & ~(talign - 1));
- ap.stack_args = cast(void*)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
- parmn[0..tsize] = p[0..tsize];
- }
+ // Instead of copying the pointers, and aliasing the source va_list,
+ // the default argument alloca will allocate storage in the caller's
+ // stack frame. This is still not correct (it should be allocated in
+ // the place where the va_list variable is declared) but most of the
+ // time the caller's stack frame _is_ the place where the va_list is
+ // allocated, so in most cases this will now work.
+ dest = cast(va_list) storage;
+ *dest = *src;
}
- else
- {
- assert(false, "not a valid argument type for va_arg");
- }
- }
- ///
- void va_end(va_list ap)
- {
+ import core.stdc.stdlib : alloca;
}
-
- import core.stdc.stdlib : alloca;
-
- ///
- void va_copy(out va_list dest, va_list src, void* storage = alloca(__va_list_tag.sizeof))
+ else
{
- // Instead of copying the pointers, and aliasing the source va_list,
- // the default argument alloca will allocate storage in the caller's
- // stack frame. This is still not correct (it should be allocated in
- // the place where the va_list variable is declared) but most of the
- // time the caller's stack frame _is_ the place where the va_list is
- // allocated, so in most cases this will now work.
- dest = cast(va_list)storage;
- *dest = *src;
+ void va_copy(out va_list dest, va_list src)
+ {
+ dest = src;
+ }
}
}
-else
-{
- static assert(false, "Unsupported platform");
-}
diff --git a/libphobos/libdruntime/core/stdc/stdint.d b/libphobos/libdruntime/core/stdc/stdint.d
index 0e31052..ac71b1d 100644
--- a/libphobos/libdruntime/core/stdc/stdint.d
+++ b/libphobos/libdruntime/core/stdc/stdint.d
@@ -14,10 +14,10 @@
module core.stdc.stdint;
-private import core.stdc.config;
-private import core.stdc.stddef; // for wchar_t
-private import core.stdc.signal; // for sig_atomic_t
-private import core.stdc.wchar_; // for wint_t
+import core.stdc.config;
+import core.stdc.stddef; // for wchar_t
+import core.stdc.signal; // for sig_atomic_t
+import core.stdc.wchar_; // for wint_t
version (OSX)
version = Darwin;
diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d
index e68f393..c76b922 100644
--- a/libphobos/libdruntime/core/stdc/stdio.d
+++ b/libphobos/libdruntime/core/stdc/stdio.d
@@ -268,7 +268,7 @@ else version (DragonFlyBSD)
ssize_t s_len; // current length of string
int s_flags; // flags
ssize_t s_sect_len; // current length of section
- };
+ }
enum {
SBUF_FIXEDLEN = 0x00000000, // fixed length buffer (default)
@@ -526,7 +526,7 @@ else version (FreeBSD)
int function(void*) _close;
int function(void*, char*, int) _read;
fpos_t function(void*, fpos_t, int) _seek;
- int function(void*, in char*, int) _write;
+ int function(void*, const scope char*, int) _write;
__sbuf _ub;
ubyte* _up;
@@ -572,7 +572,7 @@ else version (NetBSD)
int function(void*) _close;
ssize_t function(void*, char*, size_t) _read;
fpos_t function(void*, fpos_t, int) _seek;
- ssize_t function(void*, in char*, size_t) _write;
+ ssize_t function(void*, const scope char*, size_t) _write;
__sbuf _ub;
ubyte* _up;
@@ -1166,91 +1166,115 @@ version (MinGW)
// Prefer the MinGW versions over the MSVC ones, as the latter don't handle
// reals at all.
///
- int __mingw_fprintf(FILE* stream, scope const char* format, ...);
+ pragma(printf)
+ int __mingw_fprintf(FILE* stream, scope const char* format, scope const ...);
///
alias __mingw_fprintf fprintf;
///
- int __mingw_fscanf(FILE* stream, scope const char* format, ...);
+ pragma(scanf)
+ int __mingw_fscanf(FILE* stream, scope const char* format, scope ...);
///
alias __mingw_fscanf fscanf;
///
- int __mingw_sprintf(scope char* s, scope const char* format, ...);
+ pragma(printf)
+ int __mingw_sprintf(scope char* s, scope const char* format, scope const ...);
///
alias __mingw_sprintf sprintf;
///
- int __mingw_sscanf(scope const char* s, scope const char* format, ...);
+ pragma(scanf)
+ int __mingw_sscanf(scope const char* s, scope const char* format, scope ...);
///
alias __mingw_sscanf sscanf;
///
+ pragma(printf)
int __mingw_vfprintf(FILE* stream, scope const char* format, va_list arg);
///
alias __mingw_vfprintf vfprintf;
///
+ pragma(scanf)
int __mingw_vfscanf(FILE* stream, scope const char* format, va_list arg);
///
alias __mingw_vfscanf vfscanf;
///
+ pragma(printf)
int __mingw_vsprintf(scope char* s, scope const char* format, va_list arg);
///
alias __mingw_vsprintf vsprintf;
///
+ pragma(scanf)
int __mingw_vsscanf(scope const char* s, scope const char* format, va_list arg);
///
alias __mingw_vsscanf vsscanf;
///
+ pragma(printf)
int __mingw_vprintf(scope const char* format, va_list arg);
///
alias __mingw_vprintf vprintf;
///
+ pragma(scanf)
int __mingw_vscanf(scope const char* format, va_list arg);
///
alias __mingw_vscanf vscanf;
///
- int __mingw_printf(scope const char* format, ...);
+ pragma(printf)
+ int __mingw_printf(scope const char* format, scope const ...);
///
alias __mingw_printf printf;
///
- int __mingw_scanf(scope const char* format, ...);
+ pragma(scanf)
+ int __mingw_scanf(scope const char* format, scope ...);
///
alias __mingw_scanf scanf;
}
else
{
///
- int fprintf(FILE* stream, scope const char* format, ...);
+ pragma(printf)
+ int fprintf(FILE* stream, scope const char* format, scope const ...);
///
- int fscanf(FILE* stream, scope const char* format, ...);
+ pragma(scanf)
+ int fscanf(FILE* stream, scope const char* format, scope ...);
///
- int sprintf(scope char* s, scope const char* format, ...);
+ pragma(printf)
+ int sprintf(scope char* s, scope const char* format, scope const ...);
///
- int sscanf(scope const char* s, scope const char* format, ...);
+ pragma(scanf)
+ int sscanf(scope const char* s, scope const char* format, scope ...);
///
+ pragma(printf)
int vfprintf(FILE* stream, scope const char* format, va_list arg);
///
+ pragma(scanf)
int vfscanf(FILE* stream, scope const char* format, va_list arg);
///
+ pragma(printf)
int vsprintf(scope char* s, scope const char* format, va_list arg);
///
+ pragma(scanf)
int vsscanf(scope const char* s, scope const char* format, va_list arg);
///
+ pragma(printf)
int vprintf(scope const char* format, va_list arg);
///
+ pragma(scanf)
int vscanf(scope const char* format, va_list arg);
///
- int printf(scope const char* format, ...);
+ pragma(printf)
+ int printf(scope const char* format, scope const ...);
///
- int scanf(scope const char* format, ...);
+ pragma(scanf)
+ int scanf(scope const char* format, scope ...);
}
// No unsafe pointer manipulation.
@@ -1278,13 +1302,14 @@ extern (D) @trusted
int getchar()() { return getc(stdin); }
///
int putchar()(int c) { return putc(c,stdout); }
- ///
- int getc()(FILE* stream) { return fgetc(stream); }
- ///
- int putc()(int c, FILE* stream) { return fputc(c,stream); }
}
///
+alias getc = fgetc;
+///
+alias putc = fputc;
+
+///
@trusted int ungetc(int c, FILE* stream); // No unsafe pointer manipulation.
///
@@ -1322,15 +1347,37 @@ version (CRuntime_DigitalMars)
///
pure int fileno()(FILE* stream) { return stream._file; }
}
- ///
- int _snprintf(scope char* s, size_t n, scope const char* fmt, ...);
+ ///
+ pragma(printf)
+ int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
///
alias _snprintf snprintf;
///
+ pragma(printf)
int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
///
alias _vsnprintf vsnprintf;
+
+ //
+ // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the
+ // unshared version of FILE*, usable when the FILE is locked.
+ //
+
+ ///
+ int _fputc_nlock(int c, _iobuf* fp);
+ ///
+ int _fputwc_nlock(int c, _iobuf* fp);
+ ///
+ int _fgetc_nlock(_iobuf* fp);
+ ///
+ int _fgetwc_nlock(_iobuf* fp);
+ ///
+ int __fp_lock(FILE* fp);
+ ///
+ void __fp_unlock(FILE* fp);
+ ///
+ int setmode(int fd, int mode);
}
else version (CRuntime_Microsoft)
{
@@ -1351,13 +1398,15 @@ else version (CRuntime_Microsoft)
version (MinGW)
{
- int __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, ...);
+ pragma(printf)
+ int __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
///
alias __mingw_snprintf _snprintf;
///
alias __mingw_snprintf snprintf;
///
+ pragma(printf)
int __mingw_vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
///
alias __mingw_vsnprintf _vsnprintf;
@@ -1367,26 +1416,45 @@ else version (CRuntime_Microsoft)
else
{
///
- int _snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int _snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
+ pragma(printf)
int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
+ //
+ // Microsoft under-the-hood C I/O functions. Uses _iobuf* for the unshared
+ // version of FILE*, usable when the FILE is locked.
+ //
+ import core.stdc.stddef : wchar_t;
+ import core.stdc.wchar_ : wint_t;
+
///
- int _fputc_nolock(int c, FILE *fp);
+ int _fputc_nolock(int c, _iobuf* fp);
///
- int _fgetc_nolock(FILE *fp);
-
+ int _fgetc_nolock(_iobuf* fp);
///
- int _lock_file(FILE *fp);
+ wint_t _fputwc_nolock(wchar_t c, _iobuf* fp);
///
- int _unlock_file(FILE *fp);
-
+ wint_t _fgetwc_nolock(_iobuf* fp);
+ ///
+ void _lock_file(FILE* fp);
+ ///
+ void _unlock_file(FILE* fp);
+ ///
+ int _setmode(int fd, int mode);
+ ///
+ int _fseeki64(FILE* stream, long offset, int origin);
+ ///
+ long _ftelli64(FILE* stream);
///
intptr_t _get_osfhandle(int fd);
///
@@ -1410,9 +1478,28 @@ else version (CRuntime_Glibc)
}
///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
+
+ //
+ // Gnu under-the-hood C I/O functions. Uses _iobuf* for the unshared
+ // version of FILE*, usable when the FILE is locked.
+ // See http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html
+ //
+ import core.stdc.wchar_ : wint_t;
+ import core.stdc.stddef : wchar_t;
+
+ ///
+ int fputc_unlocked(int c, _iobuf* stream);
+ ///
+ int fgetc_unlocked(_iobuf* stream);
+ ///
+ wint_t fputwc_unlocked(wchar_t wc, _iobuf* stream);
+ ///
+ wint_t fgetwc_unlocked(_iobuf* stream);
}
else version (Darwin)
{
@@ -1432,8 +1519,10 @@ else version (Darwin)
}
///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else version (FreeBSD)
@@ -1454,8 +1543,10 @@ else version (FreeBSD)
}
///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else version (NetBSD)
@@ -1476,9 +1567,11 @@ else version (NetBSD)
}
///
- int snprintf(char* s, size_t n, in char* format, ...);
+ pragma(printf)
+ int snprintf(char* s, size_t n, const scope char* format, scope const ...);
///
- int vsnprintf(char* s, size_t n, in char* format, va_list arg);
+ pragma(printf)
+ int vsnprintf(char* s, size_t n, const scope char* format, va_list arg);
}
else version (OpenBSD)
{
@@ -1527,7 +1620,7 @@ else version (OpenBSD)
{
void __sclearerr()(FILE* p)
{
- p._flags &= ~(__SERR|__SEOF);
+ p._flags = p._flags & ~(__SERR|__SEOF);
}
int __sfeof()(FILE* p)
@@ -1567,8 +1660,10 @@ else version (OpenBSD)
}
///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else version (DragonFlyBSD)
@@ -1599,8 +1694,10 @@ else version (DragonFlyBSD)
enum __SALC = 0x4000;
enum __SIGN = 0x8000;
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
- int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
+ pragma(printf)
+ int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else version (Solaris)
{
@@ -1620,8 +1717,10 @@ else version (Solaris)
}
///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else version (CRuntime_Bionic)
@@ -1641,9 +1740,11 @@ else version (CRuntime_Bionic)
int fileno(FILE*);
}
- ///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
///
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
+ ///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else version (CRuntime_Musl)
@@ -1663,8 +1764,10 @@ else version (CRuntime_Musl)
}
///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else version (CRuntime_UClibc)
@@ -1685,8 +1788,10 @@ else version (CRuntime_UClibc)
}
///
- int snprintf(scope char* s, size_t n, scope const char* format, ...);
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
///
+ pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else
@@ -1854,6 +1959,22 @@ version (Windows)
O_TEXT = _O_TEXT, ///
_O_BINARY = 0x8000, ///
O_BINARY = _O_BINARY, ///
+ _O_WTEXT = 0x10000, ///
+ _O_U16TEXT = 0x20000, ///
+ _O_U8TEXT = 0x40000, ///
+ _O_ACCMODE = (_O_RDONLY|_O_WRONLY|_O_RDWR), ///
+ O_ACCMODE = _O_ACCMODE, ///
+ _O_RAW = _O_BINARY, ///
+ O_RAW = _O_BINARY, ///
+ _O_NOINHERIT = 0x0080, ///
+ O_NOINHERIT = _O_NOINHERIT, ///
+ _O_TEMPORARY = 0x0040, ///
+ O_TEMPORARY = _O_TEMPORARY, ///
+ _O_SHORT_LIVED = 0x1000, ///
+ _O_SEQUENTIAL = 0x0020, ///
+ O_SEQUENTIAL = _O_SEQUENTIAL, ///
+ _O_RANDOM = 0x0010, ///
+ O_RANDOM = _O_RANDOM, ///
}
enum
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 7c0b7b6..35e81a2 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -14,7 +14,7 @@
module core.stdc.stdlib;
-private import core.stdc.config;
+import core.stdc.config;
public import core.stdc.stddef; // for wchar_t
version (OSX)
@@ -121,19 +121,22 @@ ulong strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
version (CRuntime_Microsoft)
{
- // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
- ///
- extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
- { // Fake it 'till we make it
- return strtod(nptr, endptr);
+ version (MinGW)
+ {
+ ///
+ real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
+ ///
+ alias __mingw_strtold strtold;
+ }
+ else
+ {
+ // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
+ ///
+ extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
+ { // Fake it 'till we make it
+ return strtod(nptr, endptr);
+ }
}
-}
-else version (MinGW)
-{
- ///
- real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
- ///
- alias __mingw_strtold strtold;
}
else
{
@@ -164,13 +167,13 @@ void* realloc(void* ptr, size_t size);
void free(void* ptr);
///
-void abort() @safe;
+noreturn abort() @safe;
///
-void exit(int status);
+noreturn exit(int status);
///
int atexit(void function() func);
///
-void _Exit(int status);
+noreturn _Exit(int status);
///
char* getenv(scope const char* name);
diff --git a/libphobos/libdruntime/core/stdc/string.d b/libphobos/libdruntime/core/stdc/string.d
index 0929a4e..a26811c 100644
--- a/libphobos/libdruntime/core/stdc/string.d
+++ b/libphobos/libdruntime/core/stdc/string.d
@@ -35,51 +35,35 @@ nothrow:
@nogc:
///
-pure void* memchr(return const void* s, int c, size_t n);
+inout(void)* memchr(return inout void* s, int c, size_t n) pure;
///
-pure int memcmp(scope const void* s1, scope const void* s2, size_t n);
+int memcmp(scope const void* s1, scope const void* s2, size_t n) pure;
///
-pure void* memcpy(return void* s1, scope const void* s2, size_t n);
+void* memcpy(return void* s1, scope const void* s2, size_t n) pure;
version (Windows)
{
///
int memicmp(scope const char* s1, scope const char* s2, size_t n);
}
///
-pure void* memmove(return void* s1, scope const void* s2, size_t n);
+void* memmove(return void* s1, scope const void* s2, size_t n) pure;
///
-pure void* memset(return void* s, int c, size_t n);
+void* memset(return void* s, int c, size_t n) pure;
///
-pure char* strcpy(return char* s1, scope const char* s2);
+char* strcat(return char* s1, scope const char* s2) pure;
///
-pure char* strncpy(return char* s1, scope const char* s2, size_t n);
+inout(char)* strchr(return inout(char)* s, int c) pure;
///
-pure char* strcat(return char* s1, scope const char* s2);
-///
-pure char* strncat(return char* s1, scope const char* s2, size_t n);
-///
-pure int strcmp(scope const char* s1, scope const char* s2);
+int strcmp(scope const char* s1, scope const char* s2) pure;
///
int strcoll(scope const char* s1, scope const char* s2);
///
-pure int strncmp(scope const char* s1, scope const char* s2, size_t n);
-///
-size_t strxfrm(scope char* s1, scope const char* s2, size_t n);
-///
-pure inout(char)* strchr(return inout(char)* s, int c);
-///
-pure size_t strcspn(scope const char* s1, scope const char* s2);
+char* strcpy(return char* s1, scope const char* s2) pure;
///
-pure inout(char)* strpbrk(return inout(char)* s1, scope const char* s2);
+size_t strcspn(scope const char* s1, scope const char* s2) pure;
///
-pure inout(char)* strrchr(return inout(char)* s, int c);
-///
-pure size_t strspn(scope const char* s1, scope const char* s2);
-///
-pure inout(char)* strstr(return inout(char)* s1, scope const char* s2);
-///
-char* strtok(return char* s1, scope const char* s2);
+char* strdup(scope const char *s);
///
char* strerror(int errnum);
// This `strerror_r` definition is not following the POSIX standard
@@ -94,6 +78,22 @@ else
int strerror_r(int errnum, scope char* buf, size_t buflen);
}
///
-pure size_t strlen(scope const char* s);
+size_t strlen(scope const char* s) pure;
///
-char* strdup(scope const char *s);
+char* strncat(return char* s1, scope const char* s2, size_t n) pure;
+///
+int strncmp(scope const char* s1, scope const char* s2, size_t n) pure;
+///
+char* strncpy(return char* s1, scope const char* s2, size_t n) pure;
+///
+inout(char)* strpbrk(return inout(char)* s1, scope const char* s2) pure;
+///
+inout(char)* strrchr(return inout(char)* s, int c) pure;
+///
+size_t strspn(scope const char* s1, scope const char* s2) pure;
+///
+inout(char)* strstr(return inout(char)* s1, scope const char* s2) pure;
+///
+char* strtok(return char* s1, scope const char* s2);
+///
+size_t strxfrm(scope char* s1, scope const char* s2, size_t n);
diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d
index 16184e2..2d1a198 100644
--- a/libphobos/libdruntime/core/stdc/tgmath.d
+++ b/libphobos/libdruntime/core/stdc/tgmath.d
@@ -14,7 +14,7 @@
module core.stdc.tgmath;
-private import core.stdc.config;
+import core.stdc.config;
private static import core.stdc.math;
private static import core.stdc.complex;
@@ -23,554 +23,6 @@ extern (C):
nothrow:
@nogc:
-version (FreeBSD)
-{
- ///
- alias core.stdc.math.acos acos;
- ///
- alias core.stdc.math.acosf acos;
- ///
- alias core.stdc.math.acosl acos;
-
- ///
- alias core.stdc.complex.cacos acos;
- ///
- alias core.stdc.complex.cacosf acos;
- ///
- alias core.stdc.complex.cacosl acos;
-
- ///
- alias core.stdc.math.asin asin;
- ///
- alias core.stdc.math.asinf asin;
- ///
- alias core.stdc.math.asinl asin;
-
- ///
- alias core.stdc.complex.casin asin;
- ///
- alias core.stdc.complex.casinf asin;
- ///
- alias core.stdc.complex.casinl asin;
-
- ///
- alias core.stdc.math.atan atan;
- ///
- alias core.stdc.math.atanf atan;
- ///
- alias core.stdc.math.atanl atan;
-
- ///
- alias core.stdc.complex.catan atan;
- ///
- alias core.stdc.complex.catanf atan;
- ///
- alias core.stdc.complex.catanl atan;
-
- ///
- alias core.stdc.math.atan2 atan2;
- ///
- alias core.stdc.math.atan2f atan2;
- ///
- alias core.stdc.math.atan2l atan2;
-
- ///
- alias core.stdc.math.cos cos;
- ///
- alias core.stdc.math.cosf cos;
- ///
- alias core.stdc.math.cosl cos;
-
- ///
- alias core.stdc.complex.ccos cos;
- ///
- alias core.stdc.complex.ccosf cos;
- ///
- alias core.stdc.complex.ccosl cos;
-
- ///
- alias core.stdc.math.sin sin;
- ///
- alias core.stdc.math.sinf sin;
- ///
- alias core.stdc.math.sinl sin;
-
- ///
- alias core.stdc.complex.csin csin;
- ///
- alias core.stdc.complex.csinf csin;
- ///
- alias core.stdc.complex.csinl csin;
-
- ///
- alias core.stdc.math.tan tan;
- ///
- alias core.stdc.math.tanf tan;
- ///
- alias core.stdc.math.tanl tan;
-
- ///
- alias core.stdc.complex.ctan tan;
- ///
- alias core.stdc.complex.ctanf tan;
- ///
- alias core.stdc.complex.ctanl tan;
-
- ///
- alias core.stdc.math.acosh acosh;
- ///
- alias core.stdc.math.acoshf acosh;
- ///
- alias core.stdc.math.acoshl acosh;
-
- ///
- alias core.stdc.complex.cacosh acosh;
- ///
- alias core.stdc.complex.cacoshf acosh;
- ///
- alias core.stdc.complex.cacoshl acosh;
-
- ///
- alias core.stdc.math.asinh asinh;
- ///
- alias core.stdc.math.asinhf asinh;
- ///
- alias core.stdc.math.asinhl asinh;
-
- ///
- alias core.stdc.complex.casinh asinh;
- ///
- alias core.stdc.complex.casinhf asinh;
- ///
- alias core.stdc.complex.casinhl asinh;
-
- ///
- alias core.stdc.math.atanh atanh;
- ///
- alias core.stdc.math.atanhf atanh;
- ///
- alias core.stdc.math.atanhl atanh;
-
- ///
- alias core.stdc.complex.catanh atanh;
- ///
- alias core.stdc.complex.catanhf atanh;
- ///
- alias core.stdc.complex.catanhl atanh;
-
- ///
- alias core.stdc.math.cosh cosh;
- ///
- alias core.stdc.math.coshf cosh;
- ///
- alias core.stdc.math.coshl cosh;
-
- ///
- alias core.stdc.complex.ccosh cosh;
- ///
- alias core.stdc.complex.ccoshf cosh;
- ///
- alias core.stdc.complex.ccoshl cosh;
-
- ///
- alias core.stdc.math.sinh sinh;
- ///
- alias core.stdc.math.sinhf sinh;
- ///
- alias core.stdc.math.sinhl sinh;
-
- ///
- alias core.stdc.complex.csinh sinh;
- ///
- alias core.stdc.complex.csinhf sinh;
- ///
- alias core.stdc.complex.csinhl sinh;
-
- ///
- alias core.stdc.math.tanh tanh;
- ///
- alias core.stdc.math.tanhf tanh;
- ///
- alias core.stdc.math.tanhl tanh;
-
- ///
- alias core.stdc.complex.ctanh tanh;
- ///
- alias core.stdc.complex.ctanhf tanh;
- ///
- alias core.stdc.complex.ctanhl tanh;
-
- ///
- alias core.stdc.math.exp exp;
- ///
- alias core.stdc.math.expf exp;
- ///
- alias core.stdc.math.expl exp;
-
- ///
- alias core.stdc.complex.cexp exp;
- ///
- alias core.stdc.complex.cexpf exp;
- ///
- alias core.stdc.complex.cexpl exp;
-
- ///
- alias core.stdc.math.exp2 exp2;
- ///
- alias core.stdc.math.exp2f exp2;
- ///
- alias core.stdc.math.exp2l exp2;
-
- ///
- alias core.stdc.math.expm1 expm1;
- ///
- alias core.stdc.math.expm1f expm1;
- ///
- alias core.stdc.math.expm1l expm1;
-
- ///
- alias core.stdc.math.frexp frexp;
- ///
- alias core.stdc.math.frexpf frexp;
- ///
- alias core.stdc.math.frexpl frexp;
-
- ///
- alias core.stdc.math.ilogb ilogb;
- ///
- alias core.stdc.math.ilogbf ilogb;
- ///
- alias core.stdc.math.ilogbl ilogb;
-
- ///
- alias core.stdc.math.ldexp ldexp;
- ///
- alias core.stdc.math.ldexpf ldexp;
- ///
- alias core.stdc.math.ldexpl ldexp;
-
- ///
- alias core.stdc.math.log log;
- ///
- alias core.stdc.math.logf log;
- ///
- alias core.stdc.math.logl log;
-
- ///
- alias core.stdc.complex.clog log;
- ///
- alias core.stdc.complex.clogf log;
- ///
- alias core.stdc.complex.clogl log;
-
- ///
- alias core.stdc.math.log10 log10;
- ///
- alias core.stdc.math.log10f log10;
- ///
- alias core.stdc.math.log10l log10;
-
- ///
- alias core.stdc.math.log1p log1p;
- ///
- alias core.stdc.math.log1pf log1p;
- ///
- alias core.stdc.math.log1pl log1p;
-
- ///
- alias core.stdc.math.log2 log2;
- ///
- alias core.stdc.math.log2f log2;
- ///
- alias core.stdc.math.log2l log2;
-
- ///
- alias core.stdc.math.logb logb;
- ///
- alias core.stdc.math.logbf logb;
- ///
- alias core.stdc.math.logbl logb;
-
- ///
- alias core.stdc.math.modf modf;
- ///
- alias core.stdc.math.modff modf;
-// alias core.stdc.math.modfl modf;
-
- ///
- alias core.stdc.math.scalbn scalbn;
- ///
- alias core.stdc.math.scalbnf scalbn;
- ///
- alias core.stdc.math.scalbnl scalbn;
-
- ///
- alias core.stdc.math.scalbln scalbln;
- ///
- alias core.stdc.math.scalblnf scalbln;
- ///
- alias core.stdc.math.scalblnl scalbln;
-
- ///
- alias core.stdc.math.cbrt cbrt;
- ///
- alias core.stdc.math.cbrtf cbrt;
- ///
- alias core.stdc.math.cbrtl cbrt;
-
- ///
- alias core.stdc.math.fabs fabs;
- ///
- alias core.stdc.math.fabsf fabs;
- ///
- alias core.stdc.math.fabsl fabs;
-
- ///
- alias core.stdc.complex.cabs fabs;
- ///
- alias core.stdc.complex.cabsf fabs;
- ///
- alias core.stdc.complex.cabsl fabs;
-
- ///
- alias core.stdc.math.hypot hypot;
- ///
- alias core.stdc.math.hypotf hypot;
- ///
- alias core.stdc.math.hypotl hypot;
-
- ///
- alias core.stdc.math.pow pow;
- ///
- alias core.stdc.math.powf pow;
- ///
- alias core.stdc.math.powl pow;
-
- ///
- alias core.stdc.complex.cpow pow;
- ///
- alias core.stdc.complex.cpowf pow;
- ///
- alias core.stdc.complex.cpowl pow;
-
- ///
- alias core.stdc.math.sqrt sqrt;
- ///
- alias core.stdc.math.sqrtf sqrt;
- ///
- alias core.stdc.math.sqrtl sqrt;
-
- ///
- alias core.stdc.complex.csqrt sqrt;
- ///
- alias core.stdc.complex.csqrtf sqrt;
- ///
- alias core.stdc.complex.csqrtl sqrt;
-
- ///
- alias core.stdc.math.erf erf;
- ///
- alias core.stdc.math.erff erf;
- ///
- alias core.stdc.math.erfl erf;
-
- ///
- alias core.stdc.math.erfc erfc;
- ///
- alias core.stdc.math.erfcf erfc;
- ///
- alias core.stdc.math.erfcl erfc;
-
- ///
- alias core.stdc.math.lgamma lgamma;
- ///
- alias core.stdc.math.lgammaf lgamma;
- ///
- alias core.stdc.math.lgammal lgamma;
-
- ///
- alias core.stdc.math.tgamma tgamma;
- ///
- alias core.stdc.math.tgammaf tgamma;
- ///
- alias core.stdc.math.tgammal tgamma;
-
- ///
- alias core.stdc.math.ceil ceil;
- ///
- alias core.stdc.math.ceilf ceil;
- ///
- alias core.stdc.math.ceill ceil;
-
- ///
- alias core.stdc.math.floor floor;
- ///
- alias core.stdc.math.floorf floor;
- ///
- alias core.stdc.math.floorl floor;
-
- ///
- alias core.stdc.math.nearbyint nearbyint;
- ///
- alias core.stdc.math.nearbyintf nearbyint;
- ///
- alias core.stdc.math.nearbyintl nearbyint;
-
- ///
- alias core.stdc.math.rint rint;
- ///
- alias core.stdc.math.rintf rint;
- ///
- alias core.stdc.math.rintl rint;
-
- ///
- alias core.stdc.math.lrint lrint;
- ///
- alias core.stdc.math.lrintf lrint;
- ///
- alias core.stdc.math.lrintl lrint;
-
- ///
- alias core.stdc.math.llrint llrint;
- ///
- alias core.stdc.math.llrintf llrint;
- ///
- alias core.stdc.math.llrintl llrint;
-
- ///
- alias core.stdc.math.round round;
- ///
- alias core.stdc.math.roundf round;
- ///
- alias core.stdc.math.roundl round;
-
- ///
- alias core.stdc.math.lround lround;
- ///
- alias core.stdc.math.lroundf lround;
- ///
- alias core.stdc.math.lroundl lround;
-
- ///
- alias core.stdc.math.llround llround;
- ///
- alias core.stdc.math.llroundf llround;
- ///
- alias core.stdc.math.llroundl llround;
-
- ///
- alias core.stdc.math.trunc trunc;
- ///
- alias core.stdc.math.truncf trunc;
- ///
- alias core.stdc.math.truncl trunc;
-
- ///
- alias core.stdc.math.fmod fmod;
- ///
- alias core.stdc.math.fmodf fmod;
- ///
- alias core.stdc.math.fmodl fmod;
-
- ///
- alias core.stdc.math.remainder remainder;
- ///
- alias core.stdc.math.remainderf remainder;
- ///
- alias core.stdc.math.remainderl remainder;
-
- ///
- alias core.stdc.math.remquo remquo;
- ///
- alias core.stdc.math.remquof remquo;
- ///
- alias core.stdc.math.remquol remquo;
-
- ///
- alias core.stdc.math.copysign copysign;
- ///
- alias core.stdc.math.copysignf copysign;
- ///
- alias core.stdc.math.copysignl copysign;
-
-// alias core.stdc.math.nan nan;
-// alias core.stdc.math.nanf nan;
-// alias core.stdc.math.nanl nan;
-
- ///
- alias core.stdc.math.nextafter nextafter;
- ///
- alias core.stdc.math.nextafterf nextafter;
- ///
- alias core.stdc.math.nextafterl nextafter;
-
- ///
- alias core.stdc.math.nexttoward nexttoward;
- ///
- alias core.stdc.math.nexttowardf nexttoward;
- ///
- alias core.stdc.math.nexttowardl nexttoward;
-
- ///
- alias core.stdc.math.fdim fdim;
- ///
- alias core.stdc.math.fdimf fdim;
- ///
- alias core.stdc.math.fdiml fdim;
-
- ///
- alias core.stdc.math.fmax fmax;
- ///
- alias core.stdc.math.fmaxf fmax;
- ///
- alias core.stdc.math.fmaxl fmax;
-
- ///
- alias core.stdc.math.fmin fmin;
- ///
- alias core.stdc.math.fmin fmin;
- ///
- alias core.stdc.math.fminl fmin;
-
- ///
- alias core.stdc.math.fma fma;
- ///
- alias core.stdc.math.fmaf fma;
- ///
- alias core.stdc.math.fmal fma;
-
- ///
- alias core.stdc.complex.carg carg;
- ///
- alias core.stdc.complex.cargf carg;
- ///
- alias core.stdc.complex.cargl carg;
-
- ///
- alias core.stdc.complex.cimag cimag;
- ///
- alias core.stdc.complex.cimagf cimag;
- ///
- alias core.stdc.complex.cimagl cimag;
-
- ///
- alias core.stdc.complex.conj conj;
- ///
- alias core.stdc.complex.conjf conj;
- ///
- alias core.stdc.complex.conjl conj;
-
- ///
- alias core.stdc.complex.cproj cproj;
- ///
- alias core.stdc.complex.cprojf cproj;
- ///
- alias core.stdc.complex.cprojl cproj;
-
-// alias core.stdc.complex.creal creal;
-// alias core.stdc.complex.crealf creal;
-// alias core.stdc.complex.creall creal;
-}
version (NetBSD)
{
///
@@ -580,12 +32,10 @@ version (NetBSD)
///
alias core.stdc.math.acosl acos;
- ///
- alias core.stdc.complex.cacos acos;
- ///
- alias core.stdc.complex.cacosf acos;
- ///
- alias core.stdc.complex.cacosl acos;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cacos acos;
+ deprecated alias core.stdc.complex.cacosf acos;
+ deprecated alias core.stdc.complex.cacosl acos;
///
alias core.stdc.math.asin asin;
@@ -594,12 +44,10 @@ version (NetBSD)
///
alias core.stdc.math.asinl asin;
- ///
- alias core.stdc.complex.casin asin;
- ///
- alias core.stdc.complex.casinf asin;
- ///
- alias core.stdc.complex.casinl asin;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.casin asin;
+ deprecated alias core.stdc.complex.casinf asin;
+ deprecated alias core.stdc.complex.casinl asin;
///
alias core.stdc.math.atan atan;
@@ -608,12 +56,10 @@ version (NetBSD)
///
alias core.stdc.math.atanl atan;
- ///
- alias core.stdc.complex.catan atan;
- ///
- alias core.stdc.complex.catanf atan;
- ///
- alias core.stdc.complex.catanl atan;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.catan atan;
+ deprecated alias core.stdc.complex.catanf atan;
+ deprecated alias core.stdc.complex.catanl atan;
///
alias core.stdc.math.atan2 atan2;
@@ -629,12 +75,10 @@ version (NetBSD)
///
alias core.stdc.math.cosl cos;
- ///
- alias core.stdc.complex.ccos cos;
- ///
- alias core.stdc.complex.ccosf cos;
- ///
- alias core.stdc.complex.ccosl cos;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ccos cos;
+ deprecated alias core.stdc.complex.ccosf cos;
+ deprecated alias core.stdc.complex.ccosl cos;
///
alias core.stdc.math.sin sin;
@@ -643,12 +87,10 @@ version (NetBSD)
///
alias core.stdc.math.sinl sin;
- ///
- alias core.stdc.complex.csin csin;
- ///
- alias core.stdc.complex.csinf csin;
- ///
- alias core.stdc.complex.csinl csin;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csin csin;
+ deprecated alias core.stdc.complex.csinf csin;
+ deprecated alias core.stdc.complex.csinl csin;
///
alias core.stdc.math.tan tan;
@@ -657,12 +99,10 @@ version (NetBSD)
///
alias core.stdc.math.tanl tan;
- ///
- alias core.stdc.complex.ctan tan;
- ///
- alias core.stdc.complex.ctanf tan;
- ///
- alias core.stdc.complex.ctanl tan;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ctan tan;
+ deprecated alias core.stdc.complex.ctanf tan;
+ deprecated alias core.stdc.complex.ctanl tan;
///
alias core.stdc.math.acosh acosh;
@@ -671,12 +111,10 @@ version (NetBSD)
///
alias core.stdc.math.acoshl acosh;
- ///
- alias core.stdc.complex.cacosh acosh;
- ///
- alias core.stdc.complex.cacoshf acosh;
- ///
- alias core.stdc.complex.cacoshl acosh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cacosh acosh;
+ deprecated alias core.stdc.complex.cacoshf acosh;
+ deprecated alias core.stdc.complex.cacoshl acosh;
///
alias core.stdc.math.asinh asinh;
@@ -685,12 +123,10 @@ version (NetBSD)
///
alias core.stdc.math.asinhl asinh;
- ///
- alias core.stdc.complex.casinh asinh;
- ///
- alias core.stdc.complex.casinhf asinh;
- ///
- alias core.stdc.complex.casinhl asinh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.casinh asinh;
+ deprecated alias core.stdc.complex.casinhf asinh;
+ deprecated alias core.stdc.complex.casinhl asinh;
///
alias core.stdc.math.atanh atanh;
@@ -699,12 +135,10 @@ version (NetBSD)
///
alias core.stdc.math.atanhl atanh;
- ///
- alias core.stdc.complex.catanh atanh;
- ///
- alias core.stdc.complex.catanhf atanh;
- ///
- alias core.stdc.complex.catanhl atanh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.catanh atanh;
+ deprecated alias core.stdc.complex.catanhf atanh;
+ deprecated alias core.stdc.complex.catanhl atanh;
///
alias core.stdc.math.cosh cosh;
@@ -713,12 +147,10 @@ version (NetBSD)
///
alias core.stdc.math.coshl cosh;
- ///
- alias core.stdc.complex.ccosh cosh;
- ///
- alias core.stdc.complex.ccoshf cosh;
- ///
- alias core.stdc.complex.ccoshl cosh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ccosh cosh;
+ deprecated alias core.stdc.complex.ccoshf cosh;
+ deprecated alias core.stdc.complex.ccoshl cosh;
///
alias core.stdc.math.sinh sinh;
@@ -727,12 +159,10 @@ version (NetBSD)
///
alias core.stdc.math.sinhl sinh;
- ///
- alias core.stdc.complex.csinh sinh;
- ///
- alias core.stdc.complex.csinhf sinh;
- ///
- alias core.stdc.complex.csinhl sinh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csinh sinh;
+ deprecated alias core.stdc.complex.csinhf sinh;
+ deprecated alias core.stdc.complex.csinhl sinh;
///
alias core.stdc.math.tanh tanh;
@@ -741,12 +171,10 @@ version (NetBSD)
///
alias core.stdc.math.tanhl tanh;
- ///
- alias core.stdc.complex.ctanh tanh;
- ///
- alias core.stdc.complex.ctanhf tanh;
- ///
- alias core.stdc.complex.ctanhl tanh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ctanh tanh;
+ deprecated alias core.stdc.complex.ctanhf tanh;
+ deprecated alias core.stdc.complex.ctanhl tanh;
///
alias core.stdc.math.exp exp;
@@ -755,12 +183,10 @@ version (NetBSD)
///
alias core.stdc.math.expl exp;
- ///
- alias core.stdc.complex.cexp exp;
- ///
- alias core.stdc.complex.cexpf exp;
- ///
- alias core.stdc.complex.cexpl exp;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cexp exp;
+ deprecated alias core.stdc.complex.cexpf exp;
+ deprecated alias core.stdc.complex.cexpl exp;
///
alias core.stdc.math.exp2 exp2;
@@ -804,12 +230,10 @@ version (NetBSD)
///
alias core.stdc.math.logl log;
- ///
- alias core.stdc.complex.clog log;
- ///
- alias core.stdc.complex.clogf log;
- ///
- alias core.stdc.complex.clogl log;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.clog log;
+ deprecated alias core.stdc.complex.clogf log;
+ deprecated alias core.stdc.complex.clogl log;
///
alias core.stdc.math.log10 log10;
@@ -873,12 +297,10 @@ version (NetBSD)
///
alias core.stdc.math.fabsl fabs;
- ///
- alias core.stdc.complex.cabs fabs;
- ///
- alias core.stdc.complex.cabsf fabs;
- ///
- alias core.stdc.complex.cabsl fabs;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cabs fabs;
+ deprecated alias core.stdc.complex.cabsf fabs;
+ deprecated alias core.stdc.complex.cabsl fabs;
///
alias core.stdc.math.hypot hypot;
@@ -894,12 +316,10 @@ version (NetBSD)
///
alias core.stdc.math.powl pow;
- ///
- alias core.stdc.complex.cpow pow;
- ///
- alias core.stdc.complex.cpowf pow;
- ///
- alias core.stdc.complex.cpowl pow;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cpow pow;
+ deprecated alias core.stdc.complex.cpowf pow;
+ deprecated alias core.stdc.complex.cpowl pow;
///
alias core.stdc.math.sqrt sqrt;
@@ -908,12 +328,10 @@ version (NetBSD)
///
alias core.stdc.math.sqrtl sqrt;
- ///
- alias core.stdc.complex.csqrt sqrt;
- ///
- alias core.stdc.complex.csqrtf sqrt;
- ///
- alias core.stdc.complex.csqrtl sqrt;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csqrt sqrt;
+ deprecated alias core.stdc.complex.csqrtf sqrt;
+ deprecated alias core.stdc.complex.csqrtl sqrt;
///
alias core.stdc.math.erf erf;
@@ -1087,37 +505,23 @@ version (NetBSD)
///
alias core.stdc.math.fmal fma;
- ///
- alias core.stdc.complex.carg carg;
- ///
- alias core.stdc.complex.cargf carg;
- ///
- alias core.stdc.complex.cargl carg;
-
- ///
- alias core.stdc.complex.cimag cimag;
- ///
- alias core.stdc.complex.cimagf cimag;
- ///
- alias core.stdc.complex.cimagl cimag;
-
- ///
- alias core.stdc.complex.conj conj;
- ///
- alias core.stdc.complex.conjf conj;
- ///
- alias core.stdc.complex.conjl conj;
-
- ///
- alias core.stdc.complex.cproj cproj;
- ///
- alias core.stdc.complex.cprojf cproj;
- ///
- alias core.stdc.complex.cprojl cproj;
-
-// alias core.stdc.complex.creal creal;
-// alias core.stdc.complex.crealf creal;
-// alias core.stdc.complex.creall creal;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.carg carg;
+ deprecated alias core.stdc.complex.cargf carg;
+ deprecated alias core.stdc.complex.cargl carg;
+ deprecated alias core.stdc.complex.cimag cimag;
+ deprecated alias core.stdc.complex.cimagf cimag;
+ deprecated alias core.stdc.complex.cimagl cimag;
+ deprecated alias core.stdc.complex.conj conj;
+ deprecated alias core.stdc.complex.conjf conj;
+ deprecated alias core.stdc.complex.conjl conj;
+ deprecated alias core.stdc.complex.cproj cproj;
+ deprecated alias core.stdc.complex.cprojf cproj;
+ deprecated alias core.stdc.complex.cprojl cproj;
+
+// deprecated alias core.stdc.complex.creal creal;
+// deprecated alias core.stdc.complex.crealf creal;
+// deprecated alias core.stdc.complex.creall creal;
}
else version (OpenBSD)
{
@@ -1128,12 +532,10 @@ else version (OpenBSD)
///
alias core.stdc.math.acosl acos;
- ///
- alias core.stdc.complex.cacos acos;
- ///
- alias core.stdc.complex.cacosf acos;
- ///
- alias core.stdc.complex.cacosl acos;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cacos acos;
+ deprecated alias core.stdc.complex.cacosf acos;
+ deprecated alias core.stdc.complex.cacosl acos;
///
alias core.stdc.math.asin asin;
@@ -1142,12 +544,10 @@ else version (OpenBSD)
///
alias core.stdc.math.asinl asin;
- ///
- alias core.stdc.complex.casin asin;
- ///
- alias core.stdc.complex.casinf asin;
- ///
- alias core.stdc.complex.casinl asin;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.casin asin;
+ deprecated alias core.stdc.complex.casinf asin;
+ deprecated alias core.stdc.complex.casinl asin;
///
alias core.stdc.math.atan atan;
@@ -1156,12 +556,10 @@ else version (OpenBSD)
///
alias core.stdc.math.atanl atan;
- ///
- alias core.stdc.complex.catan atan;
- ///
- alias core.stdc.complex.catanf atan;
- ///
- alias core.stdc.complex.catanl atan;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.catan atan;
+ deprecated alias core.stdc.complex.catanf atan;
+ deprecated alias core.stdc.complex.catanl atan;
///
alias core.stdc.math.atan2 atan2;
@@ -1177,12 +575,10 @@ else version (OpenBSD)
///
alias core.stdc.math.cosl cos;
- ///
- alias core.stdc.complex.ccos cos;
- ///
- alias core.stdc.complex.ccosf cos;
- ///
- alias core.stdc.complex.ccosl cos;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ccos cos;
+ deprecated alias core.stdc.complex.ccosf cos;
+ deprecated alias core.stdc.complex.ccosl cos;
///
alias core.stdc.math.sin sin;
@@ -1191,12 +587,10 @@ else version (OpenBSD)
///
alias core.stdc.math.sinl sin;
- ///
- alias core.stdc.complex.csin csin;
- ///
- alias core.stdc.complex.csinf csin;
- ///
- alias core.stdc.complex.csinl csin;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csin csin;
+ deprecated alias core.stdc.complex.csinf csin;
+ deprecated alias core.stdc.complex.csinl csin;
///
alias core.stdc.math.tan tan;
@@ -1205,12 +599,10 @@ else version (OpenBSD)
///
alias core.stdc.math.tanl tan;
- ///
- alias core.stdc.complex.ctan tan;
- ///
- alias core.stdc.complex.ctanf tan;
- ///
- alias core.stdc.complex.ctanl tan;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ctan tan;
+ deprecated alias core.stdc.complex.ctanf tan;
+ deprecated alias core.stdc.complex.ctanl tan;
///
alias core.stdc.math.acosh acosh;
@@ -1219,12 +611,10 @@ else version (OpenBSD)
///
alias core.stdc.math.acoshl acosh;
- ///
- alias core.stdc.complex.cacosh acosh;
- ///
- alias core.stdc.complex.cacoshf acosh;
- ///
- alias core.stdc.complex.cacoshl acosh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cacosh acosh;
+ deprecated alias core.stdc.complex.cacoshf acosh;
+ deprecated alias core.stdc.complex.cacoshl acosh;
///
alias core.stdc.math.asinh asinh;
@@ -1233,12 +623,10 @@ else version (OpenBSD)
///
alias core.stdc.math.asinhl asinh;
- ///
- alias core.stdc.complex.casinh asinh;
- ///
- alias core.stdc.complex.casinhf asinh;
- ///
- alias core.stdc.complex.casinhl asinh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.casinh asinh;
+ deprecated alias core.stdc.complex.casinhf asinh;
+ deprecated alias core.stdc.complex.casinhl asinh;
///
alias core.stdc.math.atanh atanh;
@@ -1247,12 +635,10 @@ else version (OpenBSD)
///
alias core.stdc.math.atanhl atanh;
- ///
- alias core.stdc.complex.catanh atanh;
- ///
- alias core.stdc.complex.catanhf atanh;
- ///
- alias core.stdc.complex.catanhl atanh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.catanh atanh;
+ deprecated alias core.stdc.complex.catanhf atanh;
+ deprecated alias core.stdc.complex.catanhl atanh;
///
alias core.stdc.math.cosh cosh;
@@ -1261,12 +647,10 @@ else version (OpenBSD)
///
alias core.stdc.math.coshl cosh;
- ///
- alias core.stdc.complex.ccosh cosh;
- ///
- alias core.stdc.complex.ccoshf cosh;
- ///
- alias core.stdc.complex.ccoshl cosh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ccosh cosh;
+ deprecated alias core.stdc.complex.ccoshf cosh;
+ deprecated alias core.stdc.complex.ccoshl cosh;
///
alias core.stdc.math.sinh sinh;
@@ -1275,12 +659,10 @@ else version (OpenBSD)
///
alias core.stdc.math.sinhl sinh;
- ///
- alias core.stdc.complex.csinh sinh;
- ///
- alias core.stdc.complex.csinhf sinh;
- ///
- alias core.stdc.complex.csinhl sinh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csinh sinh;
+ deprecated alias core.stdc.complex.csinhf sinh;
+ deprecated alias core.stdc.complex.csinhl sinh;
///
alias core.stdc.math.tanh tanh;
@@ -1289,12 +671,10 @@ else version (OpenBSD)
///
alias core.stdc.math.tanhl tanh;
- ///
- alias core.stdc.complex.ctanh tanh;
- ///
- alias core.stdc.complex.ctanhf tanh;
- ///
- alias core.stdc.complex.ctanhl tanh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ctanh tanh;
+ deprecated alias core.stdc.complex.ctanhf tanh;
+ deprecated alias core.stdc.complex.ctanhl tanh;
///
alias core.stdc.math.exp exp;
@@ -1303,12 +683,10 @@ else version (OpenBSD)
///
alias core.stdc.math.expl exp;
- ///
- alias core.stdc.complex.cexp exp;
- ///
- alias core.stdc.complex.cexpf exp;
- ///
- alias core.stdc.complex.cexpl exp;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cexp exp;
+ deprecated alias core.stdc.complex.cexpf exp;
+ deprecated alias core.stdc.complex.cexpl exp;
///
alias core.stdc.math.exp2 exp2;
@@ -1352,12 +730,10 @@ else version (OpenBSD)
///
alias core.stdc.math.logl log;
- ///
- alias core.stdc.complex.clog log;
- ///
- alias core.stdc.complex.clogf log;
- ///
- alias core.stdc.complex.clogl log;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.clog log;
+ deprecated alias core.stdc.complex.clogf log;
+ deprecated alias core.stdc.complex.clogl log;
///
alias core.stdc.math.log10 log10;
@@ -1422,12 +798,10 @@ else version (OpenBSD)
///
alias core.stdc.math.fabsl fabs;
- ///
- alias core.stdc.complex.cabs fabs;
- ///
- alias core.stdc.complex.cabsf fabs;
- ///
- alias core.stdc.complex.cabsl fabs;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cabs fabs;
+ deprecated alias core.stdc.complex.cabsf fabs;
+ deprecated alias core.stdc.complex.cabsl fabs;
///
alias core.stdc.math.hypot hypot;
@@ -1443,12 +817,10 @@ else version (OpenBSD)
///
alias core.stdc.math.powl pow;
- ///
- alias core.stdc.complex.cpow pow;
- ///
- alias core.stdc.complex.cpowf pow;
- ///
- alias core.stdc.complex.cpowl pow;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cpow pow;
+ deprecated alias core.stdc.complex.cpowf pow;
+ deprecated alias core.stdc.complex.cpowl pow;
///
alias core.stdc.math.sqrt sqrt;
@@ -1457,12 +829,10 @@ else version (OpenBSD)
///
alias core.stdc.math.sqrtl sqrt;
- ///
- alias core.stdc.complex.csqrt sqrt;
- ///
- alias core.stdc.complex.csqrtf sqrt;
- ///
- alias core.stdc.complex.csqrtl sqrt;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csqrt sqrt;
+ deprecated alias core.stdc.complex.csqrtf sqrt;
+ deprecated alias core.stdc.complex.csqrtl sqrt;
///
alias core.stdc.math.erf erf;
@@ -1625,37 +995,23 @@ else version (OpenBSD)
///
alias core.stdc.math.fmal fma;
- ///
- alias core.stdc.complex.carg carg;
- ///
- alias core.stdc.complex.cargf carg;
- ///
- alias core.stdc.complex.cargl carg;
-
- ///
- alias core.stdc.complex.cimag cimag;
- ///
- alias core.stdc.complex.cimagf cimag;
- ///
- alias core.stdc.complex.cimagl cimag;
-
- ///
- alias core.stdc.complex.conj conj;
- ///
- alias core.stdc.complex.conjf conj;
- ///
- alias core.stdc.complex.conjl conj;
-
- ///
- alias core.stdc.complex.cproj cproj;
- ///
- alias core.stdc.complex.cprojf cproj;
- ///
- alias core.stdc.complex.cprojl cproj;
-
-// alias core.stdc.complex.creal creal;
-// alias core.stdc.complex.crealf creal;
-// alias core.stdc.complex.creall creal;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.carg carg;
+ deprecated alias core.stdc.complex.cargf carg;
+ deprecated alias core.stdc.complex.cargl carg;
+ deprecated alias core.stdc.complex.cimag cimag;
+ deprecated alias core.stdc.complex.cimagf cimag;
+ deprecated alias core.stdc.complex.cimagl cimag;
+ deprecated alias core.stdc.complex.conj conj;
+ deprecated alias core.stdc.complex.conjf conj;
+ deprecated alias core.stdc.complex.conjl conj;
+ deprecated alias core.stdc.complex.cproj cproj;
+ deprecated alias core.stdc.complex.cprojf cproj;
+ deprecated alias core.stdc.complex.cprojl cproj;
+
+// deprecated alias core.stdc.complex.creal creal;
+// deprecated alias core.stdc.complex.crealf creal;
+// deprecated alias core.stdc.complex.creall creal;
}
else
{
@@ -1666,12 +1022,10 @@ else
///
alias core.stdc.math.acosl acos;
- ///
- alias core.stdc.complex.cacos acos;
- ///
- alias core.stdc.complex.cacosf acos;
- ///
- alias core.stdc.complex.cacosl acos;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cacos acos;
+ deprecated alias core.stdc.complex.cacosf acos;
+ deprecated alias core.stdc.complex.cacosl acos;
///
alias core.stdc.math.asin asin;
@@ -1680,12 +1034,10 @@ else
///
alias core.stdc.math.asinl asin;
- ///
- alias core.stdc.complex.casin asin;
- ///
- alias core.stdc.complex.casinf asin;
- ///
- alias core.stdc.complex.casinl asin;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.casin asin;
+ deprecated alias core.stdc.complex.casinf asin;
+ deprecated alias core.stdc.complex.casinl asin;
///
alias core.stdc.math.atan atan;
@@ -1694,12 +1046,10 @@ else
///
alias core.stdc.math.atanl atan;
- ///
- alias core.stdc.complex.catan atan;
- ///
- alias core.stdc.complex.catanf atan;
- ///
- alias core.stdc.complex.catanl atan;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.catan atan;
+ deprecated alias core.stdc.complex.catanf atan;
+ deprecated alias core.stdc.complex.catanl atan;
///
alias core.stdc.math.atan2 atan2;
@@ -1715,12 +1065,10 @@ else
///
alias core.stdc.math.cosl cos;
- ///
- alias core.stdc.complex.ccos cos;
- ///
- alias core.stdc.complex.ccosf cos;
- ///
- alias core.stdc.complex.ccosl cos;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ccos cos;
+ deprecated alias core.stdc.complex.ccosf cos;
+ deprecated alias core.stdc.complex.ccosl cos;
///
alias core.stdc.math.sin sin;
@@ -1729,12 +1077,10 @@ else
///
alias core.stdc.math.sinl sin;
- ///
- alias core.stdc.complex.csin csin;
- ///
- alias core.stdc.complex.csinf csin;
- ///
- alias core.stdc.complex.csinl csin;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csin csin;
+ deprecated alias core.stdc.complex.csinf csin;
+ deprecated alias core.stdc.complex.csinl csin;
///
alias core.stdc.math.tan tan;
@@ -1743,12 +1089,10 @@ else
///
alias core.stdc.math.tanl tan;
- ///
- alias core.stdc.complex.ctan tan;
- ///
- alias core.stdc.complex.ctanf tan;
- ///
- alias core.stdc.complex.ctanl tan;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ctan tan;
+ deprecated alias core.stdc.complex.ctanf tan;
+ deprecated alias core.stdc.complex.ctanl tan;
///
alias core.stdc.math.acosh acosh;
@@ -1757,12 +1101,10 @@ else
///
alias core.stdc.math.acoshl acosh;
- ///
- alias core.stdc.complex.cacosh acosh;
- ///
- alias core.stdc.complex.cacoshf acosh;
- ///
- alias core.stdc.complex.cacoshl acosh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cacosh acosh;
+ deprecated alias core.stdc.complex.cacoshf acosh;
+ deprecated alias core.stdc.complex.cacoshl acosh;
///
alias core.stdc.math.asinh asinh;
@@ -1771,12 +1113,10 @@ else
///
alias core.stdc.math.asinhl asinh;
- ///
- alias core.stdc.complex.casinh asinh;
- ///
- alias core.stdc.complex.casinhf asinh;
- ///
- alias core.stdc.complex.casinhl asinh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.casinh asinh;
+ deprecated alias core.stdc.complex.casinhf asinh;
+ deprecated alias core.stdc.complex.casinhl asinh;
///
alias core.stdc.math.atanh atanh;
@@ -1785,12 +1125,10 @@ else
///
alias core.stdc.math.atanhl atanh;
- ///
- alias core.stdc.complex.catanh atanh;
- ///
- alias core.stdc.complex.catanhf atanh;
- ///
- alias core.stdc.complex.catanhl atanh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.catanh atanh;
+ deprecated alias core.stdc.complex.catanhf atanh;
+ deprecated alias core.stdc.complex.catanhl atanh;
///
alias core.stdc.math.cosh cosh;
@@ -1799,12 +1137,10 @@ else
///
alias core.stdc.math.coshl cosh;
- ///
- alias core.stdc.complex.ccosh cosh;
- ///
- alias core.stdc.complex.ccoshf cosh;
- ///
- alias core.stdc.complex.ccoshl cosh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ccosh cosh;
+ deprecated alias core.stdc.complex.ccoshf cosh;
+ deprecated alias core.stdc.complex.ccoshl cosh;
///
alias core.stdc.math.sinh sinh;
@@ -1813,12 +1149,10 @@ else
///
alias core.stdc.math.sinhl sinh;
- ///
- alias core.stdc.complex.csinh sinh;
- ///
- alias core.stdc.complex.csinhf sinh;
- ///
- alias core.stdc.complex.csinhl sinh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csinh sinh;
+ deprecated alias core.stdc.complex.csinhf sinh;
+ deprecated alias core.stdc.complex.csinhl sinh;
///
alias core.stdc.math.tanh tanh;
@@ -1827,12 +1161,10 @@ else
///
alias core.stdc.math.tanhl tanh;
- ///
- alias core.stdc.complex.ctanh tanh;
- ///
- alias core.stdc.complex.ctanhf tanh;
- ///
- alias core.stdc.complex.ctanhl tanh;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.ctanh tanh;
+ deprecated alias core.stdc.complex.ctanhf tanh;
+ deprecated alias core.stdc.complex.ctanhl tanh;
///
alias core.stdc.math.exp exp;
@@ -1841,12 +1173,10 @@ else
///
alias core.stdc.math.expl exp;
- ///
- alias core.stdc.complex.cexp exp;
- ///
- alias core.stdc.complex.cexpf exp;
- ///
- alias core.stdc.complex.cexpl exp;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cexp exp;
+ deprecated alias core.stdc.complex.cexpf exp;
+ deprecated alias core.stdc.complex.cexpl exp;
///
alias core.stdc.math.exp2 exp2;
@@ -1890,12 +1220,10 @@ else
///
alias core.stdc.math.logl log;
- ///
- alias core.stdc.complex.clog log;
- ///
- alias core.stdc.complex.clogf log;
- ///
- alias core.stdc.complex.clogl log;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.clog log;
+ deprecated alias core.stdc.complex.clogf log;
+ deprecated alias core.stdc.complex.clogl log;
///
alias core.stdc.math.log10 log10;
@@ -1957,6 +1285,13 @@ else
alias core.stdc.math.fabs fabs;
version (CRuntime_Microsoft)
{
+ version (MinGW)
+ {
+ ///
+ alias core.stdc.math.fabsf fabs;
+ ///
+ alias core.stdc.math.fabsl fabs;
+ }
}
else
{
@@ -1966,12 +1301,10 @@ else
alias core.stdc.math.fabsl fabs;
}
- ///
- alias core.stdc.complex.cabs fabs;
- ///
- alias core.stdc.complex.cabsf fabs;
- ///
- alias core.stdc.complex.cabsl fabs;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cabs fabs;
+ deprecated alias core.stdc.complex.cabsf fabs;
+ deprecated alias core.stdc.complex.cabsl fabs;
///
alias core.stdc.math.hypot hypot;
@@ -1987,12 +1320,10 @@ else
///
alias core.stdc.math.powl pow;
- ///
- alias core.stdc.complex.cpow pow;
- ///
- alias core.stdc.complex.cpowf pow;
- ///
- alias core.stdc.complex.cpowl pow;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.cpow pow;
+ deprecated alias core.stdc.complex.cpowf pow;
+ deprecated alias core.stdc.complex.cpowl pow;
///
alias core.stdc.math.sqrt sqrt;
@@ -2001,12 +1332,10 @@ else
///
alias core.stdc.math.sqrtl sqrt;
- ///
- alias core.stdc.complex.csqrt sqrt;
- ///
- alias core.stdc.complex.csqrtf sqrt;
- ///
- alias core.stdc.complex.csqrtl sqrt;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.csqrt sqrt;
+ deprecated alias core.stdc.complex.csqrtf sqrt;
+ deprecated alias core.stdc.complex.csqrtl sqrt;
///
alias core.stdc.math.erf erf;
@@ -2183,35 +1512,20 @@ else
///
alias core.stdc.math.fmal fma;
- ///
- alias core.stdc.complex.carg carg;
- ///
- alias core.stdc.complex.cargf carg;
- ///
- alias core.stdc.complex.cargl carg;
-
- ///
- alias core.stdc.complex.cimag cimag;
- ///
- alias core.stdc.complex.cimagf cimag;
- ///
- alias core.stdc.complex.cimagl cimag;
-
- ///
- alias core.stdc.complex.conj conj;
- ///
- alias core.stdc.complex.conjf conj;
- ///
- alias core.stdc.complex.conjl conj;
-
- ///
- alias core.stdc.complex.cproj cproj;
- ///
- alias core.stdc.complex.cprojf cproj;
- ///
- alias core.stdc.complex.cprojl cproj;
-
-// alias core.stdc.complex.creal creal;
-// alias core.stdc.complex.crealf creal;
-// alias core.stdc.complex.creall creal;
+ // @@@DEPRECATED_2.105@@@
+ deprecated alias core.stdc.complex.carg carg;
+ deprecated alias core.stdc.complex.cargf carg;
+ deprecated alias core.stdc.complex.cargl carg;
+ deprecated alias core.stdc.complex.cimag cimag;
+ deprecated alias core.stdc.complex.cimagf cimag;
+ deprecated alias core.stdc.complex.cimagl cimag;
+ deprecated alias core.stdc.complex.conj conj;
+ deprecated alias core.stdc.complex.conjf conj;
+ deprecated alias core.stdc.complex.conjl conj;
+ deprecated alias core.stdc.complex.cproj cproj;
+ deprecated alias core.stdc.complex.cprojf cproj;
+ deprecated alias core.stdc.complex.cprojl cproj;
+// deprecated alias core.stdc.complex.creal creal;
+// deprecated alias core.stdc.complex.crealf creal;
+// deprecated alias core.stdc.complex.creall creal;
}
diff --git a/libphobos/libdruntime/core/stdc/time.d b/libphobos/libdruntime/core/stdc/time.d
index 4a571e1..b19c3c7 100644
--- a/libphobos/libdruntime/core/stdc/time.d
+++ b/libphobos/libdruntime/core/stdc/time.d
@@ -15,138 +15,20 @@
module core.stdc.time;
-private import core.stdc.config;
+version (Posix)
+ public import core.sys.posix.stdc.time;
+else version (Windows)
+ public import core.sys.windows.stdc.time;
+else
+ static assert(0, "unsupported system");
-version (OSX)
- version = Darwin;
-else version (iOS)
- version = Darwin;
-else version (TVOS)
- version = Darwin;
-else version (WatchOS)
- version = Darwin;
+import core.stdc.config;
extern (C):
@trusted: // There are only a few functions here that use unsafe C strings.
nothrow:
@nogc:
-version (Windows)
-{
- ///
- struct tm
- {
- int tm_sec; /// seconds after the minute - [0, 60]
- int tm_min; /// minutes after the hour - [0, 59]
- int tm_hour; /// hours since midnight - [0, 23]
- int tm_mday; /// day of the month - [1, 31]
- int tm_mon; /// months since January - [0, 11]
- int tm_year; /// years since 1900
- int tm_wday; /// days since Sunday - [0, 6]
- int tm_yday; /// days since January 1 - [0, 365]
- int tm_isdst; /// Daylight Saving Time flag
- }
-}
-else version (Posix)
-{
- ///
- struct tm
- {
- int tm_sec; /// seconds after the minute [0-60]
- int tm_min; /// minutes after the hour [0-59]
- int tm_hour; /// hours since midnight [0-23]
- int tm_mday; /// day of the month [1-31]
- int tm_mon; /// months since January [0-11]
- int tm_year; /// years since 1900
- int tm_wday; /// days since Sunday [0-6]
- int tm_yday; /// days since January 1 [0-365]
- int tm_isdst; /// Daylight Savings Time flag
- c_long tm_gmtoff; /// offset from CUT in seconds
- char* tm_zone; /// timezone abbreviation
- }
-}
-
-version (Posix)
-{
- public import core.sys.posix.sys.types : time_t, clock_t;
-}
-else version (Windows)
-{
- ///
- alias c_long time_t;
- ///
- alias c_long clock_t;
-}
-
-///
-version (Windows)
-{
- enum clock_t CLOCKS_PER_SEC = 1000;
- clock_t clock();
-}
-else version (OSX)
-{
- enum clock_t CLOCKS_PER_SEC = 1_000_000; // was 100 until OSX 10.4/10.5
- version (X86)
- extern (C) pragma(mangle, "clock$UNIX2003") clock_t clock();
- else
- clock_t clock();
-}
-else version (Darwin) // other Darwins (iOS, TVOS, WatchOS)
-{
- enum clock_t CLOCKS_PER_SEC = 1_000_000;
- clock_t clock();
-}
-else version (FreeBSD)
-{
- enum clock_t CLOCKS_PER_SEC = 128;
- clock_t clock();
-}
-else version (NetBSD)
-{
- enum clock_t CLOCKS_PER_SEC = 100;
- clock_t clock();
-}
-else version (OpenBSD)
-{
- enum clock_t CLOCKS_PER_SEC = 100;
- clock_t clock();
-}
-else version (DragonFlyBSD)
-{
- enum clock_t CLOCKS_PER_SEC = 128;
- clock_t clock();
-}
-else version (Solaris)
-{
- enum clock_t CLOCKS_PER_SEC = 1_000_000;
- clock_t clock();
-}
-else version (CRuntime_Glibc)
-{
- enum clock_t CLOCKS_PER_SEC = 1_000_000;
- clock_t clock();
-}
-else version (CRuntime_Musl)
-{
- enum clock_t CLOCKS_PER_SEC = 1_000_000;
- clock_t clock();
-}
-else version (CRuntime_Bionic)
-{
- enum clock_t CLOCKS_PER_SEC = 1_000_000;
- clock_t clock();
-}
-else version (CRuntime_UClibc)
-{
- enum clock_t CLOCKS_PER_SEC = 1_000_000;
- clock_t clock();
-}
-else
-{
- static assert(0, "unsupported system");
-}
-
///
pure double difftime(time_t time1, time_t time0); // MT-Safe
///
@@ -164,92 +46,3 @@ time_t time(scope time_t* timer);
@system tm* localtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale
///
@system size_t strftime(scope char* s, size_t maxsize, const scope char* format, const scope tm* timeptr); // @system: MT-Safe env locale
-
-version (Windows)
-{
- ///
- void tzset(); // non-standard
- ///
- void _tzset(); // non-standard
- ///
- @system char* _strdate(return scope char* s); // non-standard
- ///
- @system char* _strtime(return scope char* s); // non-standard
-
- ///
- extern __gshared const(char)*[2] tzname; // non-standard
-}
-else version (Darwin)
-{
- ///
- void tzset(); // non-standard
- ///
- extern __gshared const(char)*[2] tzname; // non-standard
-}
-else version (CRuntime_Glibc)
-{
- ///
- void tzset(); // non-standard
- ///
- extern __gshared const(char)*[2] tzname; // non-standard
-}
-else version (FreeBSD)
-{
- ///
- void tzset(); // non-standard
- ///
- extern __gshared const(char)*[2] tzname; // non-standard
-}
-else version (NetBSD)
-{
- ///
- void tzset(); // non-standard
- ///
- extern __gshared const(char)*[2] tzname; // non-standard
-}
-else version (OpenBSD)
-{
- ///
- void tzset(); // non-standard
- ///
- extern __gshared const(char)*[2] tzname; // non-standard
-}
-else version (DragonFlyBSD)
-{
- ///
- void tzset(); // non-standard
- ///
- extern __gshared const(char)*[2] tzname; // non-standard
-}
-else version (Solaris)
-{
- ///
- void tzset();
- ///
- extern __gshared const(char)*[2] tzname;
-}
-else version (CRuntime_Bionic)
-{
- ///
- void tzset();
- ///
- extern __gshared const(char)*[2] tzname;
-}
-else version (CRuntime_Musl)
-{
- ///
- void tzset(); // non-standard
- ///
- extern __gshared const(char)*[2] tzname; // non-standard
-}
-else version (CRuntime_UClibc)
-{
- ///
- void tzset();
- ///
- extern __gshared const(char)*[2] tzname;
-}
-else
-{
- static assert(false, "Unsupported platform");
-}
diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d
index 1cf8678..6da5618 100644
--- a/libphobos/libdruntime/core/stdc/wchar_.d
+++ b/libphobos/libdruntime/core/stdc/wchar_.d
@@ -12,14 +12,11 @@
* Standards: ISO/IEC 9899:1999 (E)
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module core.stdc.wchar_;
-private import core.stdc.config;
-private import core.stdc.stdarg; // for va_list
-private import core.stdc.stdio; // for FILE, not exposed per spec
+import core.stdc.config;
+import core.stdc.stdarg; // for va_list
+import core.stdc.stdio; // for FILE, not exposed per spec
public import core.stdc.stddef; // for wchar_t
public import core.stdc.time; // for tm
public import core.stdc.stdint; // for WCHAR_MIN, WCHAR_MAX
@@ -131,44 +128,29 @@ alias wchar_t wint_t;
enum wchar_t WEOF = 0xFFFF;
///
-int fwprintf(FILE* stream, in wchar_t* format, ...);
+int fwprintf(FILE* stream, const scope wchar_t* format, scope const ...);
///
-int fwscanf(FILE* stream, in wchar_t* format, ...);
-int swscanf(in wchar_t* s, in wchar_t* format, ...);
+int fwscanf(FILE* stream, const scope wchar_t* format, scope ...);
///
-int vfwprintf(FILE* stream, in wchar_t* format, va_list arg);
+int swprintf(wchar_t* s, size_t n, const scope wchar_t* format, scope const ...);
///
-int vfwscanf(FILE* stream, in wchar_t* format, va_list arg);
-int vswscanf(in wchar_t* s, in wchar_t* format, va_list arg);
+int swscanf(const scope wchar_t* s, const scope wchar_t* format, scope ...);
///
-int vwprintf(in wchar_t* format, va_list arg);
+int vfwprintf(FILE* stream, const scope wchar_t* format, va_list arg);
///
-int vwscanf(in wchar_t* format, va_list arg);
+int vfwscanf(FILE* stream, const scope wchar_t* format, va_list arg);
///
-int wprintf(in wchar_t* format, ...);
+int vswprintf(wchar_t* s, size_t n, const scope wchar_t* format, va_list arg);
///
-int wscanf(in wchar_t* format, ...);
-
-/*
- * Windows has 2 versions of swprintf and vswprintf. MinGW defaults to the
- * Microsoft signature. Alias to match DMD/ANSI signature.
- */
-version (MinGW)
-{
- ///
- int _snwprintf(wchar_t* s, size_t n, in wchar_t* format, ...);
- alias _snwprintf swprintf;
- ///
- int _vsnwprintf(wchar_t* s, size_t n, in wchar_t* format, va_list arg);
- alias _vsnwprintf vswprintf;
-}
-else
-{
- ///
- int swprintf(wchar_t* s, size_t n, in wchar_t* format, ...);
- ///
- int vswprintf(wchar_t* s, size_t n, in wchar_t* format, va_list arg);
-}
+int vswscanf(const scope wchar_t* s, const scope wchar_t* format, va_list arg);
+///
+int vwprintf(const scope wchar_t* format, va_list arg);
+///
+int vwscanf(const scope wchar_t* format, va_list arg);
+///
+int wprintf(const scope wchar_t* format, scope const ...);
+///
+int wscanf(const scope wchar_t* format, scope ...);
// No unsafe pointer manipulation.
@trusted
@@ -182,7 +164,7 @@ else
///
wchar_t* fgetws(wchar_t* s, int n, FILE* stream);
///
-int fputws(in wchar_t* s, FILE* stream);
+int fputws(const scope wchar_t* s, FILE* stream);
// No unsafe pointer manipulation.
extern (D) @trusted
@@ -191,12 +173,13 @@ extern (D) @trusted
wint_t getwchar() { return fgetwc(stdin); }
///
wint_t putwchar(wchar_t c) { return fputwc(c,stdout); }
- ///
- wint_t getwc(FILE* stream) { return fgetwc(stream); }
- ///
- wint_t putwc(wchar_t c, FILE* stream) { return fputwc(c, stream); }
}
+///
+alias getwc = fgetwc;
+///
+alias putwc = fputwc;
+
// No unsafe pointer manipulation.
@trusted
{
@@ -215,19 +198,19 @@ extern (D) @trusted
}
///
-double wcstod(in wchar_t* nptr, wchar_t** endptr);
+double wcstod(const scope wchar_t* nptr, wchar_t** endptr);
///
-float wcstof(in wchar_t* nptr, wchar_t** endptr);
+float wcstof(const scope wchar_t* nptr, wchar_t** endptr);
///
-real wcstold(in wchar_t* nptr, wchar_t** endptr);
+real wcstold(const scope wchar_t* nptr, wchar_t** endptr);
///
-c_long wcstol(in wchar_t* nptr, wchar_t** endptr, int base);
+c_long wcstol(const scope wchar_t* nptr, wchar_t** endptr, int base);
///
-long wcstoll(in wchar_t* nptr, wchar_t** endptr, int base);
+long wcstoll(const scope wchar_t* nptr, wchar_t** endptr, int base);
///
-c_ulong wcstoul(in wchar_t* nptr, wchar_t** endptr, int base);
+c_ulong wcstoul(const scope wchar_t* nptr, wchar_t** endptr, int base);
///
-ulong wcstoull(in wchar_t* nptr, wchar_t** endptr, int base);
+ulong wcstoull(const scope wchar_t* nptr, wchar_t** endptr, int base);
///
pure wchar_t* wcscpy(return wchar_t* s1, scope const wchar_t* s2);
@@ -263,7 +246,7 @@ wchar_t* wcstok(return wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr);
pure size_t wcslen(scope const wchar_t* s);
///
-pure wchar_t* wmemchr(return const wchar_t* s, wchar_t c, size_t n);
+pure inout(wchar_t)* wmemchr(return inout wchar_t* s, wchar_t c, size_t n);
///
pure int wmemcmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n);
///
@@ -274,7 +257,7 @@ pure wchar_t* wmemmove(return wchar_t* s1, scope const wchar_t* s2, size_t n);
pure wchar_t* wmemset(return wchar_t* s, wchar_t c, size_t n);
///
-size_t wcsftime(wchar_t* s, size_t maxsize, in wchar_t* format, in tm* timeptr);
+size_t wcsftime(wchar_t* s, size_t maxsize, const scope wchar_t* format, const scope tm* timeptr);
version (Windows)
{
@@ -298,14 +281,14 @@ version (Windows)
}
///
-int mbsinit(in mbstate_t* ps);
+int mbsinit(const scope mbstate_t* ps);
///
-size_t mbrlen(in char* s, size_t n, mbstate_t* ps);
+size_t mbrlen(const scope char* s, size_t n, mbstate_t* ps);
///
-size_t mbrtowc(wchar_t* pwc, in char* s, size_t n, mbstate_t* ps);
+size_t mbrtowc(wchar_t* pwc, const scope char* s, size_t n, mbstate_t* ps);
///
size_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps);
///
-size_t mbsrtowcs(wchar_t* dst, in char** src, size_t len, mbstate_t* ps);
+size_t mbsrtowcs(wchar_t* dst, const scope char** src, size_t len, mbstate_t* ps);
///
-size_t wcsrtombs(char* dst, in wchar_t** src, size_t len, mbstate_t* ps);
+size_t wcsrtombs(char* dst, const scope wchar_t** src, size_t len, mbstate_t* ps);
diff --git a/libphobos/libdruntime/core/stdc/wctype.d b/libphobos/libdruntime/core/stdc/wctype.d
index b0c8107..b37e832 100644
--- a/libphobos/libdruntime/core/stdc/wctype.d
+++ b/libphobos/libdruntime/core/stdc/wctype.d
@@ -54,7 +54,7 @@ pure int iswxdigit(wint_t wc);
///
int iswctype(wint_t wc, wctype_t desc);
///
-@system wctype_t wctype(in char* property);
+@system wctype_t wctype(const scope char* property);
///
pure wint_t towlower(wint_t wc);
///
@@ -62,4 +62,4 @@ pure wint_t towupper(wint_t wc);
///
wint_t towctrans(wint_t wc, wctrans_t desc);
///
-@system wctrans_t wctrans(in char* property);
+@system wctrans_t wctrans(const scope char* property);
diff --git a/libphobos/libdruntime/core/sys/bionic/err.d b/libphobos/libdruntime/core/sys/bionic/err.d
new file mode 100644
index 0000000..e2756e1
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/bionic/err.d
@@ -0,0 +1,23 @@
+/**
+ * D header file for Bionic err.h.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Ernesto Castellotti
+ */
+module core.sys.bionic.err;
+import core.stdc.stdarg : va_list;
+
+version (CRuntime_Bionic):
+extern (C):
+nothrow:
+@nogc:
+
+void err(int eval, scope const char* fmt, ...);
+void errx(int eval, scope const char* fmt, ...);
+void warn(scope const char* fmt, ...);
+void warnx(scope const char* fmt, ...);
+void verr(int eval, scope const char* fmt, va_list args);
+void verrx(int eval, scope const char* fmt, va_list args);
+void vwarn(scope const char* fmt, va_list args);
+void vwarnx(scope const char* fmt, va_list args);
diff --git a/libphobos/libdruntime/core/sys/bionic/stdlib.d b/libphobos/libdruntime/core/sys/bionic/stdlib.d
new file mode 100644
index 0000000..46fabe5
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/bionic/stdlib.d
@@ -0,0 +1,17 @@
+/**
+ * D header file for Bionic stdlib.h.
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.bionic.stdlib;
+public import core.sys.posix.stdlib;
+
+version (CRuntime_Bionic):
+extern (C):
+nothrow:
+@nogc:
+
+const(char)* getprogname();
+void setprogname(scope const char* name);
diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d
new file mode 100644
index 0000000..87f3fd4
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/config.d
@@ -0,0 +1,53 @@
+/**
+ * D header file for Darwin.
+ *
+ * Copyright: Copyright (c) 2021 D Language Foundation
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.config;
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (Darwin):
+
+public import core.sys.posix.config;
+
+enum __MAC_10_0 = 100000;
+enum __MAC_10_1 = 100100;
+enum __MAC_10_2 = 100200;
+enum __MAC_10_3 = 100300;
+enum __MAC_10_4 = 100400;
+enum __MAC_10_5 = 100500;
+enum __MAC_10_6 = 100600;
+enum __MAC_10_7 = 100700;
+enum __MAC_10_8 = 100800;
+enum __MAC_10_9 = 100900;
+enum __MAC_10_10 = 101000;
+enum __MAC_10_10_2 = 101002;
+enum __MAC_10_10_3 = 101003;
+enum __MAC_10_11 = 101100;
+enum __MAC_10_11_2 = 101102;
+enum __MAC_10_11_3 = 101103;
+enum __MAC_10_11_4 = 101104;
+enum __MAC_10_12 = 101200;
+enum __MAC_10_12_1 = 101201;
+enum __MAC_10_12_2 = 101202;
+enum __MAC_10_12_4 = 101204;
+enum __MAC_10_13 = 101300;
+enum __MAC_10_13_1 = 101301;
+enum __MAC_10_13_2 = 101302;
+enum __MAC_10_13_4 = 101304;
+enum __MAC_10_14 = 101400;
+enum __MAC_10_14_1 = 101401;
+enum __MAC_10_14_4 = 101404;
+enum __MAC_10_15 = 101500;
+enum __MAC_10_15_1 = 101501;
+enum __MAC_10_16 = 101501;
+enum __MAC_11_0 = 110000;
diff --git a/libphobos/libdruntime/core/sys/darwin/dlfcn.d b/libphobos/libdruntime/core/sys/darwin/dlfcn.d
index c22424f..a38d900 100644
--- a/libphobos/libdruntime/core/sys/darwin/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/darwin/dlfcn.d
@@ -33,7 +33,7 @@ struct Dl_info
void* dli_saddr;
}
-int dladdr(in void* addr, Dl_info* info);
+int dladdr(const scope void* addr, Dl_info* info);
enum RTLD_NOLOAD = 0x10;
enum RTLD_NODELETE = 0x80;
diff --git a/libphobos/libdruntime/core/sys/darwin/err.d b/libphobos/libdruntime/core/sys/darwin/err.d
new file mode 100644
index 0000000..d96c790
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/err.d
@@ -0,0 +1,41 @@
+/**
+ * D header file for Darwin err.h.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Ernesto Castellotti
+ */
+module core.sys.darwin.err;
+import core.stdc.stdarg : va_list;
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+
+version (Darwin):
+extern (C):
+nothrow:
+@nogc:
+
+alias ExitFunction = void function(int);
+
+void err(int eval, scope const char* fmt, ...);
+void errc(int eval, int code, scope const char* fmt, ...);
+void errx(int eval, scope const char* fmt, ...);
+void warn(scope const char* fmt, ...);
+void warnc(int code, scope const char* fmt, ...);
+void warnx(scope const char* fmt, ...);
+void verr(int eval, scope const char* fmt, va_list args);
+void verrc(int eval, int code, scope const char* fmt, va_list args);
+void verrx(int eval, scope const char* fmt, va_list args);
+void vwarn(scope const char* fmt, va_list args);
+void vwarnc(int code, scope const char* fmt, va_list args);
+void vwarnx(scope const char* fmt, va_list args);
+void err_set_file(void* vfp);
+void err_set_exit(ExitFunction exitf);
diff --git a/libphobos/libdruntime/core/sys/darwin/fcntl.d b/libphobos/libdruntime/core/sys/darwin/fcntl.d
new file mode 100644
index 0000000..47d895a
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/fcntl.d
@@ -0,0 +1,20 @@
+module core.sys.darwin.fcntl;
+
+public import core.sys.posix.fcntl;
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (Darwin):
+extern (C):
+nothrow:
+@nogc:
+@system:
+
+enum F_FULLFSYNC = 51;
diff --git a/libphobos/libdruntime/core/sys/darwin/ifaddrs.d b/libphobos/libdruntime/core/sys/darwin/ifaddrs.d
new file mode 100644
index 0000000..a254036
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/ifaddrs.d
@@ -0,0 +1,77 @@
+/*******************************************************************************
+
+ Binding for Mac OSX's <ifaddr.h>, expose network interface addresses
+
+ The following functions are present as of Mac OSX 10.15:
+ - getifaddrs(3): get interface addresses
+ - freeifaddrs(3): deallocates the return value of `getifaddrs`
+ - getifmaddrs(3): get multicast group membership
+ - freeifmaddrs(3): deallocates the return value of `getifmaddrs`
+
+ Copyright: Copyright © 2020, The D Language Foundation
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: Daniel Graczer
+
+*******************************************************************************/
+
+module core.sys.darwin.ifaddrs;
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (Darwin):
+extern (C):
+nothrow:
+@nogc:
+@system:
+
+import core.sys.posix.sys.socket;
+
+///
+struct ifaddrs
+{
+ /// Next item in the list
+ ifaddrs* ifa_next;
+ /// Name of the interface
+ char* ifa_name;
+ /// Flags from SIOCGIFFLAGS
+ uint ifa_flags;
+ /// Address of interface
+ sockaddr* ifa_addr;
+ /// Netmask of interface
+ sockaddr* ifa_netmask;
+ /// Point-to-point destination addresss
+ sockaddr* if_dstaddr;
+ /// Address specific data
+ void* ifa_data;
+}
+
+/// Returns: linked list of ifaddrs structures describing interfaces
+int getifaddrs(ifaddrs**);
+/// Frees the linked list returned by getifaddrs
+void freeifaddrs(ifaddrs*);
+
+///
+struct ifmaddrs
+{
+ /// Pointer to next struct
+ ifmaddrs* ifma_next;
+ /// Interface name (AF_LINK)
+ sockaddr* ifma_name;
+ /// Multicast address
+ sockaddr* ifma_addr;
+ /// Link-layer translation, if any
+ sockaddr* ifma_lladdr;
+}
+
+/// Stores a reference to a linked list of the multicast memberships
+/// on the local machine in the memory referenced by ifmaddrs
+int getifmaddrs(ifmaddrs**);
+/// Frees the list allocated by getifmaddrs
+void freeifmaddrs(ifmaddrs*);
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
index 5bf5609..6e28bfa 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/dyld.d
@@ -33,7 +33,10 @@ uint _dyld_image_count();
const(char)* _dyld_get_image_name(uint image_index);
mach_header* _dyld_get_image_header(uint image_index);
intptr_t _dyld_get_image_vmaddr_slide(uint image_index);
-void _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
-void _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));
+void _dyld_register_func_for_add_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
+void _dyld_register_func_for_remove_image(void function(const scope mach_header* mh, intptr_t vmaddr_slide));
+int NSVersionOfRunTimeLibrary(const char* libraryPath);
+int NSVersionOfLinkTimeLibrary(const char* libraryPath);
+int _NSGetExecutablePath(char* buf, uint* bufsize);
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
index cf89747..fd1a8e4 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
@@ -44,7 +44,7 @@ version (CoreDdoc)
* Returns the section data of the given section in the given segment in the
* mach executable it is linked into.
*
- * ___
+ * ---
* void main()
* {
* import core.sys.darwin.mach.getsect;
@@ -52,7 +52,7 @@ version (CoreDdoc)
* assert(getsectdata("__TEXT", "__text", &size));
* assert(size > 0);
* }
- * ___
+ * ---
*
* Params:
* segname = the name of the segment
@@ -63,8 +63,8 @@ version (CoreDdoc)
* Returns: a pointer to the section data or `null` if it doesn't exist
*/
char* getsectdata(
- in char* segname,
- in char* sectname,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong *size
);
@@ -74,7 +74,7 @@ version (CoreDdoc)
* Returns the section data of the given section in the given segment in the
* given framework.
*
- * ___
+ * ---
* void main()
* {
* import core.sys.darwin.mach.getsect;
@@ -82,7 +82,7 @@ version (CoreDdoc)
* assert(getsectdatafromFramework("Foundation", "__TEXT", "__text", &size));
* assert(size > 0);
* }
- * ___
+ * ---
*
* Params:
* FrameworkName = the name of the framework to get the section data from
@@ -94,9 +94,9 @@ version (CoreDdoc)
* Returns: a pointer to the section data or `null` if it doesn't exist
*/
char* getsectdatafromFramework(
- in char* FrameworkName,
- in char* segname,
- in char* sectname,
+ const scope char* FrameworkName,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
@@ -115,13 +115,13 @@ version (CoreDdoc)
* Returns the section structure of the given section in the given segment
* in the mach executable it is linked into.
*
- * ___
+ * ---
* void main()
* {
* import core.sys.darwin.mach.getsect;
* assert(getsectbyname("__TEXT", "__text"));
* }
- * ___
+ * ---
*
* Params:
* segname = the name of the segment
@@ -130,8 +130,8 @@ version (CoreDdoc)
* Returns: a pointer to the section structure or `null` if it doesn't exist
*/
const(Section)* getsectbyname(
- in char* segname,
- in char* sectname
+ const scope char* segname,
+ const scope char* sectname
);
/**
@@ -140,7 +140,7 @@ version (CoreDdoc)
* Returns the section data of the given section in the given segment in the
* image pointed to by the given mach header.
*
- * ___
+ * ---
* void main()
* {
* import core.sys.darwin.mach.getsect;
@@ -151,7 +151,7 @@ version (CoreDdoc)
* assert(getsectdata(mph, "__TEXT", "__text", &size));
* assert(size > 0);
* }
- * ___
+ * ---
*
* Params:
* mhp = the mach header to get the section data from
@@ -163,9 +163,9 @@ version (CoreDdoc)
* Returns: a pointer to the section data or `null` if it doesn't exist
*/
ubyte* getsectiondata(
- in MachHeader* mhp,
- in char* segname,
- in char* sectname,
+ const scope MachHeader* mhp,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
@@ -175,13 +175,13 @@ version (CoreDdoc)
* Returns the segment structure of the given segment in the mach executable
* it is linked into.
*
- * ___
+ * ---
* void main()
* {
* import core.sys.darwin.mach.getsect;
* assert(getsegbyname("__TEXT"));
* }
- * ___
+ * ---
*
* Params:
* segname = the name of the segment
@@ -189,7 +189,7 @@ version (CoreDdoc)
* Returns: a pointer to the section structure or `null` if it doesn't exist
*/
const(SegmentCommand)* getsegbyname(
- in char* segname
+ const scope char* segname
);
/**
@@ -198,7 +198,7 @@ version (CoreDdoc)
* Returns the segment data of the given segment in the image pointed to by
* the given mach header.
*
- * ___
+ * ---
* void main()
* {
* import core.sys.darwin.mach.getsect;
@@ -209,7 +209,7 @@ version (CoreDdoc)
* assert(getsegmentdata(mph, "__TEXT", &size));
* assert(size > 0);
* }
- * ___
+ * ---
*
* Params:
* mhp = the mach header to get the section data from
@@ -220,8 +220,8 @@ version (CoreDdoc)
* Returns: a pointer to the section data or `null` if it doesn't exist
*/
ubyte* getsegmentdata(
- in MachHeader* mhp,
- in char* segname,
+ const scope MachHeader* mhp,
+ const scope char* segname,
c_ulong* size
);
@@ -236,7 +236,7 @@ version (CoreDdoc)
* Returns the section data of the given section in the given segment in the
* image pointed to by the given mach header.
*
- * ___
+ * ---
* void main()
* {
* import core.sys.darwin.mach.getsect;
@@ -247,7 +247,7 @@ version (CoreDdoc)
* assert(getsectdatafromheader(mph, "__TEXT", "__text", &size));
* assert(size > 0);
* }
- * ___
+ * ---
*
* Params:
* mhp = the mach header to get the section data from
@@ -259,17 +259,17 @@ version (CoreDdoc)
* Returns: a pointer to the section data or `null` if it doesn't exist
*/
ubyte* getsectdatafromheader(
- in mach_header* mhp,
- in char* segname,
- in char* sectname,
+ const scope mach_header* mhp,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
/// ditto
ubyte* getsectdatafromheader_64(
- in mach_header_64* mhp,
- in char* segname,
- in char* sectname,
+ const scope mach_header_64* mhp,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
@@ -280,7 +280,7 @@ version (CoreDdoc)
* Returns the section structure of the given section in the given segment
* in image pointed to by the given mach header.
*
- * ___
+ * ---
* void main()
* {
* import core.sys.darwin.mach.getsect;
@@ -289,7 +289,7 @@ version (CoreDdoc)
* auto mph = _NSGetMachExecuteHeader();
* assert(getsectbynamefromheader(mph, "__TEXT", "__text"));
* }
- * ___
+ * ---
*
* Params:
* mhp = the mach header to get the section from
@@ -299,16 +299,16 @@ version (CoreDdoc)
* Returns: a pointer to the section structure or `null` if it doesn't exist
*/
const(section)* getsectbynamefromheader(
- in mach_header* mhp,
- in char* segname,
- in char* sectname
+ const scope mach_header* mhp,
+ const scope char* segname,
+ const scope char* sectname
);
/// ditto
const(section_64)* getsectbynamefromheader_64(
- in mach_header_64* mhp,
- in char* segname,
- in char* sectname
+ const scope mach_header_64* mhp,
+ const scope char* segname,
+ const scope char* sectname
);
/**
@@ -326,17 +326,17 @@ version (CoreDdoc)
* Returns: a pointer to the section structure or `null` if it doesn't exist
*/
const(section)* getsectbynamefromheaderwithswap(
- in mach_header* mhp,
- in char* segname,
- in char* section,
+ const scope mach_header* mhp,
+ const scope char* segname,
+ const scope char* section,
int fSwap
);
/// ditto
const(section)* getsectbynamefromheaderwithswap_64(
- in mach_header_64* mhp,
- in char* segname,
- in char* section,
+ const scope mach_header_64* mhp,
+ const scope char* segname,
+ const scope char* section,
int fSwap
);
}
@@ -357,15 +357,15 @@ public import core.sys.darwin.mach.loader;
import core.stdc.config : c_ulong;
char* getsectdata(
- in char* segname,
- in char* sectname,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong *size
);
char* getsectdatafromFramework(
- in char* FrameworkName,
- in char* segname,
- in char* sectname,
+ const scope char* FrameworkName,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
@@ -377,24 +377,24 @@ c_ulong get_edata();
version (D_LP64)
{
const(section_64)* getsectbyname(
- in char* segname,
- in char* sectname
+ const scope char* segname,
+ const scope char* sectname
);
ubyte* getsectiondata(
- in mach_header_64* mhp,
- in char* segname,
- in char* sectname,
+ const scope mach_header_64* mhp,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
const(segment_command_64)* getsegbyname(
- in char* segname
+ const scope char* segname
);
ubyte* getsegmentdata(
- in mach_header_64* mhp,
- in char* segname,
+ const scope mach_header_64* mhp,
+ const scope char* segname,
c_ulong* size
);
}
@@ -403,24 +403,24 @@ version (D_LP64)
else
{
const(section)* getsectbyname(
- in char* segname,
- in char* sectname
+ const scope char* segname,
+ const scope char* sectname
);
ubyte* getsectiondata(
- in mach_header* mhp,
- in char* segname,
- in char* sectname,
+ const scope mach_header* mhp,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
const(segment_command)* getsegbyname(
- in char* segname
+ const scope char* segname
);
ubyte* getsegmentdata(
- in mach_header* mhp,
- in char* segname,
+ const scope mach_header* mhp,
+ const scope char* segname,
c_ulong* size
);
}
@@ -428,44 +428,44 @@ else
// Interfaces for tools working with 32-bit Mach-O files.
ubyte* getsectdatafromheader(
- in mach_header* mhp,
- in char* segname,
- in char* sectname,
+ const scope mach_header* mhp,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
const(section)* getsectbynamefromheader(
- in mach_header* mhp,
- in char* segname,
- in char* sectname
+ const scope mach_header* mhp,
+ const scope char* segname,
+ const scope char* sectname
);
const(section)* getsectbynamefromheaderwithswap(
- in mach_header* mhp,
- in char* segname,
- in char* section,
+ const scope mach_header* mhp,
+ const scope char* segname,
+ const scope char* section,
int fSwap
);
// Interfaces for tools working with 64-bit Mach-O files.
ubyte* getsectdatafromheader_64(
- in mach_header_64* mhp,
- in char* segname,
- in char* sectname,
+ const scope mach_header_64* mhp,
+ const scope char* segname,
+ const scope char* sectname,
c_ulong* size
);
const(section_64)* getsectbynamefromheader_64(
- in mach_header_64* mhp,
- in char* segname,
- in char* sectname
+ const scope mach_header_64* mhp,
+ const scope char* segname,
+ const scope char* sectname
);
const(section)* getsectbynamefromheaderwithswap_64(
- in mach_header_64* mhp,
- in char* segname,
- in char* section,
+ const scope mach_header_64* mhp,
+ const scope char* segname,
+ const scope char* section,
int fSwap
);
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/loader.d b/libphobos/libdruntime/core/sys/darwin/mach/loader.d
index af42485..f46698c 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/loader.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/loader.d
@@ -2568,14 +2568,7 @@ version (CoreDdoc)
ulong size;
}
}
-
-else version (OSX)
- version = Darwin;
-else version (iOS)
- version = Darwin;
-else version (TVOS)
- version = Darwin;
-else version (WatchOS)
+else
version = Darwin;
version (Darwin):
@@ -3116,12 +3109,8 @@ struct dylib_reference
}
@property void isym()(uint v) @safe pure nothrow @nogc
- in
- {
- assert(v >= 0U, "Value is smaller than the minimum value of bitfield 'isym'");
- assert(v <= 16777215U, "Value is greater than the maximum value of bitfield 'isym'");
- }
- body
+ in(v >= 0U, "Value is smaller than the minimum value of bitfield 'isym'")
+ in(v <= 16777215U, "Value is greater than the maximum value of bitfield 'isym'")
{
storage = cast(uint) ((storage & (-1 - cast(uint) 16777215U)) |
((cast(uint) v << 0U) & 16777215U));
@@ -3133,12 +3122,8 @@ struct dylib_reference
}
@property void flags()(uint v) pure nothrow @nogc @safe
- in
- {
- assert(v >= 0U, "Value is smaller than the minimum value of bitfield 'flags'");
- assert(v <= 255U, "Value is greater than the maximum value of bitfield 'flags'");
- }
- body
+ in(v >= 0U, "Value is smaller than the minimum value of bitfield 'flags'")
+ in(v <= 255U, "Value is greater than the maximum value of bitfield 'flags'")
{
storage = cast(uint) ((storage & (-1 - cast(uint) 4278190080U)) |
((cast(uint) v << 24U) & 4278190080U));
@@ -3163,12 +3148,8 @@ struct twolevel_hint
}
@property void isub_image()(uint v) pure nothrow @nogc @safe
- in
- {
- assert(v >= 0U, "Value is smaller than the minimum value of bitfield 'isub_image'");
- assert(v <= 255U, "Value is greater than the maximum value of bitfield 'isub_image'");
- }
- body
+ in(v >= 0U, "Value is smaller than the minimum value of bitfield 'isub_image'")
+ in(v <= 255U, "Value is greater than the maximum value of bitfield 'isub_image'")
{
storage = cast(uint) ((storage & (-1-cast(uint)255U)) |
((cast(uint) v << 0U) & 255U));
@@ -3180,12 +3161,8 @@ struct twolevel_hint
}
@property void itoc()(uint v) pure nothrow @nogc @safe
- in
- {
- assert(v >= 0U, "Value is smaller than the minimum value of bitfield 'itoc'");
- assert(v <= 16777215U, "Value is greater than the maximum value of bitfield 'itoc'");
- }
- body
+ in(v >= 0U, "Value is smaller than the minimum value of bitfield 'itoc'")
+ in(v <= 16777215U, "Value is greater than the maximum value of bitfield 'itoc'")
{
storage = cast(uint) ((storage & (-1-cast(uint)4294967040U)) |
((cast(uint) v << 8U) & 4294967040U));
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/nlist.d b/libphobos/libdruntime/core/sys/darwin/mach/nlist.d
new file mode 100644
index 0000000..11e5ced
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/mach/nlist.d
@@ -0,0 +1,317 @@
+/**
+ * Bindings for symbols and defines in `mach-o/nlist.h`
+ *
+ * This file was created based on the MacOSX 10.15 SDK.
+ *
+ * Copyright:
+ * D Language Foundation 2020
+ * Some documentation was extracted from the C headers
+ * and is the property of Apple Inc.
+ *
+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ * Authors: Mathias 'Geod24' Lang
+ * Source: $(DRUNTIMESRC core/sys/darwin/mach/_nlist.d)
+ */
+module core.sys.darwin.mach.nlist;
+
+import core.stdc.config;
+
+extern(C):
+nothrow:
+@nogc:
+pure:
+
+/**
+ * An entry in a list of symbols for 64-bits architectures
+ *
+ * Said symbols can be used to describe many different type of data,
+ * including STABS debug infos. Introduced in MacOSX 10.8 SDK.
+ *
+ * See_Also:
+ * https://developer.apple.com/documentation/kernel/nlist_64
+ */
+struct nlist_64
+{
+ /// Compatibility alias, as `n_strx` is in an union in C code
+ alias n_un = n_strx;
+
+ /**
+ * Index of this symbol's name into the string table
+ *
+ * All names are stored as NUL-terminated strings into the string table.
+ * For historical reason, the very first entry into the string table is `0`,
+ * hence all non-NULL names have an index > 0.
+ */
+ uint n_strx;
+
+ /**
+ * A bitfield that describes the type of this symbol
+ *
+ * In reality, this describes 4 fields:
+ * - N_STAB (top 3 bits)
+ * - N_PEXT (next 1 bit)
+ * - N_TYPE (next 3 bits)
+ * - N_EXT (last 1 bit)
+ *
+ * The enum values `N_STAB`, `N_PEXT`, `N_TYPE`, and `N_EXT` should be used
+ * as masks to check which type this `nlist_64` actually is.
+ */
+ ubyte n_type;
+ /// Section number (note that `0` means `NO_SECT`)
+ ubyte n_sect;
+ /* see <mach-o/stab.h> */
+ ushort n_desc;
+ /* value of this symbol (or stab offset) */
+ ulong n_value;
+ // Note: `n_value` *is* `uint64_t`, not `c_ulong` !
+}
+
+/// Mask to use with `nlist_64.n_type` to check what the entry describes
+enum
+{
+ /**
+ * If any of these bits set, a symbolic debugging entry
+ *
+ * Only symbolic debugging entries have some of the N_STAB bits set and if any
+ * of these bits are set then it is a symbolic debugging entry (a stab). In
+ * which case then the values of the n_type field (the entire field) are given
+ * in <mach-o/stab.h>
+ */
+ N_STAB = 0xe0,
+ /// Private external symbol bit
+ N_PEXT = 0x10,
+ /// Mask for the type bits
+ N_TYPE = 0x0e, /* mask for the type bits */
+ /// External symbol bit, set for external symbols
+ N_EXT = 0x01,
+}
+
+/// Values for `NTypeMask.N_TYPE` bits of the `nlist_64.n_type` field.
+enum
+{
+ /// Undefined (`n_sect == NO_SECT`)
+ N_UNDF = 0x0,
+ /// Absolute (`n_sect == NO_SECT`)
+ N_ABS = 0x2,
+ /// Defined in section number `nlist_64.n_sect`
+ N_SECT = 0xe,
+ /// Prebound undefined (defined in a dylib)
+ N_PBUD = 0xc,
+ /**
+ * Indirect symbol
+ *
+ * If the type is `N_INDR` then the symbol is defined to be the same as
+ * another symbol. In this case the `n_value` field is an index into
+ * the string table of the other symbol's name. When the other symbol
+ * is defined then they both take on the defined type and value.
+ */
+ N_INDR = 0xa,
+}
+
+/**
+ * Symbol is not in any section
+ *
+ * If the type is N_SECT then the n_sect field contains an ordinal of the
+ * section the symbol is defined in. The sections are numbered from 1 and
+ * refer to sections in order they appear in the load commands for the file
+ * they are in. This means the same ordinal may very well refer to different
+ * sections in different files.
+ *
+ * The n_value field for all symbol table entries (including N_STAB's) gets
+ * updated by the link editor based on the value of it's n_sect field and where
+ * the section n_sect references gets relocated. If the value of the n_sect
+ * field is NO_SECT then it's n_value field is not changed by the link editor.
+ */
+enum NO_SECT = 0;
+
+/// Maximum number of sections: 1 thru 255 inclusive
+enum MAX_SECT = 255;
+
+/**
+ * Common symbols are represented by undefined (N_UNDF) external (N_EXT) types
+ * who's values (n_value) are non-zero. In which case the value of the n_value
+ * field is the size (in bytes) of the common symbol. The n_sect field is set
+ * to NO_SECT. The alignment of a common symbol may be set as a power of 2
+ * between 2^1 and 2^15 as part of the n_desc field using the macros below. If
+ * the alignment is not set (a value of zero) then natural alignment based on
+ * the size is used.
+ */
+extern(D) ubyte GET_COMM_ALIGN(uint n_desc) @safe
+{
+ return (((n_desc) >> 8) & 0x0f);
+}
+
+/// Ditto
+extern(D) ref ushort SET_COMM_ALIGN(return ref ushort n_desc, size_t wanted_align) @safe
+{
+ return n_desc = (((n_desc) & 0xf0ff) | (((wanted_align) & 0x0f) << 8));
+}
+
+/**
+ * To support the lazy binding of undefined symbols in the dynamic link-editor,
+ * the undefined symbols in the symbol table (the nlist structures) are marked
+ * with the indication if the undefined reference is a lazy reference or
+ * non-lazy reference. If both a non-lazy reference and a lazy reference is
+ * made to the same symbol the non-lazy reference takes precedence. A reference
+ * is lazy only when all references to that symbol are made through a symbol
+ * pointer in a lazy symbol pointer section.
+ *
+ * The implementation of marking nlist structures in the symbol table for
+ * undefined symbols will be to use some of the bits of the n_desc field as a
+ * reference type. The mask REFERENCE_TYPE will be applied to the n_desc field
+ * of an nlist structure for an undefined symbol to determine the type of
+ * undefined reference (lazy or non-lazy).
+ *
+ * The constants for the REFERENCE FLAGS are propagated to the reference table
+ * in a shared library file. In that case the constant for a defined symbol,
+ * REFERENCE_FLAG_DEFINED, is also used.
+ */
+enum
+{
+ /// Reference type bits of the n_desc field of undefined symbols
+ REFERENCE_TYPE = 0x7,
+
+ /// types of references
+ REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
+ /// Ditto
+ REFERENCE_FLAG_UNDEFINED_LAZY = 1,
+ /// Ditto
+ REFERENCE_FLAG_DEFINED = 2,
+ /// Ditto
+ REFERENCE_FLAG_PRIVATE_DEFINED = 3,
+ /// Ditto
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
+ /// Ditto
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5,
+
+ /**
+ * To simplify stripping of objects that use are used with the dynamic link
+ * editor, the static link editor marks the symbols defined an object that are
+ * referenced by a dynamicly bound object (dynamic shared libraries, bundles).
+ * With this marking strip knows not to strip these symbols.
+ */
+ REFERENCED_DYNAMICALLY = 0x0010,
+}
+
+/**
+ * For images created by the static link editor with the -twolevel_namespace
+ * option in effect the flags field of the mach header is marked with
+ * MH_TWOLEVEL. And the binding of the undefined references of the image are
+ * determined by the static link editor. Which library an undefined symbol is
+ * bound to is recorded by the static linker in the high 8 bits of the n_desc
+ * field using the SET_LIBRARY_ORDINAL macro below. The ordinal recorded
+ * references the libraries listed in the Mach-O's LC_LOAD_DYLIB,
+ * LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and
+ * LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the
+ * headers. The library ordinals start from 1.
+ * For a dynamic library that is built as a two-level namespace image the
+ * undefined references from module defined in another use the same nlist struct
+ * an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For
+ * defined symbols in all images they also must have the library ordinal set to
+ * SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable
+ * image for references from plugins that refer to the executable that loads
+ * them.
+ *
+ * The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace
+ * image that are looked up by the dynamic linker with flat namespace semantics.
+ * This ordinal was added as a feature in Mac OS X 10.3 by reducing the
+ * value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries
+ * or binaries built with older tools to have 0xfe (254) dynamic libraries. In
+ * this case the ordinal value 0xfe (254) must be treated as a library ordinal
+ * for compatibility.
+ */
+ubyte GET_LIBRARY_ORDINAL(uint n_desc) @safe { return ((n_desc) >> 8) & 0xff; }
+/// Ditto
+ref ushort SET_LIBRARY_ORDINAL(return scope ref ushort n_desc, uint ordinal) @safe
+{
+ return n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
+}
+
+/// Ditto
+enum
+{
+ SELF_LIBRARY_ORDINAL = 0x00,
+ MAX_LIBRARY_ORDINAL = 0xfd,
+ DYNAMIC_LOOKUP_ORDINAL = 0xfe,
+ EXECUTABLE_ORDINAL = 0xff,
+}
+
+/**
+ * The bit 0x0020 of the n_desc field is used for two non-overlapping purposes
+ * and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED.
+ */
+enum
+{
+ /**
+ * Symbol is not to be dead stripped
+ *
+ * The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a
+ * relocatable .o file (MH_OBJECT filetype). And is used to indicate to the
+ * static link editor it is never to dead strip the symbol.
+ */
+ N_NO_DEAD_STRIP = 0x0020,
+
+ /**
+ * Symbol is discarded
+ *
+ * The N_DESC_DISCARDED bit of the n_desc field never appears in linked image.
+ * But is used in very rare cases by the dynamic link editor to mark an in
+ * memory symbol as discared and longer used for linking.
+ */
+ N_DESC_DISCARDED =0x0020,
+
+ /**
+ * Symbol is weak referenced
+ *
+ * The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that
+ * the undefined symbol is allowed to be missing and is to have the address of
+ * zero when missing.
+ */
+ N_WEAK_REF = 0x0040,
+
+ /**
+ * Coalesed symbol is a weak definition
+ *
+ * The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic
+ * linkers that the symbol definition is weak, allowing a non-weak symbol to
+ * also be used which causes the weak definition to be discared. Currently this
+ * is only supported for symbols in coalesed sections.
+ */
+ N_WEAK_DEF = 0x0080,
+
+ /**
+ * Reference to a weak symbol
+ *
+ * The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker
+ * that the undefined symbol should be resolved using flat namespace searching.
+ */
+ N_REF_TO_WEAK = 0x0080,
+
+ /**
+ * Symbol is a Thumb function (ARM)
+ *
+ * The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is
+ * a defintion of a Thumb function.
+ */
+ N_ARM_THUMB_DEF = 0x0008,
+
+ /**
+ * The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the
+ * that the function is actually a resolver function and should
+ * be called to get the address of the real function to use.
+ * This bit is only available in .o files (MH_OBJECT filetype)
+ */
+ N_SYMBOL_RESOLVER = 0x0100,
+
+ /**
+ * The N_ALT_ENTRY bit of the n_desc field indicates that the
+ * symbol is pinned to the previous content.
+ */
+ N_ALT_ENTRY = 0x0200,
+
+ /**
+ * The N_COLD_FUNC bit of the n_desc field indicates that the symbol is used
+ * infrequently and the linker should order it towards the end of the section.
+ */
+ N_COLD_FUNC = 0x0400,
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/stab.d b/libphobos/libdruntime/core/sys/darwin/mach/stab.d
new file mode 100644
index 0000000..ecdb456
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/mach/stab.d
@@ -0,0 +1,90 @@
+/**
+ * Bindings for symbols and defines in `mach-o/stab.h`
+ *
+ * This file gives definitions supplementing <nlist.h> for permanent symbol
+ * table entries of Mach-O files. Modified from the BSD definitions. The
+ * modifications from the original definitions were changing what the values of
+ * what was the n_other field (an unused field) which is now the n_sect field.
+ * These modifications are required to support symbols in an arbitrary number of
+ * sections not just the three sections (text, data and bss) in a BSD file.
+ * The values of the defined constants have NOT been changed.
+ *
+ * These must have one of the N_STAB bits on. The n_value fields are subject
+ * to relocation according to the value of their n_sect field. So for types
+ * that refer to things in sections the n_sect field must be filled in with the
+ * proper section ordinal. For types that are not to have their n_value field
+ * relocatated the n_sect field must be NO_SECT.
+ *
+ * This file was created based on the MacOSX 10.15 SDK.
+ *
+ * Copyright:
+ * D Language Foundation 2020
+ * Some documentation was extracted from the C headers
+ * and is the property of Apple Inc.
+ *
+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ * Authors: Mathias 'Geod24' Lang
+ * Source: $(DRUNTIMESRC core/sys/darwin/mach/_nlist.d)
+ */
+module core.sys.darwin.mach.stab;
+
+extern(C):
+nothrow:
+@nogc:
+pure:
+
+/**
+ * Symbolic debugger symbols.
+ *
+ * The comments give the conventional use for
+ * ```
+ * .stabs "n_name", n_type, n_sect, n_desc, n_value
+ * ```
+ *
+ * where n_type is the defined constant and not listed in the comment. Other
+ * fields not listed are zero. n_sect is the section ordinal the entry is
+ * refering to.
+ */
+enum
+{
+ N_GSYM = 0x20, /// global symbol: name,,NO_SECT,type,0
+ N_FNAME = 0x22, /// procedure name (f77 kludge): name,,NO_SECT,0,0
+ N_FUN = 0x24, /// procedure: name,,n_sect,linenumber,address
+ N_STSYM = 0x26, /// static symbol: name,,n_sect,type,address
+ N_LCSYM = 0x28, /// .lcomm symbol: name,,n_sect,type,address
+ N_BNSYM = 0x2e, /// begin nsect sym: 0,,n_sect,0,address
+ N_AST = 0x32, /// AST file path: name,,NO_SECT,0,0
+ N_OPT = 0x3c, /// emitted with gcc2_compiled and in gcc source
+ N_RSYM = 0x40, /// register sym: name,,NO_SECT,type,register
+ N_SLINE = 0x44, /// src line: 0,,n_sect,linenumber,address
+ N_ENSYM = 0x4e, /// end nsect sym: 0,,n_sect,0,address
+ N_SSYM = 0x60, /// structure elt: name,,NO_SECT,type,struct_offset
+ N_SO = 0x64, /// source file name: name,,n_sect,0,address
+ /**
+ * Object file name: name,,(see below),0,st_mtime
+ *
+ * Historically N_OSO set n_sect to 0.
+ * The N_OSO n_sect may instead hold the low byte of the cpusubtype value
+ * from the Mach-O header.
+ */
+ N_OSO = 0x66,
+ N_LSYM = 0x80, /// local sym: name,,NO_SECT,type,offset
+ N_BINCL = 0x82, /// include file beginning: name,,NO_SECT,0,sum
+ N_SOL = 0x84, /// #included file name: name,,n_sect,0,address
+ N_PARAMS = 0x86, /// compiler parameters: name,,NO_SECT,0,0
+ N_VERSION = 0x88, /// compiler version: name,,NO_SECT,0,0
+ N_OLEVEL = 0x8A, /// compiler -O level: name,,NO_SECT,0,0
+ N_PSYM = 0xa0, /// parameter: name,,NO_SECT,type,offset
+ N_EINCL = 0xa2, /// include file end: name,,NO_SECT,0,0
+ N_ENTRY = 0xa4, /// alternate entry: name,,n_sect,linenumber,address
+ N_LBRAC = 0xc0, /// left bracket: 0,,NO_SECT,nesting level,address
+ N_EXCL = 0xc2, /// deleted include file: name,,NO_SECT,0,sum
+ N_RBRAC = 0xe0, /// right bracket: 0,,NO_SECT,nesting level,address
+ N_BCOMM = 0xe2, /// begin common: name,,NO_SECT,0,0
+ N_ECOMM = 0xe4, /// end common: name,,n_sect,0,0
+ N_ECOML = 0xe8, /// end common (local name): 0,,n_sect,0,address
+ N_LENG = 0xfe, /// second stab entry with length information
+
+ // For the berkeley pascal compiler, pc(1):
+ N_PC = 0x30, /// global pascal symbol: name,,NO_SECT,subtype,line
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
index b61673f..d455d1b 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
@@ -38,6 +38,10 @@ version (AArch64)
version = AnyARM;
version (ARM)
version = AnyARM;
+version (PPC)
+ version = AnyPPC;
+version (PPC64)
+ version = AnyPPC;
version (i386)
{
@@ -235,3 +239,65 @@ else version (AnyARM)
kern_return_t thread_resume(thread_act_t);
kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
}
+else version (AnyPPC)
+{
+ alias thread_act_t = mach_port_t;
+ alias thread_state_t = void;
+ alias thread_state_flavor_t = int;
+ alias mach_msg_type_number_t = natural_t;
+
+ enum
+ {
+ PPC_THREAD_STATE = 1,
+ PPC_FLOAT_STATE = 2,
+ PPC_EXCEPTION_STATE = 3,
+ PPC_VECTOR_STATE = 4,
+ PPC_THREAD_STATE64 = 5,
+ PPC_EXCEPTION_STATE64 = 6,
+ THREAD_STATE_NONE = 7
+ }
+
+ struct ppc_thread_state_t
+ {
+ uint srr0; /// Instruction address register (PC)
+ uint srr1; /// Machine state register (supervisor)
+ uint[32] r; /// General purpose register r0-r31
+ uint cr; /// Condition register
+ uint xer; /// User's integer exception register
+ uint lr; /// Link register
+ uint ctr; /// Count register
+ uint mq; /// MQ register (601 only)
+ uint vrsave; /// Vector save register
+ }
+
+ alias ppc_thread_state32_t = ppc_thread_state_t;
+
+ struct ppc_thread_state64_t
+ {
+ ulong srr0; /// Instruction address register (PC)
+ ulong srr1; /// Machine state register (supervisor)
+ ulong[32] r; /// General purpose register r0-r31
+ uint cr; /// Condition register
+ uint pad0;
+ ulong xer; /// User's integer exception register
+ ulong lr; /// Link register
+ ulong ctr; /// Count register
+ uint vrsave; /// Vector save register
+ uint pad1;
+ }
+
+ enum : mach_msg_type_number_t
+ {
+ PPC_THREAD_STATE_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state_t.sizeof / uint.sizeof),
+ PPC_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state32_t.sizeof / uint.sizeof),
+ PPC_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state64_t.sizeof / uint.sizeof),
+ }
+
+ alias MACHINE_THREAD_STATE = PPC_THREAD_STATE;
+ alias MACHINE_THREAD_STATE_COUNT = PPC_THREAD_STATE_COUNT;
+
+ mach_port_t mach_thread_self();
+ kern_return_t thread_suspend(thread_act_t);
+ kern_return_t thread_resume(thread_act_t);
+ kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/netinet/in_.d b/libphobos/libdruntime/core/sys/darwin/netinet/in_.d
index 0653d3a..b850e3c 100644
--- a/libphobos/libdruntime/core/sys/darwin/netinet/in_.d
+++ b/libphobos/libdruntime/core/sys/darwin/netinet/in_.d
@@ -225,7 +225,7 @@ static if (_DARWIN_C_SOURCE)
{
in_addr ip_dst;
char[40] ip_opts = 0;
- };
+ }
enum IP_OPTIONS = 1;
enum IP_HDRINCL = 2;
@@ -307,14 +307,14 @@ static if (_DARWIN_C_SOURCE)
{
in_addr imr_multiaddr;
in_addr imr_interface;
- };
+ }
struct ip_mreqn
{
in_addr imr_multiaddr;
in_addr imr_address;
int imr_ifindex;
- };
+ }
struct ip_mreq_source
{
@@ -322,14 +322,14 @@ static if (_DARWIN_C_SOURCE)
in_addr imr_multiaddr;
in_addr imr_sourceaddr;
in_addr imr_interface;
- };
+ }
struct group_req
{
align(4):
uint gr_interface;
sockaddr_storage gr_group;
- };
+ }
struct group_source_req
{
@@ -337,7 +337,7 @@ static if (_DARWIN_C_SOURCE)
uint gsr_interface;
sockaddr_storage gsr_group;
sockaddr_storage gsr_source;
- };
+ }
int setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*);
int getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*);
@@ -357,7 +357,7 @@ static if (_DARWIN_C_SOURCE)
uint ipi_ifindex;
in_addr ipi_spec_dst;
in_addr ipi_addr;
- };
+ }
enum IPPROTO_MAXID = IPPROTO_AH + 1;
@@ -524,13 +524,13 @@ static if (_DARWIN_C_SOURCE)
{
in6_addr ipi6_addr;
uint ipi6_ifindex;
- };
+ }
struct ip6_mtuinfo
{
sockaddr_in6 ip6m_addr;
uint ip6m_mtu;
- };
+ }
enum IPV6_PORTRANGE_DEFAULT = 0;
enum IPV6_PORTRANGE_HIGH = 1;
diff --git a/libphobos/libdruntime/core/sys/darwin/pthread.d b/libphobos/libdruntime/core/sys/darwin/pthread.d
index 786d9f2..456cde9 100644
--- a/libphobos/libdruntime/core/sys/darwin/pthread.d
+++ b/libphobos/libdruntime/core/sys/darwin/pthread.d
@@ -43,18 +43,18 @@ int pthread_rwlock_held_np(pthread_rwlock_t*);
int pthread_rwlock_rdheld_np(pthread_rwlock_t*);
int pthread_rwlock_wrheld_np(pthread_rwlock_t*);
int pthread_getname_np(pthread_t, char*, size_t);
-int pthread_setname_np(in char*);
+int pthread_setname_np(const scope char*);
// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
int pthread_main_np();
mach_port_t pthread_mach_thread_np(pthread_t);
size_t pthread_get_stacksize_np(pthread_t);
void* pthread_get_stackaddr_np(pthread_t);
int pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);
-int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);
-int pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
+int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
+int pthread_create_suspended_np(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
int pthread_kill(pthread_t, int);
pthread_t pthread_from_mach_thread_np(mach_port_t);
// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
-int pthread_sigmask(int, in sigset_t*, sigset_t*);
+int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
// ^ __DARWIN_ALIAS(pthread_sigmask)
void pthread_yield_np();
diff --git a/libphobos/libdruntime/core/sys/darwin/stdlib.d b/libphobos/libdruntime/core/sys/darwin/stdlib.d
new file mode 100644
index 0000000..287eaa0
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/stdlib.d
@@ -0,0 +1,26 @@
+/**
+ * D header file for Darwin stdlib.h.
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.stdlib;
+public import core.sys.posix.stdlib;
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (Darwin):
+extern (C):
+nothrow:
+@nogc:
+
+const(char)* getprogname();
+void setprogname(scope const char* name);
diff --git a/libphobos/libdruntime/core/sys/darwin/sys/attr.d b/libphobos/libdruntime/core/sys/darwin/sys/attr.d
new file mode 100644
index 0000000..cb22b38
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/sys/attr.d
@@ -0,0 +1,338 @@
+/**
+ * D header file for Darwin
+ *
+ * $(LINK2 https://opensource.apple.com/source/xnu/xnu-2422.115.4/bsd/sys/attr.h.auto.html, Apple sys/attr.h)
+ */
+module core.sys.darwin.sys.attr;
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (Darwin):
+extern (C):
+nothrow:
+@nogc:
+
+import core.internal.attributes : betterC;
+import core.sys.darwin.sys.cdefs : c_ulong;
+import core.sys.posix.sys.time : timeval;
+
+// These functions aren't actually declared in attr.h but in unistd.h.
+@system
+{
+ void getattrlist(scope const char* path, scope attrlist* attrList, scope void* attrBuf,
+ size_t attrBufSize, c_ulong options);
+
+ void setattrlist(scope const char* path, scope attrlist* attrList, scope void* attrBuf,
+ size_t attrBufSize, c_ulong options);
+
+ version (TVOS) {}
+ else version (WatchOS) {}
+ else
+ int searchfs(scope const char* path, scope fssearchblock* searchBlock,
+ scope c_ulong* numMatches, uint scriptCode, uint options, scope searchstate* state);
+}
+
+enum
+{
+ FSOPT_NOFOLLOW = 0x00000001,
+ FSOPT_NOINMEMUPDATE = 0x00000002,
+ FSOPT_REPORT_FULLSIZE = 0x00000004,
+ FSOPT_PACK_INVAL_ATTRS = 0x00000008,
+ FSOPT_ATTR_CMN_EXTENDED = 0x00000020, // macOS 10.10
+}
+
+enum SEARCHFS_MAX_SEARCHPARMS = 4096;
+
+alias uint text_encoding_t, fsobj_type_t, fsobj_tag_t, fsfile_type_t, fsvolid_t, attrgroup_t;
+
+struct attrlist
+{
+ ushort bitmapcount, reserved;
+ attrgroup_t commonattr, volattr, dirattr, fileattr, forkattr;
+}
+enum ATTR_BIT_MAP_COUNT = 5;
+
+struct attribute_set_t
+{
+ attrgroup_t commonattr, volattr, dirattr, fileattr, forkattr;
+}
+
+struct attrreference_t
+{
+ int attr_dataoffset;
+ uint attr_length;
+}
+
+struct diskextent
+{
+ uint startblock, blockcount;
+}
+
+alias extentrecord = diskextent[8];
+
+alias vol_capabilities_set_t = uint[4];
+
+enum
+{
+ VOL_CAPABILITIES_FORMAT = 0,
+ VOL_CAPABILITIES_INTERFACES = 1,
+ VOL_CAPABILITIES_RESERVED1 = 2,
+ VOL_CAPABILITIES_RESERVED2 = 3,
+}
+
+struct vol_capabilities_attr_t
+{
+ vol_capabilities_set_t capabilities, valid;
+}
+
+enum ATTR_MAX_BUFFER = 8192;
+
+enum
+{
+ VOL_CAP_FMT_PERSISTENTOBJECTIDS = 0x00000001,
+ VOL_CAP_FMT_SYMBOLICLINKS = 0x00000002,
+ VOL_CAP_FMT_HARDLINKS = 0x00000004,
+ VOL_CAP_FMT_JOURNAL = 0x00000008,
+ VOL_CAP_FMT_JOURNAL_ACTIVE = 0x00000010,
+ VOL_CAP_FMT_NO_ROOT_TIMES = 0x00000020,
+ VOL_CAP_FMT_SPARSE_FILES = 0x00000040,
+ VOL_CAP_FMT_ZERO_RUNS = 0x00000080,
+ VOL_CAP_FMT_CASE_SENSITIVE = 0x00000100,
+ VOL_CAP_FMT_CASE_PRESERVING = 0x00000200,
+ VOL_CAP_FMT_FAST_STATFS = 0x00000400,
+ VOL_CAP_FMT_2TB_FILESIZE = 0x00000800,
+ VOL_CAP_FMT_OPENDENYMODES = 0x00001000,
+ VOL_CAP_FMT_HIDDEN_FILES = 0x00002000,
+ VOL_CAP_FMT_PATH_FROM_ID = 0x00004000,
+ VOL_CAP_FMT_NO_VOLUME_SIZES = 0x00008000,
+ VOL_CAP_FMT_DECMPFS_COMPRESSION = 0x00010000,
+ VOL_CAP_FMT_64BIT_OBJECT_IDS = 0x00020000,
+ VOL_CAP_FMT_DIR_HARDLINKS = 0x00040000, // macOS 10.12
+ VOL_CAP_FMT_DOCUMENT_ID = 0x00080000, // macOS 10.12
+ VOL_CAP_FMT_WRITE_GENERATION_COUNT = 0x00100000, // macOS 10.12
+ VOL_CAP_FMT_NO_IMMUTABLE_FILES = 0x00200000, // macOS 10.12.4
+ VOL_CAP_FMT_NO_PERMISSIONS = 0x00400000, // macOS 10.12.4
+ VOL_CAP_FMT_SHARED_SPACE = 0x00800000, // macOS 10.15
+ VOL_CAP_FMT_VOL_GROUPS = 0x01000000, // macOS 10.15
+}
+
+enum
+{
+ VOL_CAP_INT_SEARCHFS = 0x00000001,
+ VOL_CAP_INT_ATTRLIST = 0x00000002,
+ VOL_CAP_INT_NFSEXPORT = 0x00000004,
+ VOL_CAP_INT_READDIRATTR = 0x00000008,
+ VOL_CAP_INT_EXCHANGEDATA = 0x00000010,
+ VOL_CAP_INT_COPYFILE = 0x00000020,
+ VOL_CAP_INT_ALLOCATE = 0x00000040,
+ VOL_CAP_INT_VOL_RENAME = 0x00000080,
+ VOL_CAP_INT_ADVLOCK = 0x00000100,
+ VOL_CAP_INT_FLOCK = 0x00000200,
+ VOL_CAP_INT_EXTENDED_SECURITY = 0x00000400,
+ VOL_CAP_INT_USERACCESS = 0x00000800,
+ VOL_CAP_INT_MANLOCK = 0x00001000,
+ VOL_CAP_INT_NAMEDSTREAMS = 0x00002000,
+ VOL_CAP_INT_EXTENDED_ATTR = 0x00004000,
+ VOL_CAP_INT_CLONE = 0x00010000, // macOS 10.12
+ VOL_CAP_INT_SNAPSHOT = 0x00020000, // macOS 10.12
+ VOL_CAP_INT_RENAME_SWAP = 0x00040000, // macOS 10.12
+ VOL_CAP_INT_RENAME_EXCL = 0x00080000, // macOS 10.12
+ VOL_CAP_INT_RENAME_OPENFAIL = 0x00100000, // macOS 10.15
+}
+
+struct vol_attributes_attr_t
+{
+ attribute_set_t validattr, nativeattr;
+}
+
+enum
+{
+ ATTR_CMN_NAME = 0x00000001,
+ ATTR_CMN_DEVID = 0x00000002,
+ ATTR_CMN_FSID = 0x00000004,
+ ATTR_CMN_OBJTYPE = 0x00000008,
+ ATTR_CMN_OBJTAG = 0x00000010,
+ ATTR_CMN_OBJID = 0x00000020,
+ ATTR_CMN_OBJPERMANENTID = 0x00000040,
+ ATTR_CMN_PAROBJID = 0x00000080,
+ ATTR_CMN_SCRIPT = 0x00000100,
+ ATTR_CMN_CRTIME = 0x00000200,
+ ATTR_CMN_MODTIME = 0x00000400,
+ ATTR_CMN_CHGTIME = 0x00000800,
+ ATTR_CMN_ACCTIME = 0x00001000,
+ ATTR_CMN_BKUPTIME = 0x00002000,
+ ATTR_CMN_FNDRINFO = 0x00004000,
+ ATTR_CMN_OWNERID = 0x00008000,
+ ATTR_CMN_GRPID = 0x00010000,
+ ATTR_CMN_ACCESSMASK = 0x00020000,
+ ATTR_CMN_FLAGS = 0x00040000,
+
+ ATTR_CMN_GEN_COUNT = 0x00080000,
+ ATTR_CMN_DOCUMENT_ID = 0x00100000,
+
+ ATTR_CMN_USERACCESS = 0x00200000,
+ ATTR_CMN_EXTENDED_SECURITY = 0x00400000,
+ ATTR_CMN_UUID = 0x00800000,
+ ATTR_CMN_GRPUUID = 0x01000000,
+ ATTR_CMN_FILEID = 0x02000000,
+ ATTR_CMN_PARENTID = 0x04000000,
+ ATTR_CMN_FULLPATH = 0x08000000,
+ ATTR_CMN_ADDEDTIME = 0x10000000,
+ ATTR_CMN_ERROR = 0x20000000, // macOS 10.10
+ ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000, // macOS 10.10
+}
+
+enum ATTR_CMN_RETURNED_ATTRS = 0x80000000;
+enum ATTR_CMN_VALIDMASK = 0xFFFFFFFF;
+enum ATTR_CMN_SETMASK = 0x51C7FF00;
+enum ATTR_CMN_VOLSETMASK = 0x00006700;
+
+enum
+{
+ ATTR_VOL_FSTYPE = 0x00000001,
+ ATTR_VOL_SIGNATURE = 0x00000002,
+ ATTR_VOL_SIZE = 0x00000004,
+ ATTR_VOL_SPACEFREE = 0x00000008,
+ ATTR_VOL_SPACEAVAIL = 0x00000010,
+ ATTR_VOL_MINALLOCATION = 0x00000020,
+ ATTR_VOL_ALLOCATIONCLUMP = 0x00000040,
+ ATTR_VOL_IOBLOCKSIZE = 0x00000080,
+ ATTR_VOL_OBJCOUNT = 0x00000100,
+ ATTR_VOL_FILECOUNT = 0x00000200,
+ ATTR_VOL_DIRCOUNT = 0x00000400,
+ ATTR_VOL_MAXOBJCOUNT = 0x00000800,
+ ATTR_VOL_MOUNTPOINT = 0x00001000,
+ ATTR_VOL_NAME = 0x00002000,
+ ATTR_VOL_MOUNTFLAGS = 0x00004000,
+ ATTR_VOL_MOUNTEDDEVICE = 0x00008000,
+ ATTR_VOL_ENCODINGSUSED = 0x00010000,
+ ATTR_VOL_CAPABILITIES = 0x00020000,
+ ATTR_VOL_UUID = 0x00040000,
+ ATTR_VOL_QUOTA_SIZE = 0x10000000, // macOS 10.12.4
+ ATTR_VOL_RESERVED_SIZE = 0x20000000, // macOS 10.12.4
+ ATTR_VOL_ATTRIBUTES = 0x40000000,
+ ATTR_VOL_INFO = 0x80000000,
+}
+
+enum ATTR_VOL_VALIDMASK = 0xF007FFFF;
+enum ATTR_VOL_SETMASK = 0x80002000;
+
+enum
+{
+ ATTR_DIR_LINKCOUNT = 0x00000001,
+ ATTR_DIR_ENTRYCOUNT = 0x00000002,
+ ATTR_DIR_MOUNTSTATUS = 0x00000004,
+ ATTR_DIR_ALLOCSIZE = 0x00000008, // macOS 10.12.4
+ ATTR_DIR_IOBLOCKSIZE = 0x00000010, // macOS 10.12.4
+ ATTR_DIR_DATALENGTH = 0x00000020, // macOS 10.12.4
+}
+
+enum
+{
+ DIR_MNTSTATUS_MNTPOINT = 0x00000001,
+ DIR_MNTSTATUS_TRIGGER = 0x00000002,
+}
+
+enum ATTR_DIR_VALIDMASK = 0x0000003f;
+enum ATTR_DIR_SETMASK = 0x00000000;
+
+enum
+{
+ ATTR_FILE_LINKCOUNT = 0x00000001,
+ ATTR_FILE_TOTALSIZE = 0x00000002,
+ ATTR_FILE_ALLOCSIZE = 0x00000004,
+ ATTR_FILE_IOBLOCKSIZE = 0x00000008,
+ ATTR_FILE_DEVTYPE = 0x00000020,
+ ATTR_FILE_FORKCOUNT = 0x00000080,
+ ATTR_FILE_FORKLIST = 0x00000100,
+ ATTR_FILE_DATALENGTH = 0x00000200,
+ ATTR_FILE_DATAALLOCSIZE = 0x00000400,
+ ATTR_FILE_RSRCLENGTH = 0x00001000,
+ ATTR_FILE_RSRCALLOCSIZE = 0x00002000,
+}
+
+enum ATTR_FILE_VALIDMASK = 0x000037FF;
+enum ATTR_FILE_SETMASK = 0x00000020;
+
+enum
+{
+ ATTR_CMNEXT_RELPATH = 0x00000004, // macOS 10.12.4
+ ATTR_CMNEXT_PRIVATESIZE = 0x00000008, // macOS 10.12.4
+ ATTR_CMNEXT_NOFIRMLINKPATH = 0x00000020, // macOS 10.15
+ ATTR_CMNEXT_REALDEVID = 0x00000040, // macOS 10.15
+ ATTR_CMNEXT_REALFSID = 0x00000080, // macOS 10.15
+}
+
+enum ATTR_CMNEXT_VALIDMASK = 0x000000fc;
+enum ATTR_CMNEXT_SETMASK = 0x00000000;
+
+enum ATTR_BULK_REQUIRED = ATTR_CMN_NAME | ATTR_CMN_RETURNED_ATTRS;
+
+enum
+{
+ SRCHFS_START = 0x00000001,
+ SRCHFS_MATCHPARTIALNAMES = 0x00000002,
+ SRCHFS_MATCHDIRS = 0x00000004,
+ SRCHFS_MATCHFILES = 0x00000008,
+ SRCHFS_SKIPLINKS = 0x00000010,
+ SRCHFS_SKIPINVISIBLE = 0x00000020,
+ SRCHFS_SKIPPACKAGES = 0x00000040,
+ SRCHFS_SKIPINAPPROPRIATE = 0x00000080,
+
+ SRCHFS_NEGATEPARAMS = 0x80000000,
+ SRCHFS_VALIDOPTIONSMASK = 0x800000FF,
+}
+
+struct fssearchblock
+{
+ attrlist* returnattrs;
+ void* returnbuffer;
+ size_t returnbuffersize;
+ c_ulong maxmatches;
+ timeval timelimit;
+ void* searchparams1;
+ size_t sizeofsearchparams1;
+ void* searchparams2;
+ size_t sizeofsearchparams2;
+ attrlist searchattrs;
+}
+
+struct searchstate
+{
+ uint ss_union_flags;
+ uint ss_union_layer;
+ ubyte[548] ss_fsstate;
+}
+static assert(searchstate.sizeof == uint.sizeof * 2 + searchstate.ss_fsstate.sizeof,
+ "searchstate struct must be packed");
+
+enum FST_EOF = -1;
+
+@betterC @nogc nothrow pure @safe unittest
+{
+ // Use an enum instead of `version (Darwin)` so it works with the betterc test extractor.
+ version (OSX) enum isDarwin = true;
+ else version (iOS) enum isDarwin = true;
+ else version (TVOS) enum isDarwin = true;
+ else version (WatchOS) enum isDarwin = true;
+ else enum isDarwin = false;
+ static if (isDarwin)
+ {
+ // Verify that these types don't need __initZ and so can be used in betterC.
+ attrlist al;
+ attribute_set_t as;
+ attrreference_t ar;
+ diskextent de;
+ vol_capabilities_attr_t vca;
+ vol_attributes_attr_t vaa;
+ fssearchblock fsb;
+ searchstate ss;
+ }
+}
diff --git a/libphobos/libdruntime/core/sys/darwin/sys/sysctl.d b/libphobos/libdruntime/core/sys/darwin/sys/sysctl.d
new file mode 100644
index 0000000..6af16cc8
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/darwin/sys/sysctl.d
@@ -0,0 +1,253 @@
+/**
+ * D header file for Darwin sys/sysctl.h
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.darwin.sys.sysctl;
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (Darwin):
+extern (C):
+nothrow:
+@nogc:
+
+// Top-level identifiers
+enum
+{
+ CTL_UNSPEC = 0,
+ CTL_KERN = 1,
+ CTL_VM = 2,
+ CTL_VFS = 3,
+ CTL_NET = 4,
+ CTL_DEBUG = 5,
+ CTL_HW = 6,
+ CTL_MACHDEP = 7,
+ CTL_USER = 8,
+ CTL_MAXID = 9,
+}
+
+// CTL_KERN identifiers
+enum
+{
+ KERN_OSTYPE = 1,
+ KERN_OSRELEASE = 2,
+ KERN_OSREV = 3,
+ KERN_VERSION = 4,
+ KERN_MAXVNODES = 5,
+ KERN_MAXPROC = 6,
+ KERN_MAXFILES = 7,
+ KERN_ARGMAX = 8,
+ KERN_SECURELVL = 9,
+ KERN_HOSTNAME = 10,
+ KERN_HOSTID = 11,
+ KERN_CLOCKRATE = 12,
+ KERN_VNODE = 13,
+ KERN_PROC = 14,
+ KERN_FILE = 15,
+ KERN_PROF = 16,
+ KERN_POSIX1 = 17,
+ KERN_NGROUPS = 18,
+ KERN_JOB_CONTROL = 19,
+ KERN_SAVED_IDS = 20,
+ KERN_BOOTTIME = 21,
+ KERN_NISDOMAINNAME = 22,
+ KERN_DOMAINNAME = KERN_NISDOMAINNAME,
+ KERN_MAXPARTITIONS = 23,
+ KERN_KDEBUG = 24,
+ KERN_UPDATEINTERVAL = 25,
+ KERN_OSRELDATE = 26,
+ KERN_NTP_PLL = 27,
+ KERN_BOOTFILE = 28,
+ KERN_MAXFILESPERPROC = 29,
+ KERN_MAXPROCPERUID = 30,
+ KERN_DUMPDEV = 31,
+ KERN_IPC = 32,
+ KERN_DUMMY = 33,
+ KERN_PS_STRINGS = 34,
+ KERN_USRSTACK32 = 35,
+ KERN_LOGSIGEXIT = 36,
+ KERN_SYMFILE = 37,
+ KERN_PROCARGS = 38,
+ KERN_NETBOOT = 40,
+ KERN_SYSV = 42,
+ KERN_AFFINITY = 43,
+ KERN_TRANSLATE = 44,
+ KERN_CLASSIC = KERN_TRANSLATE,
+ KERN_EXEC = 45,
+ KERN_CLASSICHANDLER = KERN_EXEC,
+ KERN_AIOMAX = 46,
+ KERN_AIOPROCMAX = 47,
+ KERN_AIOTHREADS = 48,
+ KERN_PROCARGS2 = 49,
+ KERN_COREFILE = 50,
+ KERN_COREDUMP = 51,
+ KERN_SUGID_COREDUMP = 52,
+ KERN_PROCDELAYTERM = 53,
+ KERN_SHREG_PRIVATIZABLE = 54,
+ KERN_LOW_PRI_WINDOW = 56,
+ KERN_LOW_PRI_DELAY = 57,
+ KERN_POSIX = 58,
+ KERN_USRSTACK64 = 59,
+ KERN_NX_PROTECTION = 60,
+ KERN_TFP = 61,
+ KERN_PROCNAME = 62,
+ KERN_THALTSTACK = 63,
+ KERN_SPECULATIVE_READS = 64,
+ KERN_OSVERSION = 65,
+ KERN_SAFEBOOT = 66,
+ KERN_RAGEVNODE = 68,
+ KERN_TTY = 69,
+ KERN_CHECKOPENEVT = 70,
+ KERN_THREADNAME = 71,
+ KERN_MAXID = 72,
+}
+
+// KERN_RAGEVNODE types
+enum
+{
+ KERN_RAGE_PROC = 1,
+ KERN_RAGE_THREAD = 2,
+ KERN_UNRAGE_PROC = 3,
+ KERN_UNRAGE_THREAD = 4,
+}
+
+// KERN_OPENEVT types
+enum
+{
+ KERN_OPENEVT_PROC = 1,
+ KERN_UNOPENEVT_PROC = 2,
+}
+
+// KERN_TFP types
+enum
+{
+ KERN_TFP_POLICY = 1,
+}
+
+// KERN_TFP_POLICY values
+enum
+{
+ KERN_TFP_POLICY_DENY = 0,
+ KERN_TFP_POLICY_DEFAULT = 2,
+}
+
+// KERN_PROC subtypes
+enum
+{
+ KERN_PROC_ALL = 0,
+ KERN_PROC_PID = 1,
+ KERN_PROC_PGRP = 2,
+ KERN_PROC_SESSION = 3,
+ KERN_PROC_TTY = 4,
+ KERN_PROC_UID = 5,
+ KERN_PROC_RUID = 6,
+ KERN_PROC_LCID = 7,
+}
+
+// KERN_VFSNSPACE subtypes
+enum
+{
+ KERN_VFSNSPACE_HANDLE_PROC = 1,
+ KERN_VFSNSPACE_UNHANDLE_PROC = 2,
+}
+
+// KERN_IPC identifiers
+enum
+{
+ KIPC_MAXSOCKBUF = 1,
+ KIPC_SOCKBUF_WASTE = 2,
+ KIPC_SOMAXCONN = 3,
+ KIPC_MAX_LINKHDR = 4,
+ KIPC_MAX_PROTOHDR = 5,
+ KIPC_MAX_HDR = 6,
+ KIPC_MAX_DATALEN = 7,
+ KIPC_MBSTAT = 8,
+ KIPC_NMBCLUSTERS = 9,
+ KIPC_SOQLIMITCOMPAT = 10,
+}
+
+// CTL_VM identifiers
+enum
+{
+ VM_METER = 1,
+ VM_LOADAVG = 2,
+ VM_MACHFACTOR = 4,
+ VM_SWAPUSAGE = 5,
+ VM_MAXID = 6,
+}
+
+// CTL_HW identifiers
+enum
+{
+ HW_MACHINE = 1,
+ HW_MODEL = 2,
+ HW_NCPU = 3,
+ HW_BYTEORDER = 4,
+ HW_PHYSMEM = 5,
+ HW_USERMEM = 6,
+ HW_PAGESIZE = 7,
+ HW_DISKNAMES = 8,
+ HW_DISKSTATS = 9,
+ HW_EPOCH = 10,
+ HW_FLOATINGPT = 11,
+ HW_MACHINE_ARCH = 12,
+ HW_VECTORUNIT = 13,
+ HW_BUS_FREQ = 14,
+ HW_CPU_FREQ = 15,
+ HW_CACHELINE = 16,
+ HW_L1ICACHESIZE = 17,
+ HW_L1DCACHESIZE = 18,
+ HW_L2SETTINGS = 19,
+ HW_L2CACHESIZE = 20,
+ HW_L3SETTINGS = 21,
+ HW_L3CACHESIZE = 22,
+ HW_TB_FREQ = 23,
+ HW_MEMSIZE = 24,
+ HW_AVAILCPU = 25,
+ HW_MAXID = 26,
+}
+
+// CTL_USER identifiers
+enum
+{
+ USER_CS_PATH = 1,
+ USER_BC_BASE_MAX = 2,
+ USER_BC_DIM_MAX = 3,
+ USER_BC_SCALE_MAX = 4,
+ USER_BC_STRING_MAX = 5,
+ USER_COLL_WEIGHTS_MAX = 6,
+ USER_EXPR_NEST_MAX = 7,
+ USER_LINE_MAX = 8,
+ USER_RE_DUP_MAX = 9,
+ USER_POSIX2_VERSION = 10,
+ USER_POSIX2_C_BIND = 11,
+ USER_POSIX2_C_DEV = 12,
+ USER_POSIX2_CHAR_TERM = 13,
+ USER_POSIX2_FORT_DEV = 14,
+ USER_POSIX2_FORT_RUN = 15,
+ USER_POSIX2_LOCALEDEF = 16,
+ USER_POSIX2_SW_DEV = 17,
+ USER_POSIX2_UPE = 18,
+ USER_STREAM_MAX = 19,
+ USER_TZNAME_MAX = 20,
+ USER_MAXID = 21,
+}
+
+///
+int sysctl(const int* name, uint namelen, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
+///
+int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
+///
+int sysctlnametomib(const char* sname, int* name, size_t* namelenp);
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d b/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d
index 3ffa1b9..2c5d8d7 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d
@@ -50,7 +50,7 @@ struct Dl_info {
void *dli_fbase; /* Base address of shared object. */
const(char) *dli_sname; /* Name of nearest symbol. */
void *dli_saddr; /* Address of nearest symbol. */
-};
+}
/*
@@ -59,13 +59,13 @@ struct Dl_info {
struct Dl_serpath {
char * dls_name; /* single search path entry */
uint dls_flags; /* path information */
-};
+}
struct Dl_serinfo {
size_t dls_size; /* total buffer size */
uint dls_cnt; /* number of path entries */
Dl_serpath[1] dls_serpath; /* there may be more than one */
-};
+}
/*-
* The actual type declared by this typedef is immaterial, provided that
@@ -78,20 +78,17 @@ struct Dl_serinfo {
*/
struct __dlfunc_arg {
int __dlfunc_dummy;
-};
+}
alias dlfunc_t = void function(__dlfunc_arg);
-private template __externC(RT, P...)
-{
- alias __externC = extern(C) RT function(P) nothrow @nogc @system;
-}
-
/* XSI functions first. */
-static assert(is(typeof(&dlclose) == __externC!(int, void*)));
-static assert(is(typeof(&dlerror) == __externC!(char*)));
-static assert(is(typeof(&dlopen) == __externC!(void*, const char*, int)));
-static assert(is(typeof(&dlsym) == __externC!(void*, void*, const char*)));
+extern(C) {
+ static assert(is(typeof(&dlclose) == int function(void*)));
+ static assert(is(typeof(&dlerror) == char* function()));
+ static assert(is(typeof(&dlopen) == void* function(const scope char*, int)));
+ static assert(is(typeof(&dlsym) == void* function(void*, const scope char*)));
+}
void* fdlopen(int, int);
int dladdr(const(void)*, Dl_info*);
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/err.d b/libphobos/libdruntime/core/sys/dragonflybsd/err.d
new file mode 100644
index 0000000..c3693f8
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/err.d
@@ -0,0 +1,31 @@
+/**
+ * D header file for DragonFlyBSD err.h.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Ernesto Castellotti
+ */
+module core.sys.dragonflybsd.err;
+import core.stdc.stdarg : va_list;
+
+version (DragonFlyBSD):
+extern (C):
+nothrow:
+@nogc:
+
+alias ExitFunction = void function(int);
+
+void err(int eval, scope const char* fmt, ...);
+void errc(int eval, int code, scope const char* fmt, ...);
+void errx(int eval, scope const char* fmt, ...);
+void warn(scope const char* fmt, ...);
+void warnc(int code, scope const char* fmt, ...);
+void warnx(scope const char* fmt, ...);
+void verr(int eval, scope const char* fmt, va_list args);
+void verrc(int eval, int code, scope const char* fmt, va_list args);
+void verrx(int eval, scope const char* fmt, va_list args);
+void vwarn(scope const char* fmt, va_list args);
+void vwarnc(int code, scope const char* fmt, va_list args);
+void vwarnx(scope const char* fmt, va_list args);
+void err_set_file(void* vfp);
+void err_set_exit(ExitFunction exitf);
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d b/libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d
index c771dc1..b052816 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d
@@ -264,34 +264,34 @@ struct ip_mreq
{
in_addr imr_multiaddr;
in_addr imr_interface;
-};
+}
struct ip_mreqn
{
in_addr imr_multiaddr;
in_addr imr_address;
int imr_ifindex;
-};
+}
struct ip_mreq_source
{
in_addr imr_multiaddr;
in_addr imr_sourceaddr;
in_addr imr_interface;
-};
+}
struct group_req
{
uint gr_interface;
sockaddr_storage gr_group;
-};
+}
struct group_source_req
{
uint gsr_interface;
sockaddr_storage gsr_group;
sockaddr_storage gsr_source;
-};
+}
int setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*);
int getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*);
@@ -450,13 +450,13 @@ struct in6_pktinfo
{
in6_addr ipi6_addr;
uint ipi6_ifindex;
-};
+}
struct ip6_mtuinfo
{
sockaddr_in6 ip6m_addr;
uint ip6m_mtu;
-};
+}
enum IPV6_PORTRANGE_DEFAULT = 0;
enum IPV6_PORTRANGE_HIGH = 1;
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/stdlib.d b/libphobos/libdruntime/core/sys/dragonflybsd/stdlib.d
new file mode 100644
index 0000000..8936701
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/stdlib.d
@@ -0,0 +1,17 @@
+/**
+ * D header file for DragonFlyBSD stdlib.h.
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.dragonflybsd.stdlib;
+public import core.sys.posix.stdlib;
+
+version (DragonFlyBSD):
+extern (C):
+nothrow:
+@nogc:
+
+const(char)* getprogname();
+void setprogname(scope const char* name);
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d
index 88f7e06..5dad964 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d
@@ -58,7 +58,7 @@ struct r_debug
int r_version;
link_map* r_map;
void function(r_debug*, link_map*) r_brk;
-};
+}
struct dl_phdr_info
{
@@ -70,7 +70,7 @@ struct dl_phdr_info
uint64_t dlpi_subs;
size_t dlpi_tls_modid;
void* dlpi_tls_data;
-};
+}
private alias int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/sys/sysctl.d b/libphobos/libdruntime/core/sys/dragonflybsd/sys/sysctl.d
new file mode 100644
index 0000000..932082f
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/sys/sysctl.d
@@ -0,0 +1,199 @@
+/**
+ * D header file for DragonFlyBSD sys/sysctl.h
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.dragonflybsd.sys.sysctl;
+
+version (DragonFlyBSD):
+extern (C):
+nothrow:
+@nogc:
+
+// Top-level identifiers
+enum
+{
+ CTL_SYSCTL = 0,
+ CTL_KERN = 1,
+ CTL_VM = 2,
+ CTL_VFS = 3,
+ CTL_NET = 4,
+ CTL_DEBUG = 5,
+ CTL_HW = 6,
+ CTL_MACHDEP = 7,
+ CTL_USER = 8,
+ CTL_P1003_1B = 9,
+ CTL_LWKT = 10,
+ CTL_MAXID = 11,
+}
+
+// CTL_SYSCTL identifiers
+enum
+{
+ CTL_SYSCTL_DEBUG = 0,
+ CTL_SYSCTL_NAME = 1,
+ CTL_SYSCTL_NEXT = 2,
+ CTL_SYSCTL_NAME2OID = 3,
+ CTL_SYSCTL_OIDFMT = 4,
+ CTL_SYSCTL_OIDDESCR = 5,
+}
+
+// CTL_KERN identifiers
+enum
+{
+ KERN_OSTYPE = 1,
+ KERN_OSRELEASE = 2,
+ KERN_OSREV = 3,
+ KERN_VERSION = 4,
+ KERN_MAXVNODES = 5,
+ KERN_MAXPROC = 6,
+ KERN_MAXFILES = 7,
+ KERN_ARGMAX = 8,
+ KERN_SECURELVL = 9,
+ KERN_HOSTNAME = 10,
+ KERN_HOSTID = 11,
+ KERN_CLOCKRATE = 12,
+ KERN_VNODE = 13,
+ KERN_PROC = 14,
+ KERN_FILE = 15,
+ KERN_POSIX1 = 17,
+ KERN_NGROUPS = 18,
+ KERN_JOB_CONTROL = 19,
+ KERN_SAVED_IDS = 20,
+ KERN_BOOTTIME = 21,
+ KERN_NISDOMAINNAME = 22,
+ KERN_UPDATEINTERVAL = 23,
+ KERN_OSRELDATE = 24,
+ KERN_NTP_PLL = 25,
+ KERN_BOOTFILE = 26,
+ KERN_MAXFILESPERPROC = 27,
+ KERN_MAXPROCPERUID = 28,
+ KERN_DUMPDEV = 29,
+ KERN_IPC = 30,
+ KERN_DUMMY = 31,
+ KERN_PS_STRINGS = 32,
+ KERN_USRSTACK = 33,
+ KERN_LOGSIGEXIT = 34,
+ KERN_IOV_MAX = 35,
+ KERN_MAXPOSIXLOCKSPERUID = 36,
+ KERN_MAXID = 37,
+}
+
+// KERN_PROC subtypes
+enum
+{
+ KERN_PROC_ALL = 0,
+ KERN_PROC_PID = 1,
+ KERN_PROC_PGRP = 2,
+ KERN_PROC_SESSION = 3,
+ KERN_PROC_TTY = 4,
+ KERN_PROC_UID = 5,
+ KERN_PROC_RUID = 6,
+ KERN_PROC_ARGS = 7,
+ KERN_PROC_CWD = 8,
+ KERN_PROC_PATHNAME = 9,
+ KERN_PROC_SIGTRAMP = 10,
+ KERN_PROC_FLAGMASK = 0x10,
+ KERN_PROC_FLAG_LWP = 0x10,
+}
+
+// KERN_IPC identifiers
+enum
+{
+ KIPC_MAXSOCKBUF = 1,
+ KIPC_SOCKBUF_WASTE = 2,
+ KIPC_SOMAXCONN = 3,
+ KIPC_MAX_LINKHDR = 4,
+ KIPC_MAX_PROTOHDR = 5,
+ KIPC_MAX_HDR = 6,
+ KIPC_MAX_DATALEN = 7,
+ KIPC_MBSTAT = 8,
+ KIPC_NMBCLUSTERS = 9,
+}
+
+// CTL_HW identifiers
+enum
+{
+ HW_MACHINE = 1,
+ HW_MODEL = 2,
+ HW_NCPU = 3,
+ HW_BYTEORDER = 4,
+ HW_PHYSMEM = 5,
+ HW_USERMEM = 6,
+ HW_PAGESIZE = 7,
+ HW_DISKNAMES = 8,
+ HW_DISKSTATS = 9,
+ HW_FLOATINGPT = 10,
+ HW_MACHINE_ARCH = 11,
+ HW_MACHINE_PLATFORM = 12,
+ HW_SENSORS = 13,
+ HW_MAXID = 14,
+}
+
+// CTL_USER definitions
+enum
+{
+ USER_CS_PATH = 1,
+ USER_BC_BASE_MAX = 2,
+ USER_BC_DIM_MAX = 3,
+ USER_BC_SCALE_MAX = 4,
+ USER_BC_STRING_MAX = 5,
+ USER_COLL_WEIGHTS_MAX = 6,
+ USER_EXPR_NEST_MAX = 7,
+ USER_LINE_MAX = 8,
+ USER_RE_DUP_MAX = 9,
+ USER_POSIX2_VERSION = 10,
+ USER_POSIX2_C_BIND = 11,
+ USER_POSIX2_C_DEV = 12,
+ USER_POSIX2_CHAR_TERM = 13,
+ USER_POSIX2_FORT_DEV = 14,
+ USER_POSIX2_FORT_RUN = 15,
+ USER_POSIX2_LOCALEDEF = 16,
+ USER_POSIX2_SW_DEV = 17,
+ USER_POSIX2_UPE = 18,
+ USER_STREAM_MAX = 19,
+ USER_TZNAME_MAX = 20,
+ USER_MAXID = 21,
+}
+
+// POSIX 1003.1B definitions
+enum
+{
+ CTL_P1003_1B_ASYNCHRONOUS_IO = 1,
+ CTL_P1003_1B_MAPPED_FILES = 2,
+ CTL_P1003_1B_MEMLOCK = 3,
+ CTL_P1003_1B_MEMLOCK_RANGE = 4,
+ CTL_P1003_1B_MEMORY_PROTECTION = 5,
+ CTL_P1003_1B_MESSAGE_PASSING = 6,
+ CTL_P1003_1B_PRIORITIZED_IO = 7,
+ CTL_P1003_1B_PRIORITY_SCHEDULING = 8,
+ CTL_P1003_1B_REALTIME_SIGNALS = 9,
+ CTL_P1003_1B_SEMAPHORES = 10,
+ CTL_P1003_1B_FSYNC = 11,
+ CTL_P1003_1B_SHARED_MEMORY_OBJECTS = 12,
+ CTL_P1003_1B_SYNCHRONIZED_IO = 13,
+ CTL_P1003_1B_TIMERS = 14,
+ CTL_P1003_1B_AIO_LISTIO_MAX = 15,
+ CTL_P1003_1B_AIO_MAX = 16,
+ CTL_P1003_1B_AIO_PRIO_DELTA_MAX = 17,
+ CTL_P1003_1B_DELAYTIMER_MAX = 18,
+ CTL_P1003_1B_UNUSED19 = 19,
+ CTL_P1003_1B_PAGESIZE = 20,
+ CTL_P1003_1B_RTSIG_MAX = 21,
+ CTL_P1003_1B_SEM_NSEMS_MAX = 22,
+ CTL_P1003_1B_UNUSED23 = 23,
+ CTL_P1003_1B_SIGQUEUE_MAX = 24,
+ CTL_P1003_1B_TIMER_MAX = 25,
+ CTL_P1003_1B_MAXID = 26,
+}
+
+///
+int sysctl(const int* name, uint namelen, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
+///
+int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
+///
+int sysctlnametomib(const char* name, int* mibp, size_t* sizep);
diff --git a/libphobos/libdruntime/core/sys/freebsd/dlfcn.d b/libphobos/libdruntime/core/sys/freebsd/dlfcn.d
index 95b6c1d..7baacfe 100644
--- a/libphobos/libdruntime/core/sys/freebsd/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/freebsd/dlfcn.d
@@ -54,7 +54,7 @@ static if (__BSD_VISIBLE)
void *dli_fbase; /* Base address of shared object. */
const(char) *dli_sname; /* Name of nearest symbol. */
void *dli_saddr; /* Address of nearest symbol. */
- };
+ }
/*-
* The actual type declared by this typedef is immaterial, provided that
@@ -67,7 +67,7 @@ static if (__BSD_VISIBLE)
*/
struct __dlfunc_arg {
int __dlfunc_dummy;
- };
+ }
alias dlfunc_t = void function(__dlfunc_arg);
@@ -77,21 +77,21 @@ static if (__BSD_VISIBLE)
struct Dl_serpath {
char * dls_name; /* single search path entry */
uint dls_flags; /* path information */
- };
+ }
struct Dl_serinfo {
size_t dls_size; /* total buffer size */
uint dls_cnt; /* number of path entries */
Dl_serpath[1] dls_serpath; /* there may be more than one */
- };
+ }
}
/* XSI functions first. */
extern(C) {
static assert(is(typeof(&dlclose) == int function(void*)));
static assert(is(typeof(&dlerror) == char* function()));
- static assert(is(typeof(&dlopen) == void* function(in char*, int)));
- static assert(is(typeof(&dlsym) == void* function(void*, in char*)));
+ static assert(is(typeof(&dlopen) == void* function(const scope char*, int)));
+ static assert(is(typeof(&dlsym) == void* function(void*, const scope char*)));
}
static if (__BSD_VISIBLE)
diff --git a/libphobos/libdruntime/core/sys/freebsd/err.d b/libphobos/libdruntime/core/sys/freebsd/err.d
new file mode 100644
index 0000000..8937e0e
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/err.d
@@ -0,0 +1,31 @@
+/**
+ * D header file for FreeBSD err.h.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Ernesto Castellotti
+ */
+module core.sys.freebsd.err;
+import core.stdc.stdarg : va_list;
+
+version (FreeBSD):
+extern (C):
+nothrow:
+@nogc:
+
+alias ExitFunction = void function(int);
+
+void err(int eval, scope const char* fmt, ...);
+void errc(int eval, int code, scope const char* fmt, ...);
+void errx(int eval, scope const char* fmt, ...);
+void warn(scope const char* fmt, ...);
+void warnc(int code, scope const char* fmt, ...);
+void warnx(scope const char* fmt, ...);
+void verr(int eval, scope const char* fmt, va_list args);
+void verrc(int eval, int code, scope const char* fmt, va_list args);
+void verrx(int eval, scope const char* fmt, va_list args);
+void vwarn(scope const char* fmt, va_list args);
+void vwarnc(int code, scope const char* fmt, va_list args);
+void vwarnx(scope const char* fmt, va_list args);
+void err_set_file(void* vfp);
+void err_set_exit(ExitFunction exitf);
diff --git a/libphobos/libdruntime/core/sys/freebsd/execinfo.d b/libphobos/libdruntime/core/sys/freebsd/execinfo.d
index 125ef09..d324084 100644
--- a/libphobos/libdruntime/core/sys/freebsd/execinfo.d
+++ b/libphobos/libdruntime/core/sys/freebsd/execinfo.d
@@ -14,6 +14,8 @@ nothrow:
version (GNU)
version = BacktraceExternal;
+version (LDC)
+ version = BacktraceExternal;
version (BacktraceExternal)
{
diff --git a/libphobos/libdruntime/core/sys/freebsd/netinet/in_.d b/libphobos/libdruntime/core/sys/freebsd/netinet/in_.d
index af6a077..bce1791 100644
--- a/libphobos/libdruntime/core/sys/freebsd/netinet/in_.d
+++ b/libphobos/libdruntime/core/sys/freebsd/netinet/in_.d
@@ -268,34 +268,34 @@ static if (__BSD_VISIBLE)
{
in_addr imr_multiaddr;
in_addr imr_interface;
- };
+ }
struct ip_mreqn
{
in_addr imr_multiaddr;
in_addr imr_address;
int imr_ifindex;
- };
+ }
struct ip_mreq_source
{
in_addr imr_multiaddr;
in_addr imr_sourceaddr;
in_addr imr_interface;
- };
+ }
struct group_req
{
uint gr_interface;
sockaddr_storage gr_group;
- };
+ }
struct group_source_req
{
uint gsr_interface;
sockaddr_storage gsr_group;
sockaddr_storage gsr_source;
- };
+ }
int setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*);
int getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*);
@@ -463,13 +463,13 @@ static if (__POSIX_VISIBLE)
{
in6_addr ipi6_addr;
uint ipi6_ifindex;
- };
+ }
struct ip6_mtuinfo
{
sockaddr_in6 ip6m_addr;
uint ip6m_mtu;
- };
+ }
enum IPV6_PORTRANGE_DEFAULT = 0;
enum IPV6_PORTRANGE_HIGH = 1;
diff --git a/libphobos/libdruntime/core/sys/freebsd/stdlib.d b/libphobos/libdruntime/core/sys/freebsd/stdlib.d
new file mode 100644
index 0000000..bf93c3a
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/stdlib.d
@@ -0,0 +1,17 @@
+/**
+ * D header file for FreeBSD stdlib.h.
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.freebsd.stdlib;
+public import core.sys.posix.stdlib;
+
+version (FreeBSD):
+extern (C):
+nothrow:
+@nogc:
+
+const(char)* getprogname();
+void setprogname(scope const char* name);
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/event.d b/libphobos/libdruntime/core/sys/freebsd/sys/event.d
index 8ac7c3b..7f57862 100644
--- a/libphobos/libdruntime/core/sys/freebsd/sys/event.d
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/event.d
@@ -161,6 +161,23 @@ enum
}
int kqueue();
-int kevent(int kq, const kevent_t *changelist, int nchanges,
- kevent_t *eventlist, int nevents,
- const timespec *timeout);
+
+version (GNU)
+{
+ int kevent(int kq, const kevent_t *changelist, int nchanges,
+ kevent_t *eventlist, int nevents,
+ const timespec *timeout);
+}
+else
+{
+ static if (__FreeBSD_version >= 1200000)
+ pragma(mangle, "kevent@@FBSD_1.5")
+ int kevent(int kq, const kevent_t *changelist, int nchanges,
+ kevent_t *eventlist, int nevents,
+ const timespec *timeout);
+ else
+ pragma(mangle, "kevent@FBSD_1.0")
+ int kevent(int kq, const kevent_t *changelist, int nchanges,
+ kevent_t *eventlist, int nevents,
+ const timespec *timeout);
+}
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d
index 97e7cfa..d743d51 100644
--- a/libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d
@@ -56,7 +56,7 @@ struct r_debug
int r_version;
link_map* r_map;
void function(r_debug*, link_map*) r_brk;
-};
+}
struct dl_phdr_info
{
@@ -68,7 +68,7 @@ struct dl_phdr_info
uint64_t dlpi_subs;
size_t dlpi_tls_modid;
void* dlpi_tls_data;
-};
+}
private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/mount.d b/libphobos/libdruntime/core/sys/freebsd/sys/mount.d
index e45c460..1b0f042 100644
--- a/libphobos/libdruntime/core/sys/freebsd/sys/mount.d
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/mount.d
@@ -298,17 +298,47 @@ enum uint VQ_FLAG2000 = 0x2000;
enum uint VQ_FLAG4000 = 0x4000;
enum uint VQ_FLAG8000 = 0x8000;
-int fhopen(const fhandle_t*, int);
-int fhstat(const fhandle_t*, stat_t*);
-int fhstatfs(const fhandle_t*, statfs_t*);
-int fstatfs(int, statfs_t*);
-int getfh(const char*, fhandle_t*);
-int getfsstat(statfs_t*, c_long, int);
-int getmntinfo(statfs_t**, int);
-int lgetfh(const char*, fhandle_t*);
-int mount(const char*, const char*, int, void*);
-//int nmount(iovec*, uint, int);
-int statfs(const char*, statfs_t*);
-int unmount(const char*, int);
-
-//int getvfsbyname(const char*, xvfsconf*);
+version (GNU)
+{
+ int fhopen(const fhandle_t*, int);
+ int fhstat(const fhandle_t*, stat_t*);
+ int fhstatfs(const fhandle_t*, statfs_t*);
+ int fstatfs(int, statfs_t*);
+ int getfh(const char*, fhandle_t*);
+ int getfsstat(statfs_t*, c_long, int);
+ int getmntinfo(statfs_t**, int);
+ int lgetfh(const char*, fhandle_t*);
+ int mount(const char*, const char*, int, void*);
+ //int nmount(iovec*, uint, int);
+ int statfs(const char*, statfs_t*);
+ int unmount(const char*, int);
+ //int getvfsbyname(const char*, xvfsconf*);
+}
+else
+{
+ static if (__FreeBSD_version >= 1200000)
+ {
+ pragma(mangle, "fhstat@FBSD_1.5") int fhstat(const fhandle_t*, stat_t*);
+ pragma(mangle, "fhstatfs@FBSD_1.5") int fhstatfs(const fhandle_t*, statfs_t*);
+ pragma(mangle, "fstatfs@FBSD_1.5") int fstatfs(int, statfs_t*);
+ pragma(mangle, "getfsstat@FBSD_1.5") int getfsstat(statfs_t*, c_long, int);
+ pragma(mangle, "getmntinfo@FBSD_1.5") int getmntinfo(statfs_t**, int);
+ pragma(mangle, "statfs@FBSD_1.5") int statfs(const char*, statfs_t*);
+ }
+ else
+ {
+ pragma(mangle, "fhstat@FBSD_1.0") int fhstat(const fhandle_t*, stat_t*);
+ pragma(mangle, "fhstatfs@FBSD_1.0") int fhstatfs(const fhandle_t*, statfs_t*);
+ pragma(mangle, "fstatfs@FBSD_1.0") int fstatfs(int, statfs_t*);
+ pragma(mangle, "getfsstat@FBSD_1.0") int getfsstat(statfs_t*, c_long, int);
+ pragma(mangle, "getmntinfo@FBSD_1.0") int getmntinfo(statfs_t**, int);
+ pragma(mangle, "statfs@FBSD_1.0") int statfs(const char*, statfs_t*);
+ }
+ pragma(mangle, "fhopen@@FBSD_1.0") int fhopen(const fhandle_t*, int);
+ pragma(mangle, "getfh@@FBSD_1.0") int getfh(const char*, fhandle_t*);
+ pragma(mangle, "lgetfh@@FBSD_1.0") int lgetfh(const char*, fhandle_t*);
+ pragma(mangle, "mount@@FBSD_1.0") int mount(const char*, const char*, int, void*);
+ //int nmount(iovec*, uint, int);
+ pragma(mangle, "unmount@@FBSD_1.0") int unmount(const char*, int);
+ //int getvfsbyname(const char*, xvfsconf*);
+}
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/sysctl.d b/libphobos/libdruntime/core/sys/freebsd/sys/sysctl.d
new file mode 100644
index 0000000..b9b3e93
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/sysctl.d
@@ -0,0 +1,211 @@
+/**
+ * D header file for FreeBSD sys/sysctl.h
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.freebsd.sys.sysctl;
+
+version (FreeBSD):
+extern (C):
+nothrow:
+@nogc:
+
+// Top-level identifiers
+enum
+{
+ CTL_SYSCTL = 0,
+ CTL_KERN = 1,
+ CTL_VM = 2,
+ CTL_VFS = 3,
+ CTL_NET = 4,
+ CTL_DEBUG = 5,
+ CTL_HW = 6,
+ CTL_MACHDEP = 7,
+ CTL_USER = 8,
+ CTL_P1003_1B = 9,
+}
+
+// CTL_SYSCTL identifiers
+enum
+{
+ CTL_SYSCTL_DEBUG = 0,
+ CTL_SYSCTL_NAME = 1,
+ CTL_SYSCTL_NEXT = 2,
+ CTL_SYSCTL_NAME2OID = 3,
+ CTL_SYSCTL_OIDFMT = 4,
+ CTL_SYSCTL_OIDDESCR = 5,
+ CTL_SYSCTL_OIDLABEL = 6,
+}
+
+// CTL_KERN identifiers
+enum
+{
+ KERN_OSTYPE = 1,
+ KERN_OSRELEASE = 2,
+ KERN_OSREV = 3,
+ KERN_VERSION = 4,
+ KERN_MAXVNODES = 5,
+ KERN_MAXPROC = 6,
+ KERN_MAXFILES = 7,
+ KERN_ARGMAX = 8,
+ KERN_SECURELVL = 9,
+ KERN_HOSTNAME = 10,
+ KERN_HOSTID = 11,
+ KERN_CLOCKRATE = 12,
+ KERN_VNODE = 13,
+ KERN_PROC = 14,
+ KERN_FILE = 15,
+ KERN_PROF = 16,
+ KERN_POSIX1 = 17,
+ KERN_NGROUPS = 18,
+ KERN_JOB_CONTROL = 19,
+ KERN_SAVED_IDS = 20,
+ KERN_BOOTTIME = 21,
+ KERN_NISDOMAINNAME = 22,
+ KERN_UPDATEINTERVAL = 23,
+ KERN_OSRELDATE = 24,
+ KERN_NTP_PLL = 25,
+ KERN_BOOTFILE = 26,
+ KERN_MAXFILESPERPROC = 27,
+ KERN_MAXPROCPERUID = 28,
+ KERN_DUMPDEV = 29,
+ KERN_IPC = 30,
+ KERN_DUMMY = 31,
+ KERN_PS_STRINGS = 32,
+ KERN_USRSTACK = 33,
+ KERN_LOGSIGEXIT = 34,
+ KERN_IOV_MAX = 35,
+ KERN_HOSTUUID = 36,
+ KERN_ARND = 37,
+ KERN_MAXPHYS = 38,
+}
+
+// KERN_PROC subtypes
+enum
+{
+ KERN_PROC_ALL = 0,
+ KERN_PROC_PID = 1,
+ KERN_PROC_PGRP = 2,
+ KERN_PROC_SESSION = 3,
+ KERN_PROC_TTY = 4,
+ KERN_PROC_UID = 5,
+ KERN_PROC_RUID = 6,
+ KERN_PROC_ARGS = 7,
+ KERN_PROC_PROC = 8,
+ KERN_PROC_SV_NAME = 9,
+ KERN_PROC_RGID = 10,
+ KERN_PROC_GID = 11,
+ KERN_PROC_PATHNAME = 12,
+ KERN_PROC_OVMMAP = 13,
+ KERN_PROC_OFILEDESC = 14,
+ KERN_PROC_KSTACK = 15,
+ KERN_PROC_INC_THREAD = 0x10,
+ KERN_PROC_VMMAP = 32,
+ KERN_PROC_FILEDESC = 33,
+ KERN_PROC_GROUPS = 34,
+ KERN_PROC_ENV = 35,
+ KERN_PROC_AUXV = 36,
+ KERN_PROC_RLIMIT = 37,
+ KERN_PROC_PS_STRINGS = 38,
+ KERN_PROC_UMASK = 39,
+ KERN_PROC_OSREL = 40,
+ KERN_PROC_SIGTRAMP = 41,
+ KERN_PROC_CWD = 42,
+ KERN_PROC_NFDS = 43,
+}
+
+// KERN_IPC identifiers
+enum
+{
+ KIPC_MAXSOCKBUF = 1,
+ KIPC_SOCKBUF_WASTE = 2,
+ KIPC_SOMAXCONN = 3,
+ KIPC_MAX_LINKHDR = 4,
+ KIPC_MAX_PROTOHDR = 5,
+ KIPC_MAX_HDR = 6,
+ KIPC_MAX_DATALEN = 7,
+}
+
+// CTL_HW identifiers
+enum
+{
+ HW_MACHINE = 1,
+ HW_MODEL = 2,
+ HW_NCPU = 3,
+ HW_BYTEORDER = 4,
+ HW_PHYSMEM = 5,
+ HW_USERMEM = 6,
+ HW_PAGESIZE = 7,
+ HW_DISKNAMES = 8,
+ HW_DISKSTATS = 9,
+ HW_FLOATINGPT = 10,
+ HW_MACHINE_ARCH = 11,
+ HW_REALMEM = 12,
+}
+
+// CTL_USER identifiers
+enum
+{
+ USER_CS_PATH = 1,
+ USER_BC_BASE_MAX = 2,
+ USER_BC_DIM_MAX = 3,
+ USER_BC_SCALE_MAX = 4,
+ USER_BC_STRING_MAX = 5,
+ USER_COLL_WEIGHTS_MAX = 6,
+ USER_EXPR_NEST_MAX = 7,
+ USER_LINE_MAX = 8,
+ USER_RE_DUP_MAX = 9,
+ USER_POSIX2_VERSION = 10,
+ USER_POSIX2_C_BIND = 11,
+ USER_POSIX2_C_DEV = 12,
+ USER_POSIX2_CHAR_TERM = 13,
+ USER_POSIX2_FORT_DEV = 14,
+ USER_POSIX2_FORT_RUN = 15,
+ USER_POSIX2_LOCALEDEF = 16,
+ USER_POSIX2_SW_DEV = 17,
+ USER_POSIX2_UPE = 18,
+ USER_STREAM_MAX = 19,
+ USER_TZNAME_MAX = 20,
+}
+
+// POSIX 1003.1B definitions
+enum
+{
+ CTL_P1003_1B_ASYNCHRONOUS_IO = 1,
+ CTL_P1003_1B_MAPPED_FILES = 2,
+ CTL_P1003_1B_MEMLOCK = 3,
+ CTL_P1003_1B_MEMLOCK_RANGE = 4,
+ CTL_P1003_1B_MEMORY_PROTECTION = 5,
+ CTL_P1003_1B_MESSAGE_PASSING = 6,
+ CTL_P1003_1B_PRIORITIZED_IO = 7,
+ CTL_P1003_1B_PRIORITY_SCHEDULING = 8,
+ CTL_P1003_1B_REALTIME_SIGNALS = 9,
+ CTL_P1003_1B_SEMAPHORES = 10,
+ CTL_P1003_1B_FSYNC = 11,
+ CTL_P1003_1B_SHARED_MEMORY_OBJECTS = 12,
+ CTL_P1003_1B_SYNCHRONIZED_IO = 13,
+ CTL_P1003_1B_TIMERS = 14,
+ CTL_P1003_1B_AIO_LISTIO_MAX = 15,
+ CTL_P1003_1B_AIO_MAX = 16,
+ CTL_P1003_1B_AIO_PRIO_DELTA_MAX = 17,
+ CTL_P1003_1B_DELAYTIMER_MAX = 18,
+ CTL_P1003_1B_UNUSED19 = 19,
+ CTL_P1003_1B_PAGESIZE = 20,
+ CTL_P1003_1B_RTSIG_MAX = 21,
+ CTL_P1003_1B_SEM_NSEMS_MAX = 22,
+ CTL_P1003_1B_UNUSED23 = 23,
+ CTL_P1003_1B_SIGQUEUE_MAX = 24,
+ CTL_P1003_1B_TIMER_MAX = 25,
+ CTL_P1003_1B_MAXID = 26,
+}
+
+///
+int sysctl(const int* name, uint namelen, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
+///
+int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
+///
+int sysctlnametomib(const char* name, int* mibp, size_t* sizep);
diff --git a/libphobos/libdruntime/core/sys/linux/dlfcn.d b/libphobos/libdruntime/core/sys/linux/dlfcn.d
index f2decc2..a815d09 100644
--- a/libphobos/libdruntime/core/sys/linux/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/linux/dlfcn.d
@@ -9,6 +9,7 @@ version (linux):
extern (C):
nothrow:
@nogc:
+@system:
version (ARM) version = ARM_Any;
version (AArch64) version = ARM_Any;
@@ -236,14 +237,14 @@ static if (__USE_GNU)
enum LM_ID_NEWLM = -1;
}
-// void* dlopen(in char* __file, int __mode); // POSIX
+// void* dlopen(const scope char* __file, int __mode); // POSIX
// int dlclose(void* __handle); // POSIX
-// void* dlsym(void* __handle, in char* __name); // POSIX
+// void* dlsym(void* __handle, const scope char* __name); // POSIX
static if (__USE_GNU)
{
- void* dlmopen(Lmid_t __nsid, in char* __file, int __mode);
- void* dlvsym(void* __handle, in char* __name, in char* __version);
+ void* dlmopen(Lmid_t __nsid, const scope char* __file, int __mode);
+ void* dlvsym(void* __handle, const scope char* __name, const scope char* __version);
}
// char* dlerror(); // POSIX
@@ -258,7 +259,7 @@ static if (__USE_GNU)
void* dli_saddr;
}
- int dladdr(in void* __address, Dl_info* __info);
+ int dladdr(const scope void* __address, Dl_info* __info);
int dladdr1(void* __address, Dl_info* __info, void** __extra_info, int __flags);
enum
diff --git a/libphobos/libdruntime/core/sys/linux/elf.d b/libphobos/libdruntime/core/sys/linux/elf.d
index ab07ac9..4d0b227 100644
--- a/libphobos/libdruntime/core/sys/linux/elf.d
+++ b/libphobos/libdruntime/core/sys/linux/elf.d
@@ -9,6 +9,7 @@ version (linux):
extern (C):
pure:
nothrow:
+@system:
import core.stdc.stdint;
@@ -831,7 +832,6 @@ enum AT_EXECFN = 31;
enum AT_SYSINFO = 32;
enum AT_SYSINFO_EHDR = 33;
-;
enum AT_L1I_CACHESHAPE = 34;
enum AT_L1D_CACHESHAPE = 35;
enum AT_L2_CACHESHAPE = 36;
diff --git a/libphobos/libdruntime/core/sys/linux/epoll.d b/libphobos/libdruntime/core/sys/linux/epoll.d
index 4798967..f5ff7db 100644
--- a/libphobos/libdruntime/core/sys/linux/epoll.d
+++ b/libphobos/libdruntime/core/sys/linux/epoll.d
@@ -10,10 +10,13 @@ module core.sys.linux.epoll;
version (linux):
+import core.sys.posix.signal : sigset_t;
+
extern (C):
@system:
@nogc:
nothrow:
+@system:
version (ARM) version = ARM_Any;
version (AArch64) version = ARM_Any;
@@ -51,16 +54,19 @@ enum
EPOLLHUP = 0x010,
EPOLLRDHUP = 0x2000, // since Linux 2.6.17
EPOLLEXCLUSIVE = 1u << 28, // since Linux 4.5
+ EPOLLWAKEUP = 1u << 29,
EPOLLONESHOT = 1u << 30,
EPOLLET = 1u << 31
}
-/* Valid opcodes ( "op" parameter ) to issue to epoll_ctl(). */
+/**
+ * Valid opcodes ( "op" parameter ) to issue to epoll_ctl().
+ */
enum
{
- EPOLL_CTL_ADD = 1, // Add a file descriptor to the interface.
- EPOLL_CTL_DEL = 2, // Remove a file descriptor from the interface.
- EPOLL_CTL_MOD = 3, // Change file descriptor epoll_event structure.
+ EPOLL_CTL_ADD = 1, /// Add a file descriptor to the interface.
+ EPOLL_CTL_DEL = 2, /// Remove a file descriptor from the interface.
+ EPOLL_CTL_MOD = 3, /// Change file descriptor epoll_event structure.
}
version (X86_Any)
@@ -141,7 +147,82 @@ union epoll_data_t
ulong u64;
}
+/**
+ * Creates an epoll instance.
+ *
+ * Params:
+ * size = a hint specifying the number of file descriptors to be associated
+ * with the new instance. T
+ * Returns: an fd for the new instance. The fd returned by epoll_create() should
+ * be closed with close().
+ * See_also: epoll_create1 (int flags)
+ */
int epoll_create (int size);
+
+/* Same as epoll_create but with an FLAGS parameter. The unused SIZE
+ parameter has been dropped. */
+
+/**
+ * Creates an epoll instance.
+ *
+ * Params:
+ * flags = a specified flag. If flags is 0, then, other than the fact that the
+ * obsolete size argument is dropped, epoll_create1() is the same as
+ * epoll_create().
+ * Returns: an fd for the new instance. The fd returned by epoll_create() should
+ * be closed with close().
+ * See_also: epoll_create (int size)
+ */
int epoll_create1 (int flags);
+
+/**
+ * Manipulate an epoll instance
+ *
+ * Params:
+ * epfd = an epoll file descriptor instance
+ * op = one of the EPOLL_CTL_* constants
+ * fd = target file descriptor of the operation
+ * event = describes which events the caller is interested in and any
+ * associated user dat
+ * Returns: 0 in case of success, -1 in case of error ( the "errno" variable
+ * will contain the specific error code )
+ */
int epoll_ctl (int epfd, int op, int fd, epoll_event *event);
+
+
+/**
+ * Wait for events on an epoll instance.
+ *
+ *
+ * Params:
+ * epfd = an epoll file descriptor instance
+ * events = a buffer that will contain triggered events
+ * maxevents = the maximum number of events to be returned ( usually size of
+ * "events" )
+ * timeout = specifies the maximum wait time in milliseconds (-1 == infinite)
+ *
+ * Returns: the number of triggered events returned in "events" buffer. Or -1 in
+ * case of error with the "errno" variable set to the specific error
+ * code.
+ */
int epoll_wait (int epfd, epoll_event *events, int maxevents, int timeout);
+
+/**
+ * Wait for events on an epoll instance
+ *
+ *
+ * Params:
+ * epfd = an epoll file descriptor instance
+ * events = a buffer that will contain triggered events
+ * maxevents = the maximum number of events to be returned ( usually size of
+ * "events" )
+ * timeout = specifies the maximum wait time in milliseconds (-1 == infinite)
+ * ss = a signal set. May be specified as `null`, in which case epoll_pwait() is
+ * equivalent to epoll_wait().
+ *
+ * Returns: the number of triggered events returned in "events" buffer. Or -1 in
+ * case of error with the "errno" variable set to the specific error
+ * code.
+ */
+int epoll_pwait (int epfd, epoll_event *events, int maxevents, int timeout,
+ const sigset_t *ss);
diff --git a/libphobos/libdruntime/core/sys/linux/err.d b/libphobos/libdruntime/core/sys/linux/err.d
new file mode 100644
index 0000000..be5378d
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/linux/err.d
@@ -0,0 +1,24 @@
+/**
+ * D header file for Linux err.h.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Ernesto Castellotti
+ */
+module core.sys.linux.err;
+import core.stdc.stdarg : va_list;
+
+version (linux):
+extern (C):
+nothrow:
+@nogc:
+@system:
+
+void err(int eval, scope const char* fmt, ...);
+void errx(int eval, scope const char* fmt, ...);
+void warn(scope const char* fmt, ...);
+void warnx(scope const char* fmt, ...);
+void verr(int eval, scope const char* fmt, va_list args);
+void verrx(int eval, scope const char* fmt, va_list args);
+void vwarn(scope const char* fmt, va_list args);
+void vwarnx(scope const char* fmt, va_list args);
diff --git a/libphobos/libdruntime/core/sys/linux/errno.d b/libphobos/libdruntime/core/sys/linux/errno.d
index bc93675..02ae151 100644
--- a/libphobos/libdruntime/core/sys/linux/errno.d
+++ b/libphobos/libdruntime/core/sys/linux/errno.d
@@ -8,6 +8,7 @@ module core.sys.linux.errno;
version (linux):
extern (C):
nothrow:
+@system:
public import core.stdc.errno;
import core.sys.linux.config;
diff --git a/libphobos/libdruntime/core/sys/linux/execinfo.d b/libphobos/libdruntime/core/sys/linux/execinfo.d
index 3259443..4169ca3 100644
--- a/libphobos/libdruntime/core/sys/linux/execinfo.d
+++ b/libphobos/libdruntime/core/sys/linux/execinfo.d
@@ -10,6 +10,8 @@ module core.sys.linux.execinfo;
version (linux):
extern (C):
nothrow:
+@system:
+@nogc:
int backtrace(void** buffer, int size);
char** backtrace_symbols(const(void*)* buffer, int size);
diff --git a/libphobos/libdruntime/core/sys/linux/fcntl.d b/libphobos/libdruntime/core/sys/linux/fcntl.d
index 974a5cc..11c3745 100644
--- a/libphobos/libdruntime/core/sys/linux/fcntl.d
+++ b/libphobos/libdruntime/core/sys/linux/fcntl.d
@@ -5,6 +5,7 @@ public import core.sys.posix.fcntl;
version (linux):
extern(C):
nothrow:
+@system:
// From linux/falloc.h
/// fallocate(2) params
diff --git a/libphobos/libdruntime/core/sys/linux/ifaddrs.d b/libphobos/libdruntime/core/sys/linux/ifaddrs.d
index d7b6d6d..5490e97a 100644
--- a/libphobos/libdruntime/core/sys/linux/ifaddrs.d
+++ b/libphobos/libdruntime/core/sys/linux/ifaddrs.d
@@ -22,6 +22,7 @@ version (linux):
extern (C):
nothrow:
@nogc:
+@system:
struct ifaddrs
{
@@ -46,7 +47,7 @@ struct ifaddrs
/// Address specific data
void* ifa_data;
-};
+}
/// Returns: linked list of ifaddrs structures describing interfaces
int getifaddrs(ifaddrs** );
diff --git a/libphobos/libdruntime/core/sys/linux/link.d b/libphobos/libdruntime/core/sys/linux/link.d
index 4d7eb1e..b417ec8 100644
--- a/libphobos/libdruntime/core/sys/linux/link.d
+++ b/libphobos/libdruntime/core/sys/linux/link.d
@@ -8,6 +8,7 @@ module core.sys.linux.link;
version (linux):
extern (C):
nothrow:
+@system:
version (ARM) version = ARM_Any;
version (AArch64) version = ARM_Any;
diff --git a/libphobos/libdruntime/core/sys/linux/netinet/in_.d b/libphobos/libdruntime/core/sys/linux/netinet/in_.d
index 47102e1..67bf654 100644
--- a/libphobos/libdruntime/core/sys/linux/netinet/in_.d
+++ b/libphobos/libdruntime/core/sys/linux/netinet/in_.d
@@ -121,27 +121,27 @@ version (linux_libc)
{
in_addr imr_multiaddr;
in_addr imr_interface;
- };
+ }
struct ip_mreq_source
{
in_addr imr_multiaddr;
in_addr imr_interface;
in_addr imr_sourceaddr;
- };
+ }
struct group_req
{
uint gr_interface;
sockaddr_storage gr_group;
- };
+ }
struct group_source_req
{
uint gsr_interface;
sockaddr_storage gsr_group;
sockaddr_storage gsr_source;
- };
+ }
struct ip_msfilter
{
@@ -150,7 +150,7 @@ version (linux_libc)
uint imsf_fmode;
uint imsf_numsrc;
in_addr[1] imsf_slist;
- };
+ }
extern(D) size_t IP_MSFILTER_SIZE(int numsrc)
{
@@ -164,7 +164,7 @@ version (linux_libc)
uint gf_fmode;
uint gf_numsrc;
sockaddr_storage[1] gf_slist;
- };
+ }
extern(D) size_t GROUP_FILTER_SIZE(int numsrc) pure @safe
{
@@ -186,13 +186,13 @@ version (linux_libc)
{
in6_addr ipi6_addr;
uint ipi6_ifindex;
- };
+ }
struct ip6_mtuinfo
{
sockaddr_in6 ip6m_addr;
uint ip6m_mtu;
- };
+ }
int inet6_opt_init(void* __extbuf, socklen_t __extlen);
int inet6_opt_append(void* __extbuf, socklen_t __extlen, int __offset,
@@ -313,21 +313,21 @@ version (linux_libc)
{
in_addr ip_dst;
char[40] ip_opts = 0;
- };
+ }
struct ip_mreqn
{
in_addr imr_multiaddr;
in_addr imr_address;
int imr_ifindex;
- };
+ }
struct in_pktinfo
{
int ipi_ifindex;
in_addr ipi_spec_dst;
in_addr ipi_addr;
- };
+ }
}
enum IPV6_ADDRFORM = 1;
diff --git a/libphobos/libdruntime/core/sys/linux/sched.d b/libphobos/libdruntime/core/sys/linux/sched.d
index 53cd0ef..dc815a0 100644
--- a/libphobos/libdruntime/core/sys/linux/sched.d
+++ b/libphobos/libdruntime/core/sys/linux/sched.d
@@ -17,6 +17,7 @@
module core.sys.linux.sched;
import core.bitop : popcnt;
+import core.stdc.stdlib : malloc, free;
import core.sys.posix.sched;
import core.sys.posix.config;
import core.sys.posix.sys.types;
@@ -25,6 +26,7 @@ version (linux):
extern (C):
@nogc:
nothrow:
+@system:
private // helpers
@@ -49,6 +51,21 @@ private // helpers
return 1UL << (cpu % __NCPUBITS);
}
+ cpu_set_t* __CPU_ALLOC(size_t count)
+ {
+ return cast(cpu_set_t*) malloc(__CPU_ALLOC_SIZE(count));
+ }
+
+ size_t __CPU_ALLOC_SIZE(size_t count) pure
+ {
+ return ((count + __NCPUBITS - 1) / __NCPUBITS) * cpu_mask.sizeof;
+ }
+
+ void __CPU_FREE(cpu_set_t* set)
+ {
+ free(cast(void*) set);
+ }
+
cpu_mask __CPU_SET_S(size_t cpu, size_t setsize, cpu_set_t* cpusetp) pure
{
if (cpu < 8 * setsize)
@@ -87,6 +104,21 @@ struct cpu_set_t
/// Access macros for 'cpu_set' (missing a lot of them)
+cpu_set_t* CPU_ALLOC(size_t count)
+{
+ return __CPU_ALLOC(count);
+}
+
+size_t CPU_ALLOC_SIZE(size_t count) pure
+{
+ return __CPU_ALLOC_SIZE(count);
+}
+
+void CPU_FREE(cpu_set_t* set)
+{
+ __CPU_FREE(set);
+}
+
cpu_mask CPU_SET(size_t cpu, cpu_set_t* cpusetp) pure
{
return __CPU_SET_S(cpu, cpu_set_t.sizeof, cpusetp);
@@ -102,6 +134,11 @@ int CPU_COUNT(cpu_set_t* cpusetp) pure
return __CPU_COUNT_S(cpu_set_t.sizeof, cpusetp);
}
+int CPU_COUNT_S(size_t setsize, cpu_set_t* cpusetp) pure
+{
+ return __CPU_COUNT_S(setsize, cpusetp);
+}
+
/* Scheduler control functions */
int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
@@ -110,6 +147,12 @@ int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
int clone(int function(void*), void* child_stack, int flags, void* arg, ...);
int unshare(int flags) @trusted;
+version (CRuntime_Glibc)
+{
+ /* Determine CPU on which the calling thread is running */
+ int sched_getcpu();
+}
+
enum CLONE_FILES = 0x400;
enum CLONE_FS = 0x200;
enum CLONE_NEWCGROUP = 0x2000000;
@@ -122,4 +165,5 @@ enum CLONE_NEWUTS = 0x4000000;
enum CLONE_SIGHAND = 0x800;
enum CLONE_SYSVSEM = 0x40000;
enum CLONE_THREAD = 0x10000;
+enum CLONE_VFORK = 0x4000;
enum CLONE_VM = 0x100;
diff --git a/libphobos/libdruntime/core/sys/linux/stdio.d b/libphobos/libdruntime/core/sys/linux/stdio.d
index 578b215..ab8971b 100644
--- a/libphobos/libdruntime/core/sys/linux/stdio.d
+++ b/libphobos/libdruntime/core/sys/linux/stdio.d
@@ -13,6 +13,8 @@ import core.sys.linux.config : __USE_FILE_OFFSET64;
import core.stdc.stdio : FILE;
import core.stdc.stddef : wchar_t;
+@system:
+
extern(C) nothrow
{
alias ssize_t function(void *cookie, char *buf, size_t size) cookie_read_function_t;
diff --git a/libphobos/libdruntime/core/sys/linux/string.d b/libphobos/libdruntime/core/sys/linux/string.d
index a388c8b..1b2c8d8 100644
--- a/libphobos/libdruntime/core/sys/linux/string.d
+++ b/libphobos/libdruntime/core/sys/linux/string.d
@@ -14,6 +14,7 @@ version (linux):
extern (C):
nothrow:
@nogc:
+@system:
static if (__USE_GNU)
{
diff --git a/libphobos/libdruntime/core/sys/linux/sys/inotify.d b/libphobos/libdruntime/core/sys/linux/sys/inotify.d
index 67545a8..e0acf33 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/inotify.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/inotify.d
@@ -10,6 +10,7 @@ version (linux):
extern (C):
@system:
nothrow:
+@nogc:
version (ARM) version = ARM_Any;
version (AArch64) version = ARM_Any;
diff --git a/libphobos/libdruntime/core/sys/linux/sys/mman.d b/libphobos/libdruntime/core/sys/linux/sys/mman.d
index 212943b..20e8cf2 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/mman.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/mman.d
@@ -8,6 +8,8 @@ module core.sys.linux.sys.mman;
version (linux):
extern (C):
nothrow:
+@system:
+@nogc:
version (ARM) version = ARM_Any;
version (AArch64) version = ARM_Any;
diff --git a/libphobos/libdruntime/core/sys/linux/sys/prctl.d b/libphobos/libdruntime/core/sys/linux/sys/prctl.d
index a5a4807..a732216 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/prctl.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/prctl.d
@@ -141,7 +141,7 @@ struct prctl_mm_map
ulong* auxv;
uint auxv_size;
uint exe_fd;
-};
+}
int prctl(int option, size_t arg2, size_t arg3, size_t arg4, size_t arg5);
diff --git a/libphobos/libdruntime/core/sys/linux/sys/signalfd.d b/libphobos/libdruntime/core/sys/linux/sys/signalfd.d
index 5d4cb67..736b145 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/signalfd.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/signalfd.d
@@ -14,6 +14,7 @@ version (linux):
extern (C):
@system:
nothrow:
+@nogc:
struct signalfd_siginfo
{
diff --git a/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d b/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d
index 699cd3e..0c9ed59 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d
@@ -7,6 +7,7 @@
module core.sys.linux.sys.sysinfo;
version (linux) extern(C) @nogc nothrow:
+@system:
import core.sys.linux.config;
diff --git a/libphobos/libdruntime/core/sys/linux/sys/time.d b/libphobos/libdruntime/core/sys/linux/sys/time.d
index 4b55f70..6ea626e 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/time.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/time.d
@@ -13,7 +13,7 @@
*/
module core.sys.linux.sys.time;
-private import core.sys.linux.config;
+import core.sys.linux.config;
public import core.sys.posix.sys.time; // timeval
version (linux):
diff --git a/libphobos/libdruntime/core/sys/linux/sys/xattr.d b/libphobos/libdruntime/core/sys/linux/sys/xattr.d
index a14c6c6..2f8d3f3 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/xattr.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/xattr.d
@@ -13,6 +13,7 @@ version (linux):
extern (C):
@system:
nothrow:
+@nogc:
enum {
XATTR_CREATE = 1, /* set value, fail if attr already exists. */
@@ -52,17 +53,17 @@ enum XATTR_CAPS_SUFFIX = "capability";
enum XATTR_NAME_CAPS = XATTR_SECURITY_PREFIX ~ XATTR_CAPS_SUFFIX;
-int setxattr(in char* path, in char* name, in void* value, size_t size, int flags);
+int setxattr(const scope char* path, const scope char* name, const scope void* value, size_t size, int flags);
-int lsetxattr(in char* path, in char* name, in void* value, size_t size, int flags);
-int fsetxattr(int fd, in char* name, in void* value, size_t size, int flags);
-ssize_t getxattr(in char* path, in char* name, void* value, size_t size);
-ssize_t lgetxattr(in char* path, in char* name, void* value, size_t size);
-ssize_t fgetxattr(int fd, in char* name, void* value, size_t size);
-ssize_t listxattr(in char* path, char* list, size_t size);
-ssize_t llistxattr(in char* path, char* list, size_t size);
+int lsetxattr(const scope char* path, const scope char* name, const scope void* value, size_t size, int flags);
+int fsetxattr(int fd, const scope char* name, const scope void* value, size_t size, int flags);
+ssize_t getxattr(const scope char* path, const scope char* name, void* value, size_t size);
+ssize_t lgetxattr(const scope char* path, const scope char* name, void* value, size_t size);
+ssize_t fgetxattr(int fd, const scope char* name, void* value, size_t size);
+ssize_t listxattr(const scope char* path, char* list, size_t size);
+ssize_t llistxattr(const scope char* path, char* list, size_t size);
ssize_t flistxattr (int __fd, char *list, size_t size);
-int removexattr (in char *path, in char *name);
-int lremovexattr (in char *path, in char *name);
-int fremovexattr (int fd, in char *name);
+int removexattr (const scope char *path, const scope char *name);
+int lremovexattr (const scope char *path, const scope char *name);
+int fremovexattr (int fd, const scope char *name);
diff --git a/libphobos/libdruntime/core/sys/linux/tipc.d b/libphobos/libdruntime/core/sys/linux/tipc.d
index 161a313..3246e62 100644
--- a/libphobos/libdruntime/core/sys/linux/tipc.d
+++ b/libphobos/libdruntime/core/sys/linux/tipc.d
@@ -10,6 +10,7 @@ module core.sys.linux.tipc;
version (linux):
extern (C) nothrow @nogc:
+@system:
struct tipc_portid
{
diff --git a/libphobos/libdruntime/core/sys/linux/unistd.d b/libphobos/libdruntime/core/sys/linux/unistd.d
index 21fd962..4845746 100644
--- a/libphobos/libdruntime/core/sys/linux/unistd.d
+++ b/libphobos/libdruntime/core/sys/linux/unistd.d
@@ -5,6 +5,7 @@ public import core.sys.posix.unistd;
version (linux):
extern(C):
nothrow:
+@system:
// Additional seek constants for sparse file handling
// from Linux's unistd.h, stdio.h, and linux/fs.h
@@ -18,3 +19,6 @@ enum {
/// Prompt for a password without echoing it.
char* getpass(const(char)* prompt);
+
+// Exit all threads in a process
+void exit_group(int status);
diff --git a/libphobos/libdruntime/core/sys/netbsd/dlfcn.d b/libphobos/libdruntime/core/sys/netbsd/dlfcn.d
index 88eb94b..468ffbf 100644
--- a/libphobos/libdruntime/core/sys/netbsd/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/netbsd/dlfcn.d
@@ -55,7 +55,7 @@ static if (__BSD_VISIBLE)
void *dli_fbase; /* Base address of shared object. */
const(char) *dli_sname; /* Name of nearest symbol. */
void *dli_saddr; /* Address of nearest symbol. */
- };
+ }
/*-
* The actual type declared by this typedef is immaterial, provided that
@@ -68,7 +68,7 @@ static if (__BSD_VISIBLE)
*/
struct __dlfunc_arg {
int __dlfunc_dummy;
- };
+ }
alias dlfunc_t = void function(__dlfunc_arg);
@@ -78,25 +78,22 @@ static if (__BSD_VISIBLE)
struct Dl_serpath {
char * dls_name; /* single search path entry */
uint dls_flags; /* path information */
- };
+ }
struct Dl_serinfo {
size_t dls_size; /* total buffer size */
uint dls_cnt; /* number of path entries */
Dl_serpath[1] dls_serpath; /* there may be more than one */
- };
-}
-
-private template __externC(RT, P...)
-{
- alias __externC = extern(C) RT function(P) nothrow @nogc;
+ }
}
/* XSI functions first. */
-static assert(is(typeof(&dlclose) == __externC!(int, void*)));
-static assert(is(typeof(&dlerror) == __externC!(char*)));
-static assert(is(typeof(&dlopen) == __externC!(void*, const char*, int)));
-static assert(is(typeof(&dlsym) == __externC!(void*, void*, const char*)));
+extern(C) {
+ static assert(is(typeof(&dlclose) == int function(void*)));
+ static assert(is(typeof(&dlerror) == char* function()));
+ static assert(is(typeof(&dlopen) == void* function(const scope char*, int)));
+ static assert(is(typeof(&dlsym) == void* function(void*, const scope char*)));
+}
static if (__BSD_VISIBLE)
{
diff --git a/libphobos/libdruntime/core/sys/netbsd/err.d b/libphobos/libdruntime/core/sys/netbsd/err.d
new file mode 100644
index 0000000..44eb66a
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/netbsd/err.d
@@ -0,0 +1,27 @@
+/**
+ * D header file for NetBSD err.h.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Ernesto Castellotti
+ */
+module core.sys.netbsd.err;
+import core.stdc.stdarg : va_list;
+
+version (NetBSD):
+extern (C):
+nothrow:
+@nogc:
+
+void err(int eval, scope const char* fmt, ...);
+void errc(int eval, int code, scope const char* fmt, ...);
+void errx(int eval, scope const char* fmt, ...);
+void warn(scope const char* fmt, ...);
+void warnc(int code, scope const char* fmt, ...);
+void warnx(scope const char* fmt, ...);
+void verr(int eval, scope const char* fmt, va_list args);
+void verrc(int eval, int code, scope const char* fmt, va_list args);
+void verrx(int eval, scope const char* fmt, va_list args);
+void vwarn(scope const char* fmt, va_list args);
+void vwarnc(int code, scope const char* fmt, va_list args);
+void vwarnx(scope const char* fmt, va_list args);
diff --git a/libphobos/libdruntime/core/sys/netbsd/stdlib.d b/libphobos/libdruntime/core/sys/netbsd/stdlib.d
new file mode 100644
index 0000000..84c68a7
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/netbsd/stdlib.d
@@ -0,0 +1,17 @@
+/**
+ * D header file for NetBSD stdlib.h.
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.netbsd.stdlib;
+public import core.sys.posix.stdlib;
+
+version (NetBSD):
+extern (C):
+nothrow:
+@nogc:
+
+const(char)* getprogname();
+void setprogname(scope const char* name);
diff --git a/libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d
index cc24a77..4caec61 100644
--- a/libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d
+++ b/libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d
@@ -50,7 +50,7 @@ struct r_debug
int r_version;
link_map* r_map;
void function(r_debug*, link_map*) r_brk;
-};
+}
struct dl_phdr_info
{
@@ -62,7 +62,7 @@ struct dl_phdr_info
uint64_t dlpi_subs;
size_t dlpi_tls_modid;
void* dlpi_tls_data;
-};
+}
private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;
diff --git a/libphobos/libdruntime/core/sys/netbsd/sys/sysctl.d b/libphobos/libdruntime/core/sys/netbsd/sys/sysctl.d
new file mode 100644
index 0000000..9b2a0b7
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/netbsd/sys/sysctl.d
@@ -0,0 +1,254 @@
+/**
+ * D header file for NetBSD sys/sysctl.h
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.netbsd.sys.sysctl;
+
+version (NetBSD):
+extern (C):
+nothrow:
+@nogc:
+
+// Top-level identifiers
+enum
+{
+ CTL_UNSPEC = 0,
+ CTL_KERN = 1,
+ CTL_VM = 2,
+ CTL_VFS = 3,
+ CTL_NET = 4,
+ CTL_DEBUG = 5,
+ CTL_HW = 6,
+ CTL_MACHDEP = 7,
+ CTL_DDB = 9,
+ CTL_PROC = 10,
+ CTL_VENDOR = 11,
+ CTL_EMUL = 12,
+ CTL_SECURITY = 13,
+}
+
+// CTL_KERN identifiers
+enum
+{
+ KERN_OSTYPE = 1,
+ KERN_OSRELEASE = 2,
+ KERN_OSREV = 3,
+ KERN_VERSION = 4,
+ KERN_MAXVNODES = 5,
+ KERN_MAXPROC = 6,
+ KERN_MAXFILES = 7,
+ KERN_ARGMAX = 8,
+ KERN_SECURELVL = 9,
+ KERN_HOSTNAME = 10,
+ KERN_HOSTID = 11,
+ KERN_CLOCKRATE = 12,
+ KERN_VNODE = 13,
+ KERN_PROC = 14,
+ KERN_FILE = 15,
+ KERN_PROF = 16,
+ KERN_POSIX1 = 17,
+ KERN_NGROUPS = 18,
+ KERN_JOB_CONTROL = 19,
+ KERN_SAVED_IDS = 20,
+ KERN_OBOOTTIME = 21,
+ KERN_DOMAINNAME = 22,
+ KERN_MAXPARTITIONS = 23,
+ KERN_RAWPARTITION = 24,
+ KERN_NTPTIME = 25,
+ KERN_TIMEX = 26,
+ KERN_AUTONICETIME = 27,
+ KERN_AUTONICEVAL = 28,
+ KERN_RTC_OFFSET = 29,
+ KERN_ROOT_DEVICE = 30,
+ KERN_MSGBUFSIZE = 31,
+ KERN_FSYNC = 32,
+ KERN_OLDSYSVMSG = 33,
+ KERN_OLDSYSVSEM = 34,
+ KERN_OLDSYSVSHM = 35,
+ KERN_OLDSHORTCORENAME = 36,
+ KERN_SYNCHRONIZED_IO = 37,
+ KERN_IOV_MAX = 38,
+ KERN_MBUF = 39,
+ KERN_MAPPED_FILES = 40,
+ KERN_MEMLOCK = 41,
+ KERN_MEMLOCK_RANGE = 42,
+ KERN_MEMORY_PROTECTION = 43,
+ KERN_LOGIN_NAME_MAX = 44,
+ KERN_DEFCORENAME = 45,
+ KERN_LOGSIGEXIT = 46,
+ KERN_PROC2 = 47,
+ KERN_PROC_ARGS = 48,
+ KERN_FSCALE = 49,
+ KERN_CCPU = 50,
+ KERN_CP_TIME = 51,
+ KERN_OLDSYSVIPC_INFO = 52,
+ KERN_MSGBUF = 53,
+ KERN_CONSDEV = 54,
+ KERN_MAXPTYS = 55,
+ KERN_PIPE = 56,
+ KERN_MAXPHYS = 57,
+ KERN_SBMAX = 58,
+ KERN_TKSTAT = 59,
+ KERN_MONOTONIC_CLOCK = 60,
+ KERN_URND = 61,
+ KERN_LABELSECTOR = 62,
+ KERN_LABELOFFSET = 63,
+ KERN_LWP = 64,
+ KERN_FORKFSLEEP = 65,
+ KERN_POSIX_THREADS = 66,
+ KERN_POSIX_SEMAPHORES = 67,
+ KERN_POSIX_BARRIERS = 68,
+ KERN_POSIX_TIMERS = 69,
+ KERN_POSIX_SPIN_LOCKS = 70,
+ KERN_POSIX_READER_WRITER_LOCKS = 71,
+ KERN_DUMP_ON_PANIC = 72,
+ KERN_SOMAXKVA = 73,
+ KERN_ROOT_PARTITION = 74,
+ KERN_DRIVERS = 75,
+ KERN_BUF = 76,
+ KERN_FILE2 = 77,
+ KERN_VERIEXEC = 78,
+ KERN_CP_ID = 79,
+ KERN_HARDCLOCK_TICKS = 80,
+ KERN_ARND = 81,
+ KERN_SYSVIPC = 82,
+ KERN_BOOTTIME = 83,
+ KERN_EVCNT = 84,
+ KERN_SOFIXEDBUF = 85,
+}
+
+// KERN_PROC subtypes
+enum
+{
+ KERN_PROC_ALL = 0,
+ KERN_PROC_PID = 1,
+ KERN_PROC_PGRP = 2,
+ KERN_PROC_SESSION = 3,
+ KERN_PROC_TTY = 4,
+ KERN_PROC_UID = 5,
+ KERN_PROC_RUID = 6,
+ KERN_PROC_KTHREAD = 7,
+ KERN_PROC_RGID = 8,
+}
+
+// KERN_PROC_ARGS subtypes
+enum
+{
+ KERN_PROC_ARGV = 1,
+ KERN_PROC_NARGV = 2,
+ KERN_PROC_ENV = 3,
+ KERN_PROC_NENV = 4,
+ KERN_PROC_PATHNAME = 5,
+ KERN_PROC_CWD = 6,
+}
+
+// KERN_SYSVIPC subtypes
+enum
+{
+ KERN_SYSVIPC_INFO = 1,
+ KERN_SYSVIPC_MSG = 2,
+ KERN_SYSVIPC_SEM = 3,
+ KERN_SYSVIPC_SHM = 4,
+ KERN_SYSVIPC_SHMMAX = 5,
+ KERN_SYSVIPC_SHMMNI = 6,
+ KERN_SYSVIPC_SHMSEG = 7,
+ KERN_SYSVIPC_SHMMAXPGS = 8,
+ KERN_SYSVIPC_SHMUSEPHYS = 9,
+}
+
+// KERN_SYSVIPC_INFO subtypes
+enum
+{
+ KERN_SYSVIPC_MSG_INFO = 4,
+ KERN_SYSVIPC_SEM_INFO = 5,
+ KERN_SYSVIPC_SHM_INFO = 6,
+}
+
+// KERN_TKSTAT subtypes
+enum
+{
+ KERN_TKSTAT_NIN = 1,
+ KERN_TKSTAT_NOUT = 2,
+ KERN_TKSTAT_CANCC = 3,
+ KERN_TKSTAT_RAWCC = 4,
+}
+
+// KERN_BUF subtypes
+enum
+{
+ KERN_BUF_ALL = 0,
+}
+
+// KERN_FILE
+enum
+{
+ KERN_FILE_BYFILE = 1,
+ KERN_FILE_BYPID = 2,
+ KERN_FILESLOP = 10,
+}
+
+// KERN_EVCNT
+enum
+{
+ KERN_EVCNT_COUNT_ANY = 0,
+ KERN_EVCNT_COUNT_NONZERO = 1,
+}
+
+// CTL_HW identifiers
+enum
+{
+ HW_MACHINE = 1,
+ HW_MODEL = 2,
+ HW_NCPU = 3,
+ HW_BYTEORDER = 4,
+ HW_PHYSMEM = 5,
+ HW_USERMEM = 6,
+ HW_PAGESIZE = 7,
+ HW_DISKNAMES = 8,
+ HW_IOSTATS = 9,
+ HW_MACHINE_ARCH = 10,
+ HW_ALIGNBYTES = 11,
+ HW_CNMAGIC = 12,
+ HW_PHYSMEM64 = 13,
+ HW_USERMEM64 = 14,
+ HW_IOSTATNAMES = 15,
+ HW_NCPUONLINE = 16,
+}
+
+// CTL_USER definitions
+enum
+{
+ USER_CS_PATH = 1,
+ USER_BC_BASE_MAX = 2,
+ USER_BC_DIM_MAX = 3,
+ USER_BC_SCALE_MAX = 4,
+ USER_BC_STRING_MAX = 5,
+ USER_COLL_WEIGHTS_MAX = 6,
+ USER_EXPR_NEST_MAX = 7,
+ USER_LINE_MAX = 8,
+ USER_RE_DUP_MAX = 9,
+ USER_POSIX2_VERSION = 10,
+ USER_POSIX2_C_BIND = 11,
+ USER_POSIX2_C_DEV = 12,
+ USER_POSIX2_CHAR_TERM = 13,
+ USER_POSIX2_FORT_DEV = 14,
+ USER_POSIX2_FORT_RUN = 15,
+ USER_POSIX2_LOCALEDEF = 16,
+ USER_POSIX2_SW_DEV = 17,
+ USER_POSIX2_UPE = 18,
+ USER_STREAM_MAX = 19,
+ USER_TZNAME_MAX = 20,
+ USER_ATEXIT_MAX = 21,
+}
+
+///
+int sysctl(const int* name, uint namelen, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
+///
+int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
+///
+int sysctlnametomib(const char* sname, int* name, size_t* namelenp);
diff --git a/libphobos/libdruntime/core/sys/openbsd/err.d b/libphobos/libdruntime/core/sys/openbsd/err.d
new file mode 100644
index 0000000..b467614
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/openbsd/err.d
@@ -0,0 +1,27 @@
+/**
+ * D header file for OpenBSD err.h.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Ernesto Castellotti
+ */
+module core.sys.openbsd.err;
+import core.stdc.stdarg : va_list;
+
+version (OpenBSD):
+extern (C):
+nothrow:
+@nogc:
+
+void err(int eval, scope const char* fmt, ...);
+void errc(int eval, int code, scope const char* fmt, ...);
+void errx(int eval, scope const char* fmt, ...);
+void warn(scope const char* fmt, ...);
+void warnc(int code, scope const char* fmt, ...);
+void warnx(scope const char* fmt, ...);
+void verr(int eval, scope const char* fmt, va_list args);
+void verrc(int eval, int code, scope const char* fmt, va_list args);
+void verrx(int eval, scope const char* fmt, va_list args);
+void vwarn(scope const char* fmt, va_list args);
+void vwarnc(int code, scope const char* fmt, va_list args);
+void vwarnx(scope const char* fmt, va_list args);
diff --git a/libphobos/libdruntime/core/sys/openbsd/stdlib.d b/libphobos/libdruntime/core/sys/openbsd/stdlib.d
new file mode 100644
index 0000000..2d4d7a9
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/openbsd/stdlib.d
@@ -0,0 +1,17 @@
+/**
+ * D header file for OpenBSD stdlib.h.
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.openbsd.stdlib;
+public import core.sys.posix.stdlib;
+
+version (OpenBSD):
+extern (C):
+nothrow:
+@nogc:
+
+const(char)* getprogname();
+void setprogname(scope const char* name);
diff --git a/libphobos/libdruntime/core/sys/openbsd/string.d b/libphobos/libdruntime/core/sys/openbsd/string.d
index 8d35b9c..cb978c8 100644
--- a/libphobos/libdruntime/core/sys/openbsd/string.d
+++ b/libphobos/libdruntime/core/sys/openbsd/string.d
@@ -18,4 +18,6 @@ nothrow:
static if (__BSD_VISIBLE)
{
pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+ pure int timingsafe_bcmp(scope const void*, scope const void*, size_t);
+ pure int timingsafe_memcmp(scope const void*, scope const void*, size_t);
}
diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
index 3582b4c..55fc792 100644
--- a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
+++ b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
@@ -55,7 +55,7 @@ struct dl_phdr_info
char* dlpi_name;
ElfW!"Phdr"* dlpi_phdr;
ElfW!"Half" dlpi_phnum;
-};
+}
private alias int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;
@@ -63,3 +63,8 @@ private alias int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_
int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);
int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;
+
+int _rtld_addr_phdr(const void*, dl_phdr_info*) @nogc
+{
+ return 0;
+}
diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/sysctl.d b/libphobos/libdruntime/core/sys/openbsd/sys/sysctl.d
new file mode 100644
index 0000000..c6f9845
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/openbsd/sys/sysctl.d
@@ -0,0 +1,254 @@
+/**
+ * D header file for OpenBSD sys/sysctl.h
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.openbsd.sys.sysctl;
+
+version (OpenBSD):
+extern (C):
+nothrow:
+@nogc:
+
+// Top-level identifiers
+enum
+{
+ CTL_UNSPEC = 0,
+ CTL_KERN = 1,
+ CTL_VM = 2,
+ CTL_FS = 3,
+ CTL_NET = 4,
+ CTL_DEBUG = 5,
+ CTL_HW = 6,
+ CTL_MACHDEP = 7,
+ CTL_DDB = 9,
+ CTL_VFS = 10,
+ CTL_MAXID = 11,
+}
+
+// CTL_KERN identifiers
+enum
+{
+ KERN_OSTYPE = 1,
+ KERN_OSRELEASE = 2,
+ KERN_OSREV = 3,
+ KERN_VERSION = 4,
+ KERN_MAXVNODES = 5,
+ KERN_MAXPROC = 6,
+ KERN_MAXFILES = 7,
+ KERN_ARGMAX = 8,
+ KERN_SECURELVL = 9,
+ KERN_HOSTNAME = 10,
+ KERN_HOSTID = 11,
+ KERN_CLOCKRATE = 12,
+ KERN_PROF = 16,
+ KERN_POSIX1 = 17,
+ KERN_NGROUPS = 18,
+ KERN_JOB_CONTROL = 19,
+ KERN_SAVED_IDS = 20,
+ KERN_BOOTTIME = 21,
+ KERN_DOMAINNAME = 22,
+ KERN_MAXPARTITIONS = 23,
+ KERN_RAWPARTITION = 24,
+ KERN_MAXTHREAD = 25,
+ KERN_NTHREADS = 26,
+ KERN_OSVERSION = 27,
+ KERN_SOMAXCONN = 28,
+ KERN_SOMINCONN = 29,
+ KERN_NOSUIDCOREDUMP = 32,
+ KERN_FSYNC = 33,
+ KERN_SYSVMSG = 34,
+ KERN_SYSVSEM = 35,
+ KERN_SYSVSHM = 36,
+ KERN_MSGBUFSIZE = 38,
+ KERN_MALLOCSTATS = 39,
+ KERN_CPTIME = 40,
+ KERN_NCHSTATS = 41,
+ KERN_FORKSTAT = 42,
+ KERN_NSELCOLL = 43,
+ KERN_TTY = 44,
+ KERN_CCPU = 45,
+ KERN_FSCALE = 46,
+ KERN_NPROCS = 47,
+ KERN_MSGBUF = 48,
+ KERN_POOL = 49,
+ KERN_STACKGAPRANDOM = 50,
+ KERN_SYSVIPC_INFO = 51,
+ KERN_ALLOWKMEM = 52,
+ KERN_WITNESSWATCH = 53,
+ KERN_SPLASSERT = 54,
+ KERN_PROC_ARGS = 55,
+ KERN_NFILES = 56,
+ KERN_TTYCOUNT = 57,
+ KERN_NUMVNODES = 58,
+ KERN_MBSTAT = 59,
+ KERN_WITNESS = 60,
+ KERN_SEMINFO = 61,
+ KERN_SHMINFO = 62,
+ KERN_INTRCNT = 63,
+ KERN_WATCHDOG = 64,
+ KERN_ALLOWDT = 65,
+ KERN_PROC = 66,
+ KERN_MAXCLUSTERS = 67,
+ KERN_EVCOUNT = 68,
+ KERN_TIMECOUNTER = 69,
+ KERN_MAXLOCKSPERUID = 70,
+ KERN_CPTIME2 = 71,
+ KERN_CACHEPCT = 72,
+ KERN_FILE = 73,
+ KERN_WXABORT = 74,
+ KERN_CONSDEV = 75,
+ KERN_NETLIVELOCKS = 76,
+ KERN_POOL_DEBUG = 77,
+ KERN_PROC_CWD = 78,
+ KERN_PROC_NOBROADCASTKILL = 79,
+ KERN_PROC_VMMAP = 80,
+ KERN_GLOBAL_PTRACE = 81,
+ KERN_CONSBUFSIZE = 82,
+ KERN_CONSBUF = 83,
+ KERN_AUDIO = 84,
+ KERN_CPUSTATS = 85,
+ KERN_PFSTATUS = 86,
+ KERN_TIMEOUT_STATS = 87,
+ KERN_UTC_OFFSET = 88,
+ KERN_MAXID = 89,
+}
+
+// KERN_PROC subtypes
+enum
+{
+ KERN_PROC_ALL = 0,
+ KERN_PROC_PID = 1,
+ KERN_PROC_PGRP = 2,
+ KERN_PROC_SESSION = 3,
+ KERN_PROC_TTY = 4,
+ KERN_PROC_UID = 5,
+ KERN_PROC_RUID = 6,
+ KERN_PROC_KTHREAD = 7,
+ KERN_PROC_SHOW_THREADS = 0x40000000,
+}
+
+// KERN_SYSVIPC_INFO subtypes
+enum
+{
+ KERN_SYSVIPC_MSG_INFO = 1,
+ KERN_SYSVIPC_SEM_INFO = 2,
+ KERN_SYSVIPC_SHM_INFO = 3,
+}
+
+// KERN_PROC_ARGS subtypes
+enum
+{
+ KERN_PROC_ARGV = 1,
+ KERN_PROC_NARGV = 2,
+ KERN_PROC_ENV = 3,
+ KERN_PROC_NENV = 4,
+}
+
+// KERN_AUDIO subtypes
+enum
+{
+ KERN_AUDIO_RECORD = 1,
+ KERN_AUDIO_MAXID = 2,
+}
+
+// KERN_WITNESS
+enum
+{
+ KERN_WITNESS_WATCH = 1,
+ KERN_WITNESS_LOCKTRACE = 2,
+ KERN_WITNESS_MAXID = 3,
+}
+
+// KERN_FILE
+enum
+{
+ KERN_FILE_BYFILE = 1,
+ KERN_FILE_BYPID = 2,
+ KERN_FILE_BYUID = 3,
+ KERN_FILESLOP = 10,
+
+ KERN_FILE_TEXT = -1,
+ KERN_FILE_CDIR = -2,
+ KERN_FILE_RDIR = -3,
+ KERN_FILE_TRACE = -4,
+}
+
+// KERN_INTRCNT
+enum
+{
+ KERN_INTRCNT_NUM = 1,
+ KERN_INTRCNT_CNT = 2,
+ KERN_INTRCNT_NAME = 3,
+ KERN_INTRCNT_VECTOR = 4,
+ KERN_INTRCNT_MAXID = 5,
+}
+
+// KERN_WATCHDOG
+enum
+{
+ KERN_WATCHDOG_PERIOD = 1,
+ KERN_WATCHDOG_AUTO = 2,
+ KERN_WATCHDOG_MAXID = 3,
+}
+
+// KERN_TIMECOUNTER
+enum
+{
+ KERN_TIMECOUNTER_TICK = 1,
+ KERN_TIMECOUNTER_TIMESTEPWARNINGS = 2,
+ KERN_TIMECOUNTER_HARDWARE = 3,
+ KERN_TIMECOUNTER_CHOICE = 4,
+ KERN_TIMECOUNTER_MAXID = 5,
+}
+
+// CTL_FS identifiers
+enum
+{
+ FS_POSIX = 1,
+ FS_MAXID = 2,
+}
+
+// CTL_FS_POSIX identifiers
+enum
+{
+ FS_POSIX_SETUID = 1,
+ FS_POSIX_MAXID = 2,
+}
+
+// CTL_HW identifiers
+enum
+{
+ HW_MACHINE = 1,
+ HW_MODEL = 2,
+ HW_NCPU = 3,
+ HW_BYTEORDER = 4,
+ HW_PHYSMEM = 5,
+ HW_USERMEM = 6,
+ HW_PAGESIZE = 7,
+ HW_DISKNAMES = 8,
+ HW_DISKSTATS = 9,
+ HW_DISKCOUNT = 10,
+ HW_SENSORS = 11,
+ HW_CPUSPEED = 12,
+ HW_SETPERF = 13,
+ HW_VENDOR = 14,
+ HW_PRODUCT = 15,
+ HW_VERSION = 16,
+ HW_SERIALNO = 17,
+ HW_UUID = 18,
+ HW_PHYSMEM64 = 19,
+ HW_USERMEM64 = 20,
+ HW_NCPUFOUND = 21,
+ HW_ALLOWPOWERDOWN = 22,
+ HW_PERFPOLICY = 23,
+ HW_SMT = 24,
+ HW_NCPUONLINE = 25,
+ HW_MAXID = 26,
+}
+
+///
+int sysctl(const int* name, uint namelen, void* oldp, size_t* oldlenp,
+ const void* newp, size_t newlen);
diff --git a/libphobos/libdruntime/core/sys/openbsd/unistd.d b/libphobos/libdruntime/core/sys/openbsd/unistd.d
new file mode 100644
index 0000000..ddd102c
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/openbsd/unistd.d
@@ -0,0 +1,17 @@
+/**
+ * D header file for OpenBSD unistd.h.
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Brian Callahan
+ */
+module core.sys.openbsd.unistd;
+public import core.sys.posix.unistd;
+
+version (OpenBSD):
+extern (C):
+nothrow:
+@nogc:
+
+int pledge(const scope char*, const scope char*);
+int unveil(const scope char*, const scope char*);
diff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d
index 1165446..f4e0f12 100644
--- a/libphobos/libdruntime/core/sys/posix/aio.d
+++ b/libphobos/libdruntime/core/sys/posix/aio.d
@@ -8,8 +8,8 @@
*/
module core.sys.posix.aio;
-private import core.sys.posix.signal;
-private import core.sys.posix.sys.types;
+import core.sys.posix.signal;
+import core.sys.posix.sys.types;
version (OSX)
version = Darwin;
diff --git a/libphobos/libdruntime/core/sys/posix/arpa/inet.d b/libphobos/libdruntime/core/sys/posix/arpa/inet.d
index ac8e3eb..6881142 100644
--- a/libphobos/libdruntime/core/sys/posix/arpa/inet.d
+++ b/libphobos/libdruntime/core/sys/posix/arpa/inet.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.arpa.inet;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.inttypes; // for uint32_t, uint16_t
public import core.sys.posix.sys.socket; // for socklen_t
@@ -51,11 +51,11 @@ uint16_t htons(uint16_t);
uint32_t ntohl(uint32_t);
uint16_t ntohs(uint16_t);
-in_addr_t inet_addr(in char*);
+in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
// per spec: const char* inet_ntop(int, const void*, char*, socklen_t);
-char* inet_ntop(int, in void*, char*, socklen_t);
-int inet_pton(int, in char*, void*);
+char* inet_ntop(int, const scope void*, char*, socklen_t);
+int inet_pton(int, const scope char*, void*);
*/
version (CRuntime_Glibc)
@@ -78,10 +78,10 @@ version (CRuntime_Glibc)
uint16_t ntohs(uint16_t);
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (Darwin)
{
@@ -103,10 +103,10 @@ else version (Darwin)
uint16_t ntohs(uint16_t);
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (FreeBSD)
{
@@ -128,10 +128,10 @@ else version (FreeBSD)
uint16_t ntohs(uint16_t);
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (NetBSD)
{
@@ -153,10 +153,10 @@ else version (NetBSD)
uint16_t ntohs(uint16_t);
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (OpenBSD)
{
@@ -194,10 +194,10 @@ else version (OpenBSD)
uint16_t ntohs(uint16_t x) { return __swap16(x); }
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (DragonFlyBSD)
{
@@ -219,10 +219,10 @@ else version (DragonFlyBSD)
uint16_t ntohs(uint16_t);
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (Solaris)
{
@@ -243,10 +243,10 @@ else version (Solaris)
uint16_t ntohs(uint16_t);
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (CRuntime_Bionic)
{
@@ -283,10 +283,10 @@ else version (CRuntime_Bionic)
uint16_t ntohs(uint16_t x) { return __swap16(x); }
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, size_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, size_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (CRuntime_Musl)
{
@@ -308,10 +308,10 @@ else version (CRuntime_Musl)
uint16_t ntohs(uint16_t);
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
else version (CRuntime_UClibc)
{
@@ -333,10 +333,10 @@ else version (CRuntime_UClibc)
uint16_t ntohs(uint16_t);
}
- in_addr_t inet_addr(in char*);
+ in_addr_t inet_addr(const scope char*);
char* inet_ntoa(in_addr);
- const(char)* inet_ntop(int, in void*, char*, socklen_t);
- int inet_pton(int, in char*, void*);
+ const(char)* inet_ntop(int, const scope void*, char*, socklen_t);
+ int inet_pton(int, const scope char*, void*);
}
//
diff --git a/libphobos/libdruntime/core/sys/posix/config.d b/libphobos/libdruntime/core/sys/posix/config.d
index 20e711c..3b575fa 100644
--- a/libphobos/libdruntime/core/sys/posix/config.d
+++ b/libphobos/libdruntime/core/sys/posix/config.d
@@ -19,6 +19,7 @@ public import core.stdc.config;
version (Posix):
extern (C) nothrow @nogc:
+@system:
enum _XOPEN_SOURCE = 600;
enum _POSIX_SOURCE = true;
@@ -116,6 +117,7 @@ else version (CRuntime_UClibc)
else version (CRuntime_Bionic)
{
enum _GNU_SOURCE = false;
+ enum __USE_FILE_OFFSET64 = false; // see https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md
enum __USE_GNU = _GNU_SOURCE;
version (D_LP64)
diff --git a/libphobos/libdruntime/core/sys/posix/dirent.d b/libphobos/libdruntime/core/sys/posix/dirent.d
index b12d6b1..8a2440e 100644
--- a/libphobos/libdruntime/core/sys/posix/dirent.d
+++ b/libphobos/libdruntime/core/sys/posix/dirent.d
@@ -15,7 +15,7 @@
*/
module core.sys.posix.dirent;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for ino_t
version (OSX)
@@ -31,6 +31,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required
@@ -44,7 +45,7 @@ struct dirent
}
int closedir(DIR*);
-DIR* opendir(in char*);
+DIR* opendir(const scope char*);
dirent* readdir(DIR*);
void rewinddir(DIR*);
*/
@@ -129,7 +130,12 @@ else version (Darwin)
// Other Darwin variants (iOS, TVOS, WatchOS) only support 64-bit inodes,
// no suffix needed
version (OSX)
- pragma(mangle, "readdir$INODE64") dirent* readdir(DIR*);
+ {
+ version (AArch64)
+ dirent* readdir(DIR*);
+ else
+ pragma(mangle, "readdir$INODE64") dirent* readdir(DIR*);
+ }
else
dirent* readdir(DIR*);
}
@@ -180,7 +186,17 @@ else version (FreeBSD)
alias void* DIR;
- dirent* readdir(DIR*);
+ version (GNU)
+ {
+ dirent* readdir(DIR*);
+ }
+ else
+ {
+ static if (__FreeBSD_version >= 1200000)
+ pragma(mangle, "readdir@FBSD_1.5") dirent* readdir(DIR*);
+ else
+ pragma(mangle, "readdir@FBSD_1.0") dirent* readdir(DIR*);
+ }
}
else version (NetBSD)
{
@@ -434,10 +450,16 @@ else
// in else below.
version (OSX)
{
- version (D_LP64)
+ version (AArch64)
+ {
+ int closedir(DIR*);
+ DIR* opendir(const scope char*);
+ void rewinddir(DIR*);
+ }
+ else version (D_LP64)
{
int closedir(DIR*);
- pragma(mangle, "opendir$INODE64") DIR* opendir(in char*);
+ pragma(mangle, "opendir$INODE64") DIR* opendir(const scope char*);
pragma(mangle, "rewinddir$INODE64") void rewinddir(DIR*);
}
else
@@ -445,21 +467,21 @@ version (OSX)
// 32-bit mangles __DARWIN_UNIX03 specific functions with $UNIX2003 to
// maintain backward compatibility with binaries build pre 10.5
pragma(mangle, "closedir$UNIX2003") int closedir(DIR*);
- pragma(mangle, "opendir$INODE64$UNIX2003") DIR* opendir(in char*);
+ pragma(mangle, "opendir$INODE64$UNIX2003") DIR* opendir(const scope char*);
pragma(mangle, "rewinddir$INODE64$UNIX2003") void rewinddir(DIR*);
}
}
else version (NetBSD)
{
int closedir(DIR*);
- DIR* __opendir30(in char*);
+ DIR* __opendir30(const scope char*);
alias __opendir30 opendir;
void rewinddir(DIR*);
}
else
{
int closedir(DIR*);
- DIR* opendir(in char*);
+ DIR* opendir(const scope char*);
//dirent* readdir(DIR*);
void rewinddir(DIR*);
}
@@ -492,7 +514,17 @@ else version (Darwin)
}
else version (FreeBSD)
{
- int readdir_r(DIR*, dirent*, dirent**);
+ version (GNU)
+ {
+ int readdir_r(DIR*, dirent*, dirent**);
+ }
+ else
+ {
+ static if (__FreeBSD_version >= 1200000)
+ pragma(mangle, "readdir_r@FBSD_1.5") int readdir_r(DIR*, dirent*, dirent**);
+ else
+ pragma(mangle, "readdir_r@FBSD_1.0") int readdir_r(DIR*, dirent*, dirent**);
+ }
}
else version (DragonFlyBSD)
{
@@ -559,8 +591,16 @@ version (CRuntime_Glibc)
}
else version (FreeBSD)
{
- void seekdir(DIR*, c_long);
- c_long telldir(DIR*);
+ version (GNU)
+ {
+ void seekdir(DIR*, c_long);
+ c_long telldir(DIR*);
+ }
+ else
+ {
+ pragma(mangle, "seekdir@@FBSD_1.0") void seekdir(DIR*, c_long);
+ pragma(mangle, "telldir@@FBSD_1.0") c_long telldir(DIR*);
+ }
}
else version (NetBSD)
{
diff --git a/libphobos/libdruntime/core/sys/posix/dlfcn.d b/libphobos/libdruntime/core/sys/posix/dlfcn.d
index 11113d3..f6476ec 100644
--- a/libphobos/libdruntime/core/sys/posix/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/posix/dlfcn.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.dlfcn;
-private import core.sys.posix.config;
+import core.sys.posix.config;
version (OSX)
version = Darwin;
@@ -45,6 +45,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// XOpen (XSI)
@@ -57,8 +58,8 @@ RTLD_LOCAL
int dlclose(void*);
char* dlerror();
-void* dlopen(in char*, int);
-void* dlsym(void*, in char*);
+void* dlopen(const scope char*, int);
+void* dlsym(void*, const scope char*);
*/
version (CRuntime_Glibc)
@@ -124,8 +125,8 @@ version (CRuntime_Glibc)
int dlclose(void*);
char* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
}
else version (Darwin)
{
@@ -136,9 +137,9 @@ else version (Darwin)
int dlclose(void*);
char* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
- int dladdr(void* addr, Dl_info* info);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
+ int dladdr(scope const void* addr, Dl_info* info);
struct Dl_info
{
@@ -157,8 +158,8 @@ else version (FreeBSD)
int dlclose(void*);
char* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
int dladdr(const(void)* addr, Dl_info* info);
struct Dl_info
@@ -180,8 +181,8 @@ else version (NetBSD)
int dlclose(void*);
char* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
int dladdr(const(void)* addr, Dl_info* info);
struct Dl_info
@@ -201,8 +202,8 @@ else version (OpenBSD)
int dlclose(void*);
char* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
int dladdr(const(void)* addr, Dl_info* info);
struct Dl_info
@@ -222,8 +223,8 @@ else version (DragonFlyBSD)
int dlclose(void*);
char* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
int dladdr(const(void)* addr, Dl_info* info);
struct Dl_info
@@ -243,8 +244,8 @@ else version (Solaris)
int dlclose(void*);
char* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
int dladdr(const(void)* addr, Dl_info* info);
struct Dl_info
@@ -265,11 +266,11 @@ else version (CRuntime_Bionic)
RTLD_GLOBAL = 2
}
- int dladdr(in void*, Dl_info*);
+ int dladdr(const scope void*, Dl_info*);
int dlclose(void*);
const(char)* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
struct Dl_info
{
@@ -291,8 +292,17 @@ else version (CRuntime_Musl)
}
int dlclose(void*);
const(char)* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
+
+ int dladdr(scope const void *addr, Dl_info *info);
+ struct Dl_info
+ {
+ const(char)* dli_fname;
+ void* dli_fbase;
+ const(char)* dli_sname;
+ void* dli_saddr;
+ }
}
else version (CRuntime_UClibc)
{
@@ -331,6 +341,6 @@ else version (CRuntime_UClibc)
int dlclose(void*);
char* dlerror();
- void* dlopen(in char*, int);
- void* dlsym(void*, in char*);
+ void* dlopen(const scope char*, int);
+ void* dlsym(void*, const scope char*);
}
diff --git a/libphobos/libdruntime/core/sys/posix/fcntl.d b/libphobos/libdruntime/core/sys/posix/fcntl.d
index 9febcff..59df921 100644
--- a/libphobos/libdruntime/core/sys/posix/fcntl.d
+++ b/libphobos/libdruntime/core/sys/posix/fcntl.d
@@ -14,8 +14,8 @@
*/
module core.sys.posix.fcntl;
-private import core.sys.posix.config;
-private import core.stdc.stdint;
+import core.sys.posix.config;
+import core.stdc.stdint;
public import core.sys.posix.sys.types; // for off_t, mode_t
public import core.sys.posix.sys.stat; // for S_IFMT, etc.
@@ -49,6 +49,7 @@ extern (C):
nothrow:
@nogc:
+@system:
//
// Required
@@ -96,9 +97,9 @@ struct flock
pid_t l_pid;
}
-int creat(in char*, mode_t);
+int creat(const scope char*, mode_t);
int fcntl(int, int, ...);
-int open(in char*, int, ...);
+int open(const scope char*, int, ...);
*/
version (CRuntime_Glibc)
{
@@ -272,16 +273,16 @@ version (CRuntime_Glibc)
static if ( __USE_FILE_OFFSET64 )
{
- int creat64(in char*, mode_t);
+ int creat64(const scope char*, mode_t);
alias creat64 creat;
- int open64(in char*, int, ...);
+ int open64(const scope char*, int, ...);
alias open64 open;
}
else
{
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
}
enum AT_SYMLINK_NOFOLLOW = 0x100;
@@ -331,8 +332,8 @@ else version (Darwin)
short l_whence;
}
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
}
else version (FreeBSD)
{
@@ -392,8 +393,8 @@ else version (FreeBSD)
short l_whence;
}
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
enum AT_SYMLINK_NOFOLLOW = 0x200;
enum AT_FDCWD = -100;
@@ -457,8 +458,8 @@ else version (OpenBSD)
short l_whence;
}
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
enum AT_FDCWD = -100;
@@ -517,8 +518,8 @@ else version (NetBSD)
}
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
}
else version (DragonFlyBSD)
{
@@ -604,8 +605,8 @@ else version (DragonFlyBSD)
alias oflock = flock;
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
//int fcntl(int, int, ...); /*defined below*/
//int flock(int, int);
}
@@ -694,8 +695,8 @@ else version (Solaris)
version (D_LP64)
{
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
static if (__USE_LARGEFILE64)
{
@@ -707,16 +708,16 @@ else version (Solaris)
{
static if (__USE_LARGEFILE64)
{
- int creat64(in char*, mode_t);
+ int creat64(const scope char*, mode_t);
alias creat64 creat;
- int open64(in char*, int, ...);
+ int open64(const scope char*, int, ...);
alias open64 open;
}
else
{
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
}
}
}
@@ -772,8 +773,8 @@ else version (CRuntime_Bionic)
pid_t l_pid;
}
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
enum AT_FDCWD = -100;
}
@@ -925,9 +926,13 @@ else version (CRuntime_Musl)
pid_t l_pid;
}
enum FD_CLOEXEC = 1;
- int open(in char*, int, ...);
+ int open(const scope char*, int, ...);
enum AT_FDCWD = -100;
+ enum AT_SYMLINK_NOFOLLOW = 0x100;
+ enum AT_REMOVEDIR = 0x200;
+ enum AT_SYMLINK_FOLLOW = 0x400;
+ enum AT_EACCESS = 0x200;
}
else version (CRuntime_UClibc)
{
@@ -1037,16 +1042,16 @@ else version (CRuntime_UClibc)
static if ( __USE_FILE_OFFSET64 )
{
- int creat64(in char*, mode_t);
+ int creat64(const scope char*, mode_t);
alias creat64 creat;
- int open64(in char*, int, ...);
+ int open64(const scope char*, int, ...);
alias open64 open;
}
else
{
- int creat(in char*, mode_t);
- int open(in char*, int, ...);
+ int creat(const scope char*, mode_t);
+ int open(const scope char*, int, ...);
}
enum AT_SYMLINK_NOFOLLOW = 0x100;
@@ -1057,9 +1062,9 @@ else
static assert(false, "Unsupported platform");
}
-//int creat(in char*, mode_t);
+//int creat(const scope char*, mode_t);
int fcntl(int, int, ...);
-//int open(in char*, int, ...);
+//int open(const scope char*, int, ...);
// Generic Posix fallocate
int posix_fallocate(int, off_t, off_t);
diff --git a/libphobos/libdruntime/core/sys/posix/grp.d b/libphobos/libdruntime/core/sys/posix/grp.d
index 41afeeb..92dcf34 100644
--- a/libphobos/libdruntime/core/sys/posix/grp.d
+++ b/libphobos/libdruntime/core/sys/posix/grp.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.grp;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for gid_t, uid_t
version (OSX)
@@ -30,6 +30,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required
@@ -43,7 +44,7 @@ struct group
char** gr_mem;
}
-group* getgrnam(in char*);
+group* getgrnam(const scope char*);
group* getgrgid(gid_t);
*/
@@ -152,50 +153,50 @@ else
static assert(false, "Unsupported platform");
}
-group* getgrnam(in char*);
+group* getgrnam(const scope char*);
group* getgrgid(gid_t);
//
// Thread-Safe Functions (TSF)
//
/*
-int getgrnam_r(in char*, group*, char*, size_t, group**);
+int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
*/
version (CRuntime_Glibc)
{
- int getgrnam_r(in char*, group*, char*, size_t, group**);
+ int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
}
else version (Darwin)
{
- int getgrnam_r(in char*, group*, char*, size_t, group**);
+ int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
}
else version (FreeBSD)
{
- int getgrnam_r(in char*, group*, char*, size_t, group**);
+ int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
}
else version (NetBSD)
{
- int getgrnam_r(in char*, group*, char*, size_t, group**);
+ int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
}
else version (OpenBSD)
{
- int getgrnam_r(in char*, group*, char*, size_t, group**);
+ int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
}
else version (DragonFlyBSD)
{
- int getgrnam_r(in char*, group*, char*, size_t, group**);
+ int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
}
else version (Solaris)
{
- int getgrnam_r(in char*, group*, char*, int, group**);
+ int getgrnam_r(const scope char*, group*, char*, int, group**);
int getgrgid_r(gid_t, group*, char*, int, group**);
}
else version (CRuntime_Bionic)
@@ -203,12 +204,12 @@ else version (CRuntime_Bionic)
}
else version (CRuntime_UClibc)
{
- int getgrnam_r(in char*, group*, char*, size_t, group**);
+ int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
}
else version (CRuntime_Musl)
{
- int getgrnam_r(in char*, group*, char*, size_t, group**);
+ int getgrnam_r(const scope char*, group*, char*, size_t, group**);
int getgrgid_r(gid_t, group*, char*, size_t, group**);
}
else
diff --git a/libphobos/libdruntime/core/sys/posix/iconv.d b/libphobos/libdruntime/core/sys/posix/iconv.d
index 9ba6fdd..cea8987 100644
--- a/libphobos/libdruntime/core/sys/posix/iconv.d
+++ b/libphobos/libdruntime/core/sys/posix/iconv.d
@@ -34,18 +34,19 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
alias void* iconv_t;
/// Allocate descriptor for code conversion from codeset FROMCODE to
/// codeset TOCODE.
-iconv_t iconv_open (in char* tocode, in char* fromcode);
+iconv_t iconv_open (const scope char* tocode, const scope char* fromcode);
/// Convert at most *INBYTESLEFT bytes from *INBUF according to the
/// code conversion algorithm specified by CD and place up to
/// *OUTBYTESLEFT bytes in buffer at *OUTBUF.
-size_t iconv (iconv_t cd, in char** inbuf,
+size_t iconv (iconv_t cd, const scope char** inbuf,
size_t* inbytesleft,
char** outbuf,
size_t* outbytesleft);
diff --git a/libphobos/libdruntime/core/sys/posix/inttypes.d b/libphobos/libdruntime/core/sys/posix/inttypes.d
index 15863b4..4bde28f 100644
--- a/libphobos/libdruntime/core/sys/posix/inttypes.d
+++ b/libphobos/libdruntime/core/sys/posix/inttypes.d
@@ -14,11 +14,12 @@
*/
module core.sys.posix.inttypes;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.inttypes;
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// Required
@@ -26,15 +27,15 @@ extern (C) nothrow @nogc:
/*
intmax_t imaxabs(intmax_t);
imaxdiv_t imaxdiv(intmax_t, intmax_t);
-intmax_t strtoimax(in char*, char**, int);
-uintmax_t strtoumax(in char*, char**, int);
-intmax_t wcstoimax(in wchar_t*, wchar_t**, int);
-uintmax_t wcstoumax(in wchar_t*, wchar_t**, int);
+intmax_t strtoimax(const scope char*, char**, int);
+uintmax_t strtoumax(const scope char*, char**, int);
+intmax_t wcstoimax(const scope wchar_t*, wchar_t**, int);
+uintmax_t wcstoumax(const scope wchar_t*, wchar_t**, int);
*/
intmax_t imaxabs(intmax_t);
imaxdiv_t imaxdiv(intmax_t, intmax_t);
-intmax_t strtoimax(in char*, char**, int);
-uintmax_t strtoumax(in char*, char**, int);
-intmax_t wcstoimax(in wchar_t*, wchar_t**, int);
-uintmax_t wcstoumax(in wchar_t*, wchar_t**, int);
+intmax_t strtoimax(const scope char*, char**, int);
+uintmax_t strtoumax(const scope char*, char**, int);
+intmax_t wcstoimax(const scope wchar_t*, wchar_t**, int);
+uintmax_t wcstoumax(const scope wchar_t*, wchar_t**, int);
diff --git a/libphobos/libdruntime/core/sys/posix/libgen.d b/libphobos/libdruntime/core/sys/posix/libgen.d
index 6770cd8..b90765f 100644
--- a/libphobos/libdruntime/core/sys/posix/libgen.d
+++ b/libphobos/libdruntime/core/sys/posix/libgen.d
@@ -15,6 +15,7 @@
module core.sys.posix.libgen;
@nogc nothrow:
+@system:
extern (C):
version (Posix):
diff --git a/libphobos/libdruntime/core/sys/posix/locale.d b/libphobos/libdruntime/core/sys/posix/locale.d
new file mode 100644
index 0000000..18558a2
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/posix/locale.d
@@ -0,0 +1,452 @@
+/**
+ * D header file for POSIX's <locale.h>.
+ *
+ * See_Also: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/locale.h.html
+ * Copyright: D Language Foundation, 2019
+ * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Authors: Mathias 'Geod24' Lang
+ * Standards: The Open Group Base Specifications Issue 7, 2018 edition
+ * Source: $(DRUNTIMESRC core/sys/posix/_locale.d)
+ */
+module core.sys.posix.locale;
+
+version (Posix):
+extern(C):
+@system:
+nothrow:
+@nogc:
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (Darwin)
+ version = DarwinBSDLocale;
+version (FreeBSD)
+ version = DarwinBSDLocale;
+version (NetBSD)
+ version = DarwinBSDLocale;
+version (DragonflyBSD)
+ version = DarwinBSDLocale;
+
+version (CRuntime_Glibc)
+ version = GNULinuxLocale;
+version (CRuntime_Bionic)
+ version = GNULinuxLocale;
+version (CRuntime_UClibc)
+ version = GNULinuxLocale;
+
+version (DarwinBSDLocale)
+{
+ ///
+ struct lconv
+ {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_p_cs_precedes;
+ char int_n_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+ }
+
+ ///
+ enum
+ {
+ LC_ALL = 0,
+ LC_COLLATE = 1,
+ LC_CTYPE = 2,
+ LC_MESSAGES = 6,
+ LC_MONETARY = 3,
+ LC_NUMERIC = 4,
+ LC_TIME = 5,
+ }
+
+ private struct _xlocale;
+
+ ///
+ alias locale_t = _xlocale*;
+
+ version (NetBSD)
+ enum LC_ALL_MASK = (cast(int)~0);
+ else
+ enum LC_ALL_MASK = (
+ LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK |
+ LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK);
+
+
+ ///
+ enum
+ {
+ LC_COLLATE_MASK = (1 << 0),
+ LC_CTYPE_MASK = (1 << 1),
+ LC_MESSAGES_MASK = (1 << 2),
+ LC_MONETARY_MASK = (1 << 3),
+ LC_NUMERIC_MASK = (1 << 4),
+ LC_TIME_MASK = (1 << 5),
+ }
+
+ ///
+ enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
+
+ /// Duplicate existing locale
+ locale_t duplocale(locale_t locale);
+ /// Free an allocated locale
+ void freelocale(locale_t locale);
+ /// Natural language formatting for C
+ lconv* localeconv();
+ /// Create a new locale
+ locale_t newlocale(int mask, const char* locale, locale_t base);
+ /// Set the C library's notion of natural language formatting style
+ char* setlocale(int category, const char* locale);
+ /// Set the per-thread locale
+ locale_t uselocale (locale_t locale);
+}
+else version (GNULinuxLocale)
+{
+ ///
+ struct lconv
+ {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_p_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_cs_precedes;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+ }
+
+ ///
+ enum
+ {
+ LC_ALL = 6,
+ LC_COLLATE = 3,
+ LC_CTYPE = 0,
+ LC_MESSAGES = 5,
+ LC_MONETARY = 4,
+ LC_NUMERIC = 1,
+ LC_TIME = 2,
+
+ // Linux-specific
+ LC_PAPER = 7,
+ LC_NAME = 8,
+ LC_ADDRESS = 9,
+ LC_TELEPHONE = 10,
+ LC_MEASUREMENT = 11,
+ LC_IDENTIFICATION = 12,
+ }
+
+ ///
+ enum
+ {
+ LC_ALL_MASK = (LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK |
+ LC_COLLATE_MASK | LC_MONETARY_MASK | LC_MESSAGES_MASK |
+ LC_PAPER_MASK | LC_NAME_MASK | LC_ADDRESS_MASK |
+ LC_TELEPHONE_MASK | LC_MEASUREMENT_MASK |
+ LC_IDENTIFICATION_MASK),
+
+ LC_COLLATE_MASK = (1 << LC_COLLATE),
+ LC_CTYPE_MASK = (1 << LC_CTYPE),
+ LC_MESSAGES_MASK = (1 << LC_MESSAGES),
+ LC_MONETARY_MASK = (1 << LC_MONETARY),
+ LC_NUMERIC_MASK = (1 << LC_NUMERIC),
+ LC_TIME_MASK = (1 << LC_TIME),
+
+ // Linux specific
+ LC_PAPER_MASK = (1 << LC_PAPER),
+ LC_NAME_MASK = (1 << LC_NAME),
+ LC_ADDRESS_MASK = (1 << LC_ADDRESS),
+ LC_TELEPHONE_MASK = (1 << LC_TELEPHONE),
+ LC_MEASUREMENT_MASK = (1 << LC_MEASUREMENT),
+ LC_IDENTIFICATION_MASK = (1 << LC_IDENTIFICATION),
+ }
+
+ private struct __locale_struct;
+
+ ///
+ alias locale_t = __locale_struct*;
+
+ ///
+ enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
+
+ /// Duplicate existing locale
+ locale_t duplocale(locale_t locale);
+ /// Free an allocated locale
+ void freelocale(locale_t locale);
+ /// Natural language formatting for C
+ lconv* localeconv();
+ /// Create a new locale
+ locale_t newlocale(int mask, const char* locale, locale_t base);
+ /// Set the C library's notion of natural language formatting style
+ char* setlocale(int category, const char* locale);
+ /// Set the per-thread locale
+ locale_t uselocale (locale_t locale);
+}
+else version (CRuntime_Musl)
+{
+ ///
+ struct lconv
+ {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_p_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_cs_precedes;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+ }
+
+ ///
+ enum
+ {
+ LC_CTYPE = 0,
+ LC_NUMERIC = 1,
+ LC_TIME = 2,
+ LC_COLLATE = 3,
+ LC_MONETARY = 4,
+ LC_MESSAGES = 5,
+ LC_ALL = 6,
+ }
+
+ ///
+ enum
+ {
+ LC_CTYPE_MASK = (1 << LC_CTYPE),
+ LC_NUMERIC_MASK = (1 << LC_NUMERIC),
+ LC_TIME_MASK = (1 << LC_TIME),
+ LC_COLLATE_MASK = (1 << LC_COLLATE),
+ LC_MONETARY_MASK = (1 << LC_MONETARY),
+ LC_MESSAGES_MASK = (1 << LC_MESSAGES),
+ LC_ALL_MASK = 0x7fffffff,
+ }
+
+ private struct __locale_struct;
+
+ ///
+ alias locale_t = __locale_struct*;
+
+ ///
+ enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
+
+ /// Duplicate existing locale
+ locale_t duplocale(locale_t locale);
+ /// Free an allocated locale
+ void freelocale(locale_t locale);
+ /// Natural language formatting for C
+ lconv* localeconv();
+ /// Create a new locale
+ locale_t newlocale(int mask, const char* locale, locale_t base);
+ /// Set the C library's notion of natural language formatting style
+ char* setlocale(int category, const char* locale);
+ /// Set the per-thread locale
+ locale_t uselocale (locale_t locale);
+}
+else version (OpenBSD)
+{
+ ///
+ struct lconv
+ {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_p_cs_precedes;
+ char int_n_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+ }
+
+ ///
+ enum
+ {
+ LC_ALL = 0,
+ LC_COLLATE = 1,
+ LC_CTYPE = 2,
+ LC_MONETARY = 3,
+ LC_NUMERIC = 4,
+ LC_TIME = 5,
+ LC_MESSAGES = 6,
+ }
+ private enum _LC_LAST = 7;
+
+ ///
+ enum
+ {
+ LC_COLLATE_MASK = (1 << LC_COLLATE),
+ LC_CTYPE_MASK = (1 << LC_CTYPE),
+ LC_MONETARY_MASK = (1 << LC_MONETARY),
+ LC_NUMERIC_MASK = (1 << LC_NUMERIC),
+ LC_TIME_MASK = (1 << LC_TIME),
+ LC_MESSAGES_MASK = (1 << LC_MESSAGES),
+ LC_ALL_MASK = ((1 << _LC_LAST) - 2),
+ }
+
+ ///
+ alias locale_t = void*;
+
+ ///
+ enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
+
+ /// Duplicate existing locale
+ locale_t duplocale(locale_t locale);
+ /// Free an allocated locale
+ void freelocale(locale_t locale);
+ /// Natural language formatting for C
+ lconv* localeconv();
+ /// Create a new locale
+ locale_t newlocale(int mask, const char* locale, locale_t base);
+ /// Set the C library's notion of natural language formatting style
+ char* setlocale(int category, const char* locale);
+ /// Set the per-thread locale
+ locale_t uselocale (locale_t locale);
+}
+else version (Solaris)
+{
+ ///
+ struct lconv
+ {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_p_cs_precedes;
+ char int_n_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+ }
+
+ ///
+ enum
+ {
+ LC_CTYPE = 0,
+ LC_NUMERIC = 1,
+ LC_TIME = 2,
+ LC_COLLATE = 3,
+ LC_MONETARY = 4,
+ LC_MESSAGES = 5,
+ LC_ALL = 6,
+ }
+
+ ///
+ enum
+ {
+ LC_CTYPE_MASK = (1 << LC_CTYPE),
+ LC_NUMERIC_MASK = (1 << LC_NUMERIC),
+ LC_TIME_MASK = (1 << LC_TIME),
+ LC_COLLATE_MASK = (1 << LC_COLLATE),
+ LC_MONETARY_MASK = (1 << LC_MONETARY),
+ LC_MESSAGES_MASK = (1 << LC_MESSAGES),
+ LC_ALL_MASK = 0x3f,
+ }
+
+ private struct _LC_locale_t;
+
+ ///
+ alias locale_t = _LC_locale_t**;
+
+ ///
+ enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
+
+ /// Duplicate existing locale
+ locale_t duplocale(locale_t locale);
+ /// Free an allocated locale
+ void freelocale(locale_t locale);
+ /// Natural language formatting for C
+ lconv* localeconv();
+ /// Create a new locale
+ locale_t newlocale(int mask, const char* locale, locale_t base);
+ /// Set the C library's notion of natural language formatting style
+ char* setlocale(int category, const char* locale);
+ /// Set the per-thread locale
+ locale_t uselocale (locale_t locale);
+}
+else
+ static assert(false, "unimplemented platform");
diff --git a/libphobos/libdruntime/core/sys/posix/mqueue.d b/libphobos/libdruntime/core/sys/posix/mqueue.d
index d554376..2f1a8c6 100644
--- a/libphobos/libdruntime/core/sys/posix/mqueue.d
+++ b/libphobos/libdruntime/core/sys/posix/mqueue.d
@@ -19,6 +19,7 @@
* Authors: Andreas Bok Andersen, Mathias Lang
* Standards: POSIX.1-2001.
* See_Also: $(HTTP pubs.opengroup.org/onlinepubs/9699919799/basedefs/mqueue.h.html, Standard)
+ * Source: $(DRUNTIMESRC core/sys/posix/mqueue.d)
*/
module core.sys.posix.mqueue;
@@ -30,6 +31,7 @@ version (Posix):
version (CRuntime_Glibc):
extern (C):
@nogc nothrow:
+@system:
/// Message queue descriptor.
@@ -57,16 +59,17 @@ struct mq_attr
* Note:
* Linux prototypes are:
* mqd_t mq_open (const(char)* name, int oflag);
- * mqd_t mq_open(const(char)* name, int oflag, mode_t mode, mq_attr* attr);
+ * mqd_t mq_open (const(char)* name, int oflag, mode_t mode, mq_attr* attr);
*
* Params:
* name = Name of the message queue to open.
- * oflags = determines the type of access used.
+ * oflag = determines the type of access used.
* If `O_CREAT` is on `oflag`, the third argument is taken as a
* `mode_t`, the mode of the created message queue.
* If `O_CREAT` is on `oflag`, the fourth argument is taken as
* a pointer to a `mq_attr' (message queue attributes).
* If the fourth argument is `null`, default attributes are used.
+ * ... = varargs matching the function prototypes
*
* Returns:
* Message queue descriptor or (mqd_t) -1 on error.
diff --git a/libphobos/libdruntime/core/sys/posix/net/if_.d b/libphobos/libdruntime/core/sys/posix/net/if_.d
index e6eb57b..3713673 100644
--- a/libphobos/libdruntime/core/sys/posix/net/if_.d
+++ b/libphobos/libdruntime/core/sys/posix/net/if_.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.net.if_;
-private import core.sys.posix.config;
+import core.sys.posix.config;
version (OSX)
version = Darwin;
@@ -40,7 +40,7 @@ struct if_nameindex // renamed to if_nameindex_t
IF_NAMESIZE
-uint if_nametoindex(in char*);
+uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
if_nameindex_t* if_nameindex();
void if_freenameindex(if_nameindex_t*);
@@ -56,7 +56,7 @@ version (CRuntime_Glibc)
enum IF_NAMESIZE = 16;
- uint if_nametoindex(in char*);
+ uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
if_nameindex_t* if_nameindex();
void if_freenameindex(if_nameindex_t*);
@@ -71,7 +71,7 @@ else version (Darwin)
enum IF_NAMESIZE = 16;
- uint if_nametoindex(in char*);
+ uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
if_nameindex_t* if_nameindex();
void if_freenameindex(if_nameindex_t*);
@@ -86,7 +86,7 @@ else version (FreeBSD)
enum IF_NAMESIZE = 16;
- uint if_nametoindex(in char*);
+ uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
if_nameindex_t* if_nameindex();
void if_freenameindex(if_nameindex_t*);
@@ -101,7 +101,7 @@ else version (NetBSD)
enum IF_NAMESIZE = 16;
- uint if_nametoindex(in char*);
+ uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
if_nameindex_t* if_nameindex();
void if_freenameindex(if_nameindex_t*);
@@ -116,7 +116,7 @@ else version (OpenBSD)
enum IF_NAMESIZE = 16;
- uint if_nametoindex(in char*);
+ uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
if_nameindex_t* if_nameindex();
void if_freenameindex(if_nameindex_t*);
@@ -131,7 +131,7 @@ else version (DragonFlyBSD)
enum IF_NAMESIZE = 16;
- uint if_nametoindex(in char*);
+ uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
if_nameindex_t* if_nameindex();
void if_freenameindex(if_nameindex_t*);
@@ -140,7 +140,7 @@ else version (CRuntime_Bionic)
{
enum IF_NAMESIZE = 16;
- uint if_nametoindex(in char*);
+ uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
}
else version (CRuntime_UClibc)
@@ -153,7 +153,7 @@ else version (CRuntime_UClibc)
enum IF_NAMESIZE = 16;
- uint if_nametoindex(in char*);
+ uint if_nametoindex(const scope char*);
char* if_indextoname(uint, char*);
if_nameindex_t* if_nameindex();
void if_freenameindex(if_nameindex_t*);
diff --git a/libphobos/libdruntime/core/sys/posix/netdb.d b/libphobos/libdruntime/core/sys/posix/netdb.d
index f125183..bede638 100644
--- a/libphobos/libdruntime/core/sys/posix/netdb.d
+++ b/libphobos/libdruntime/core/sys/posix/netdb.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.netdb;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.inttypes; // for uint32_t
public import core.sys.posix.netinet.in_; // for in_port_t, in_addr_t
public import core.sys.posix.sys.types; // for ino_t
@@ -33,6 +33,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required
diff --git a/libphobos/libdruntime/core/sys/posix/netinet/in_.d b/libphobos/libdruntime/core/sys/posix/netinet/in_.d
index ef20a8f..a58fa85 100644
--- a/libphobos/libdruntime/core/sys/posix/netinet/in_.d
+++ b/libphobos/libdruntime/core/sys/posix/netinet/in_.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.netinet.in_;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.inttypes; // for uint32_t, uint16_t, uint8_t
public import core.sys.posix.arpa.inet;
public import core.sys.posix.sys.socket; // for sa_family_t
@@ -804,7 +804,7 @@ else version (FreeBSD)
}
// macros
- extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -812,7 +812,7 @@ else version (FreeBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
}
- extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -820,7 +820,7 @@ else version (FreeBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -829,58 +829,58 @@ else version (FreeBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
}
- extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
}
- extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
}
- extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xff;
}
- extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure
+ extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
{
return a.s6_addr[1] & 0x0f;
}
- extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
@@ -943,7 +943,7 @@ else version (NetBSD)
}
// macros
- extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -951,7 +951,7 @@ else version (NetBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
}
- extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -959,7 +959,7 @@ else version (NetBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -968,58 +968,58 @@ else version (NetBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
}
- extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
}
- extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
}
- extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xff;
}
- extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure
+ extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
{
return a.s6_addr[1] & 0x0f;
}
- extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
@@ -1082,7 +1082,7 @@ else version (OpenBSD)
}
// macros
- extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1090,7 +1090,7 @@ else version (OpenBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
}
- extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1098,7 +1098,7 @@ else version (OpenBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1107,58 +1107,58 @@ else version (OpenBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
}
- extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
}
- extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
}
- extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xff;
}
- extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure
+ extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
{
return a.s6_addr[1] & 0x0f;
}
- extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
@@ -1221,7 +1221,7 @@ else version (DragonFlyBSD)
}
// macros
- extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1229,7 +1229,7 @@ else version (DragonFlyBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
}
- extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1237,7 +1237,7 @@ else version (DragonFlyBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1246,58 +1246,58 @@ else version (DragonFlyBSD)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
}
- extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
}
- extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
}
- extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
{
return a.s6_addr[0] == 0xff;
}
- extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure
+ extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
{
return a.s6_addr[1] & 0x0f;
}
- extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
}
- extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
{
return IN6_IS_ADDR_MULTICAST(a) &&
__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
@@ -1350,67 +1350,67 @@ else version (Solaris)
}
// macros
- extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
{
return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
(a.s6_addr32[2] == 0) && (a.s6_addr32[3] == 0);
}
- extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
{
return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
(a.s6_addr32[2] == 0) && (a.s6_addr32[3] == ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
{
return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
(a.s6_addr32[2] == 0) && (a.s6_addr32[3] != 0) &&
(a.s6_addr32[3] != ntohl(1));
}
- extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
{
return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
(a.s6_addr32[2] == ntohl(0x0000ffff));
}
- extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0x80;
}
- extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0xc0;
}
- extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
{
return a.s6_addr8[0] == 0xff;
}
- extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x01;
}
- extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x02;
}
- extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x05;
}
- extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
{
return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x08;
}
- extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure
+ extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
{
return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x0e;
}
@@ -1470,7 +1470,7 @@ else version (CRuntime_Bionic)
extern (D) pure
{
- bool IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a )
+ bool IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a )
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1478,7 +1478,7 @@ else version (CRuntime_Bionic)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
}
- bool IN6_IS_ADDR_LOOPBACK( in in6_addr* a )
+ bool IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a )
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1486,7 +1486,7 @@ else version (CRuntime_Bionic)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
}
- bool IN6_IS_ADDR_V4COMPAT( in in6_addr* a )
+ bool IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a )
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1495,63 +1495,63 @@ else version (CRuntime_Bionic)
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
}
- bool IN6_IS_ADDR_V4MAPPED( in in6_addr* a )
+ bool IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a )
{
return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
(*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
}
- bool IN6_IS_ADDR_LINKLOCAL( in in6_addr* a )
+ bool IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a )
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
}
- bool IN6_IS_ADDR_SITELOCAL( in in6_addr* a )
+ bool IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a )
{
return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
}
- bool IN6_IS_ADDR_ULA( in in6_addr* a )
+ bool IN6_IS_ADDR_ULA( const scope in6_addr* a )
{
return (a.s6_addr[0] & 0xfe) == 0xfc;
}
- bool IN6_IS_ADDR_MULTICAST( in in6_addr* a )
+ bool IN6_IS_ADDR_MULTICAST( const scope in6_addr* a )
{
return a.s6_addr[0] == 0xff;
}
- uint8_t IPV6_ADDR_MC_SCOPE( in in6_addr* a )
+ uint8_t IPV6_ADDR_MC_SCOPE( const scope in6_addr* a )
{
return a.s6_addr[1] & 0x0f;
}
- bool IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a )
+ bool IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a )
{
return IN6_IS_ADDR_MULTICAST(a) &&
IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL;
}
- bool IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a )
+ bool IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a )
{
return IN6_IS_ADDR_MULTICAST(a) &&
IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL;
}
- bool IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a )
+ bool IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a )
{
return IN6_IS_ADDR_MULTICAST(a) &&
IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL;
}
- bool IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a )
+ bool IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a )
{
return IN6_IS_ADDR_MULTICAST(a) &&
IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL;
}
- bool IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a )
+ bool IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a )
{
return IN6_IS_ADDR_MULTICAST(a) &&
IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL;
diff --git a/libphobos/libdruntime/core/sys/posix/netinet/tcp.d b/libphobos/libdruntime/core/sys/posix/netinet/tcp.d
index 134e133..d400d2d 100644
--- a/libphobos/libdruntime/core/sys/posix/netinet/tcp.d
+++ b/libphobos/libdruntime/core/sys/posix/netinet/tcp.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.netinet.tcp;
-private import core.sys.posix.config;
+import core.sys.posix.config;
version (OSX)
version = Darwin;
diff --git a/libphobos/libdruntime/core/sys/posix/poll.d b/libphobos/libdruntime/core/sys/posix/poll.d
index 9070eee..fdc4176 100644
--- a/libphobos/libdruntime/core/sys/posix/poll.d
+++ b/libphobos/libdruntime/core/sys/posix/poll.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.poll;
-private import core.sys.posix.config;
+import core.sys.posix.config;
version (OSX)
version = Darwin;
@@ -29,6 +29,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// XOpen (XSI)
@@ -91,7 +92,7 @@ else version (Darwin)
int fd;
short events;
short revents;
- };
+ }
alias uint nfds_t;
@@ -127,7 +128,7 @@ else version (FreeBSD)
int fd;
short events;
short revents;
- };
+ }
enum
{
@@ -161,7 +162,7 @@ else version (NetBSD)
int fd;
short events;
short revents;
- };
+ }
enum
{
@@ -195,7 +196,7 @@ else version (OpenBSD)
int fd;
short events;
short revents;
- };
+ }
enum
{
@@ -226,7 +227,7 @@ else version (DragonFlyBSD)
int fd;
short events;
short revents;
- };
+ }
enum
{
diff --git a/libphobos/libdruntime/core/sys/posix/pthread.d b/libphobos/libdruntime/core/sys/posix/pthread.d
index 1d0d294..395ed0f 100644
--- a/libphobos/libdruntime/core/sys/posix/pthread.d
+++ b/libphobos/libdruntime/core/sys/posix/pthread.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.pthread;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types;
public import core.sys.posix.sched;
public import core.sys.posix.time;
@@ -33,6 +33,7 @@ else version (WatchOS)
version (Posix):
extern (C)
nothrow:
+@system:
//
// Required
@@ -55,23 +56,23 @@ PTHREAD_PROCESS_PRIVATE
int pthread_atfork(void function(), void function(), void function());
int pthread_attr_destroy(pthread_attr_t*);
-int pthread_attr_getdetachstate(in pthread_attr_t*, int*);
-int pthread_attr_getschedparam(in pthread_attr_t*, sched_param*);
+int pthread_attr_getdetachstate(const scope pthread_attr_t*, int*);
+int pthread_attr_getschedparam(const scope pthread_attr_t*, sched_param*);
int pthread_attr_init(pthread_attr_t*);
int pthread_attr_setdetachstate(pthread_attr_t*, int);
-int pthread_attr_setschedparam(in pthread_attr_t*, sched_param*);
+int pthread_attr_setschedparam(const scope pthread_attr_t*, sched_param*);
int pthread_cancel(pthread_t);
void pthread_cleanup_push(void function(void*), void*);
void pthread_cleanup_pop(int);
int pthread_cond_broadcast(pthread_cond_t*);
int pthread_cond_destroy(pthread_cond_t*);
-int pthread_cond_init(in pthread_cond_t*, pthread_condattr_t*);
+int pthread_cond_init(const scope pthread_cond_t*, pthread_condattr_t*);
int pthread_cond_signal(pthread_cond_t*);
-int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, in timespec*);
+int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);
int pthread_condattr_destroy(pthread_condattr_t*);
int pthread_condattr_init(pthread_condattr_t*);
-int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
+int pthread_create(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
int pthread_detach(pthread_t);
int pthread_equal(pthread_t, pthread_t);
void pthread_exit(void*);
@@ -88,7 +89,7 @@ int pthread_mutexattr_destroy(pthread_mutexattr_t*);
int pthread_mutexattr_init(pthread_mutexattr_t*);
int pthread_once(pthread_once_t*, void function());
int pthread_rwlock_destroy(pthread_rwlock_t*);
-int pthread_rwlock_init(pthread_rwlock_t*, in pthread_rwlockattr_t*);
+int pthread_rwlock_init(pthread_rwlock_t*, const scope pthread_rwlockattr_t*);
int pthread_rwlock_rdlock(pthread_rwlock_t*);
int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
int pthread_rwlock_trywrlock(pthread_rwlock_t*);
@@ -99,7 +100,7 @@ int pthread_rwlockattr_init(pthread_rwlockattr_t*);
pthread_t pthread_self();
int pthread_setcancelstate(int, int*);
int pthread_setcanceltype(int, int*);
-int pthread_setspecific(pthread_key_t, in void*);
+int pthread_setspecific(pthread_key_t, const scope void*);
void pthread_testcancel();
*/
version (CRuntime_Glibc)
@@ -290,7 +291,7 @@ else version (OpenBSD)
}
enum PTHREAD_MUTEX_INITIALIZER = null;
- //enum PTHREAD_ONCE_INIT = { PTHREAD_NEEDS_INIT, PTHREAD_MUTEX_INITIALIZER };
+ enum PTHREAD_ONCE_INIT = pthread_once_t.init;
enum PTHREAD_COND_INITIALIZER = null;
enum PTHREAD_RWLOCK_INITIALIZER = null;
}
@@ -329,8 +330,7 @@ else version (DragonFlyBSD)
enum PTHREAD_DONE_INIT = 1;
enum PTHREAD_MUTEX_INITIALIZER = null;
- //enum PTHREAD_ONCE_INIT = { PTHREAD_NEEDS_INIT, NULL };
- enum PTHREAD_ONCE_INIT = pthread_once_t.init;;
+ enum PTHREAD_ONCE_INIT = pthread_once_t.init;
enum PTHREAD_COND_INITIALIZER = null;
enum PTHREAD_RWLOCK_INITIALIZER = null;
}
@@ -444,11 +444,11 @@ int pthread_atfork(void function(), void function(), void function());
@nogc {
int pthread_atfork(void function() @nogc, void function() @nogc, void function() @nogc);
int pthread_attr_destroy(pthread_attr_t*);
- int pthread_attr_getdetachstate(in pthread_attr_t*, int*);
- int pthread_attr_getschedparam(in pthread_attr_t*, sched_param*);
+ int pthread_attr_getdetachstate(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedparam(const scope pthread_attr_t*, sched_param*);
int pthread_attr_init(pthread_attr_t*);
int pthread_attr_setdetachstate(pthread_attr_t*, int);
- int pthread_attr_setschedparam(in pthread_attr_t*, sched_param*);
+ int pthread_attr_setschedparam(const scope pthread_attr_t*, sched_param*);
int pthread_cancel(pthread_t);
}
@@ -716,13 +716,13 @@ else
int pthread_cond_broadcast(pthread_cond_t*);
int pthread_cond_destroy(pthread_cond_t*);
-int pthread_cond_init(in pthread_cond_t*, pthread_condattr_t*) @trusted;
+int pthread_cond_init(const scope pthread_cond_t*, pthread_condattr_t*) @trusted;
int pthread_cond_signal(pthread_cond_t*);
-int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, in timespec*);
+int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);
int pthread_condattr_destroy(pthread_condattr_t*);
int pthread_condattr_init(pthread_condattr_t*);
-int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
+int pthread_create(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
int pthread_detach(pthread_t);
int pthread_equal(pthread_t, pthread_t);
void pthread_exit(void*);
@@ -742,7 +742,7 @@ int pthread_mutexattr_destroy(pthread_mutexattr_t*);
int pthread_mutexattr_init(pthread_mutexattr_t*) @trusted;
int pthread_once(pthread_once_t*, void function());
int pthread_rwlock_destroy(pthread_rwlock_t*);
-int pthread_rwlock_init(pthread_rwlock_t*, in pthread_rwlockattr_t*);
+int pthread_rwlock_init(pthread_rwlock_t*, const scope pthread_rwlockattr_t*);
int pthread_rwlock_rdlock(pthread_rwlock_t*);
int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
int pthread_rwlock_trywrlock(pthread_rwlock_t*);
@@ -753,7 +753,7 @@ int pthread_rwlockattr_init(pthread_rwlockattr_t*);
pthread_t pthread_self();
int pthread_setcancelstate(int, int*);
int pthread_setcanceltype(int, int*);
-int pthread_setspecific(pthread_key_t, in void*);
+int pthread_setspecific(pthread_key_t, const scope void*);
void pthread_testcancel();
//
@@ -763,10 +763,10 @@ void pthread_testcancel();
PTHREAD_BARRIER_SERIAL_THREAD
int pthread_barrier_destroy(pthread_barrier_t*);
-int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
-int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); (BAR|TSH)
+int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); (BAR|TSH)
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); (BAR|TSH)
*/
@@ -776,10 +776,10 @@ version (CRuntime_Glibc)
enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
int pthread_barrier_destroy(pthread_barrier_t*);
- int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+ int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
- int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
+ int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
}
@@ -788,10 +788,10 @@ else version (FreeBSD)
enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
int pthread_barrier_destroy(pthread_barrier_t*);
- int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+ int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
- int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
+ int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
}
@@ -803,10 +803,10 @@ else version (DragonFlyBSD)
enum PTHREAD_THREADS_MAX = c_ulong.max;
int pthread_barrier_destroy(pthread_barrier_t*);
- int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+ int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
- int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
+ int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
}
@@ -815,10 +815,10 @@ else version (NetBSD)
enum PTHREAD_BARRIER_SERIAL_THREAD = 1234567;
int pthread_barrier_destroy(pthread_barrier_t*);
- int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+ int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
- int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
+ int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
}
@@ -827,10 +827,10 @@ else version (OpenBSD)
enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
int pthread_barrier_destroy(pthread_barrier_t*);
- int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+ int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
- int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
+ int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
}
@@ -842,10 +842,10 @@ else version (Solaris)
enum PTHREAD_BARRIER_SERIAL_THREAD = -2;
int pthread_barrier_destroy(pthread_barrier_t*);
- int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+ int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
- int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
+ int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
}
@@ -857,10 +857,10 @@ else version (CRuntime_Musl)
enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
int pthread_barrier_destroy(pthread_barrier_t*);
- int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+ int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
- int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
+ int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
}
@@ -869,10 +869,10 @@ else version (CRuntime_UClibc)
enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
int pthread_barrier_destroy(pthread_barrier_t*);
- int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
+ int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
- int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
+ int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
}
@@ -885,22 +885,22 @@ else
// Clock (CS)
//
/*
-int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
+int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*);
int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
*/
version (CRuntime_Glibc)
{
- int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
+ int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*);
int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
}
else version (FreeBSD)
{
- int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
+ int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*);
int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
}
else version (DragonFlyBSD)
{
- int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
+ int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*);
int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
}
else version (NetBSD)
@@ -909,7 +909,7 @@ else version (NetBSD)
}
else version (OpenBSD)
{
- int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
+ int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*);
int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
}
else version (Darwin)
@@ -917,7 +917,7 @@ else version (Darwin)
}
else version (Solaris)
{
- int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
+ int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*);
int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
}
else version (CRuntime_Bionic)
@@ -925,12 +925,12 @@ else version (CRuntime_Bionic)
}
else version (CRuntime_Musl)
{
- int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
+ int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*);
int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
}
else version (CRuntime_UClibc)
{
- int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
+ int pthread_condattr_getclock(const scope pthread_condattr_t*, clockid_t*);
int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
}
else
@@ -1033,10 +1033,10 @@ PTHREAD_MUTEX_ERRORCHECK
PTHREAD_MUTEX_NORMAL
PTHREAD_MUTEX_RECURSIVE
-int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
-int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);
+int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
int pthread_setconcurrency(int);
*/
@@ -1048,10 +1048,10 @@ version (CRuntime_Glibc)
enum PTHREAD_MUTEX_ERRORCHECK = 2;
enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
- int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
int pthread_setconcurrency(int);
}
@@ -1062,10 +1062,10 @@ else version (Darwin)
enum PTHREAD_MUTEX_RECURSIVE = 2;
enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
- int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
int pthread_setconcurrency(int);
}
@@ -1081,7 +1081,7 @@ else version (FreeBSD)
}
enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
@@ -1099,7 +1099,7 @@ else version (NetBSD)
}
enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
@@ -1118,7 +1118,7 @@ else version (OpenBSD)
}
enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
@@ -1136,7 +1136,7 @@ else version (DragonFlyBSD)
}
enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
@@ -1154,7 +1154,7 @@ else version (Solaris)
enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
@@ -1168,9 +1168,9 @@ else version (CRuntime_Bionic)
enum PTHREAD_MUTEX_ERRORCHECK = 2;
enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
- int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
}
else version (CRuntime_Musl)
@@ -1198,10 +1198,10 @@ else version (CRuntime_UClibc)
PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
}
- int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_getconcurrency();
- int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
int pthread_setconcurrency(int);
}
@@ -1263,69 +1263,69 @@ else
// Timeouts (TMO)
//
/*
-int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
-int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
-int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
*/
version (CRuntime_Glibc)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (Darwin)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (FreeBSD)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (NetBSD)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (OpenBSD)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (DragonFlyBSD)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (Solaris)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (CRuntime_Bionic)
{
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (CRuntime_Musl)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else version (CRuntime_UClibc)
{
- int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);
- int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
- int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
+ int pthread_mutex_timedlock(pthread_mutex_t*, const scope timespec*);
+ int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const scope timespec*);
+ int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const scope timespec*);
}
else
{
@@ -1340,10 +1340,10 @@ PTHREAD_PRIO_INHERIT (TPI)
PTHREAD_PRIO_NONE (TPP|TPI)
PTHREAD_PRIO_PROTECT (TPI)
-int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*); (TPP)
+int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*); (TPP)
int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*); (TPP)
int pthread_mutexattr_getprioceiling(pthread_mutexattr_t*, int*); (TPP)
-int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*); (TPI|TPP)
+int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*); (TPI|TPP)
int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); (TPP)
int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); (TPI|TPP)
*/
@@ -1356,10 +1356,10 @@ version (Darwin)
PTHREAD_PRIO_PROTECT
}
- int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*);
+ int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*);
int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);
- int pthread_mutexattr_getprioceiling(in pthread_mutexattr_t*, int*);
- int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
}
@@ -1372,10 +1372,10 @@ else version (Solaris)
PTHREAD_PRIO_PROTECT = 0x20,
}
- int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*);
+ int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*);
int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);
- int pthread_mutexattr_getprioceiling(in pthread_mutexattr_t*, int*);
- int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
}
@@ -1387,14 +1387,14 @@ else version (Solaris)
PTHREAD_SCOPE_PROCESS
PTHREAD_SCOPE_SYSTEM
-int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
-int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
-int pthread_attr_getscope(in pthread_attr_t*, int*);
+int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
int pthread_attr_setscope(pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
-int pthread_setschedparam(pthread_t, int, in sched_param*);
+int pthread_setschedparam(pthread_t, int, const scope sched_param*);
int pthread_setschedprio(pthread_t, int);
*/
@@ -1406,14 +1406,14 @@ version (CRuntime_Glibc)
PTHREAD_SCOPE_PROCESS
}
- int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*, int*);
+ int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
int pthread_attr_setscope(pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
- int pthread_setschedparam(pthread_t, int, in sched_param*);
+ int pthread_setschedparam(pthread_t, int, const scope sched_param*);
int pthread_setschedprio(pthread_t, int);
}
else version (Darwin)
@@ -1424,14 +1424,14 @@ else version (Darwin)
PTHREAD_SCOPE_PROCESS = 2
}
- int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*, int*);
+ int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
int pthread_attr_setscope(pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
- int pthread_setschedparam(pthread_t, int, in sched_param*);
+ int pthread_setschedparam(pthread_t, int, const scope sched_param*);
// int pthread_setschedprio(pthread_t, int); // not implemented
}
else version (FreeBSD)
@@ -1442,12 +1442,12 @@ else version (FreeBSD)
PTHREAD_SCOPE_SYSTEM = 0x2
}
- int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*, int*);
+ int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
- int pthread_attr_setscope(in pthread_attr_t*, int);
+ int pthread_attr_setscope(const scope pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
int pthread_setschedparam(pthread_t, int, sched_param*);
// int pthread_setschedprio(pthread_t, int); // not implemented
@@ -1460,12 +1460,12 @@ else version (NetBSD)
PTHREAD_SCOPE_SYSTEM = 0x1
}
- int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*, int*);
+ int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
- int pthread_attr_setscope(in pthread_attr_t*, int);
+ int pthread_attr_setscope(const scope pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
int pthread_setschedparam(pthread_t, int, sched_param*);
//int pthread_setschedprio(pthread_t, int);
@@ -1478,12 +1478,12 @@ else version (OpenBSD)
PTHREAD_SCOPE_SYSTEM = 0x2
}
- int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*, int*);
+ int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
- int pthread_attr_setscope(in pthread_attr_t*, int);
+ int pthread_attr_setscope(const scope pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
int pthread_setschedparam(pthread_t, int, sched_param*);
// int pthread_setschedprio(pthread_t, int); // not implemented
@@ -1496,12 +1496,12 @@ else version (DragonFlyBSD)
PTHREAD_SCOPE_SYSTEM = 0x2
}
- int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*, int*);
+ int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
- int pthread_attr_setscope(in pthread_attr_t*, int);
+ int pthread_attr_setscope(const scope pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
int pthread_setschedparam(pthread_t, int, sched_param*);
}
@@ -1513,12 +1513,12 @@ else version (Solaris)
PTHREAD_SCOPE_SYSTEM = 1,
}
- int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*, int*);
+ int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
- int pthread_attr_setscope(in pthread_attr_t*, int);
+ int pthread_attr_setscope(const scope pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
int pthread_setschedparam(pthread_t, int, sched_param*);
int pthread_setschedprio(pthread_t, int);
@@ -1531,12 +1531,12 @@ else version (CRuntime_Bionic)
PTHREAD_SCOPE_PROCESS
}
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
int pthread_attr_setscope(pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
- int pthread_setschedparam(pthread_t, int, in sched_param*);
+ int pthread_setschedparam(pthread_t, int, const scope sched_param*);
}
else version (CRuntime_Musl)
{
@@ -1547,7 +1547,7 @@ else version (CRuntime_Musl)
}
int pthread_getschedparam(pthread_t, int*, sched_param*);
- int pthread_setschedparam(pthread_t, int, in sched_param*);
+ int pthread_setschedparam(pthread_t, int, const scope sched_param*);
int pthread_setschedprio(pthread_t, int);
}
else version (CRuntime_UClibc)
@@ -1558,14 +1558,14 @@ else version (CRuntime_UClibc)
PTHREAD_SCOPE_PROCESS
}
- int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
- int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
- int pthread_attr_getscope(in pthread_attr_t*, int*);
+ int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
+ int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*);
+ int pthread_attr_getscope(const scope pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
int pthread_attr_setscope(pthread_attr_t*, int);
int pthread_getschedparam(pthread_t, int*, sched_param*);
- int pthread_setschedparam(pthread_t, int, in sched_param*);
+ int pthread_setschedparam(pthread_t, int, const scope sched_param*);
int pthread_setschedprio(pthread_t, int);
}
else
@@ -1577,9 +1577,9 @@ else
// Stack (TSA|TSS)
//
/*
-int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); (TSA|TSS)
-int pthread_attr_getstackaddr(in pthread_attr_t*, void**); (TSA)
-int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); (TSS)
+int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); (TSA|TSS)
+int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); (TSA)
+int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); (TSS)
int pthread_attr_setstack(pthread_attr_t*, void*, size_t); (TSA|TSS)
int pthread_attr_setstackaddr(pthread_attr_t*, void*); (TSA)
int pthread_attr_setstacksize(pthread_attr_t*, size_t); (TSS)
@@ -1587,86 +1587,86 @@ int pthread_attr_setstacksize(pthread_attr_t*, size_t); (TSS)
version (CRuntime_Glibc)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (Darwin)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (FreeBSD)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (NetBSD)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (OpenBSD)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (DragonFlyBSD)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (Solaris)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (CRuntime_Bionic)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (CRuntime_Musl)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
}
else version (CRuntime_UClibc)
{
- int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
- int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
- int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
+ int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
+ int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
+ int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
@@ -1680,39 +1680,39 @@ else
// Shared Synchronization (TSH)
//
/*
-int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
+int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
-int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
+int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
-int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
+int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
*/
version (CRuntime_Glibc)
{
- int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
+ int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
- int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
- int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
+ int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
}
else version (FreeBSD)
{
- int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
+ int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
- int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
- int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
+ int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
}
else version (NetBSD)
{
- int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
+ int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
- int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
- int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
+ int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
}
else version (OpenBSD)
@@ -1720,29 +1720,29 @@ else version (OpenBSD)
}
else version (DragonFlyBSD)
{
- int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
+ int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
- int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
- int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
+ int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
}
else version (Darwin)
{
- int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
+ int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
- int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
- int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
+ int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
}
else version (Solaris)
{
- int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
+ int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
- int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
- int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
+ int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
}
else version (CRuntime_Bionic)
@@ -1765,11 +1765,11 @@ else version (CRuntime_Musl)
}
else version (CRuntime_UClibc)
{
- int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
+ int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
- int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
+ int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
- int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
+ int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
}
else
diff --git a/libphobos/libdruntime/core/sys/posix/pwd.d b/libphobos/libdruntime/core/sys/posix/pwd.d
index 9d9aaa3..e7ddda7 100644
--- a/libphobos/libdruntime/core/sys/posix/pwd.d
+++ b/libphobos/libdruntime/core/sys/posix/pwd.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.pwd;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for gid_t, uid_t
version (OSX)
@@ -30,6 +30,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required
@@ -44,7 +45,7 @@ struct passwd
char* pw_shell;
}
-passwd* getpwnam(in char*);
+passwd* getpwnam(const scope char*);
passwd* getpwuid(uid_t);
*/
@@ -201,47 +202,47 @@ else
static assert(false, "Unsupported platform");
}
-passwd* getpwnam(in char*);
+passwd* getpwnam(const scope char*);
passwd* getpwuid(uid_t);
//
// Thread-Safe Functions (TSF)
//
/*
-int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
*/
version (CRuntime_Glibc)
{
- int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+ int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
}
else version (Darwin)
{
- int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+ int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
}
else version (FreeBSD)
{
- int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+ int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
}
else version (NetBSD)
{
- int __getpwnam_r50(in char*, passwd*, char*, size_t, passwd**);
+ int __getpwnam_r50(const scope char*, passwd*, char*, size_t, passwd**);
alias __getpwnam_r50 getpwnam_r;
int __getpwuid_r50(uid_t, passwd*, char*, size_t, passwd**);
alias __getpwuid_r50 getpwuid_r;
}
else version (OpenBSD)
{
- int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+ int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
}
else version (DragonFlyBSD)
{
- int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+ int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
}
else version (Solaris)
@@ -250,7 +251,7 @@ else version (Solaris)
alias getpwuid_r = __posix_getpwuid_r;
// POSIX.1c standard version of the functions
- int __posix_getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+ int __posix_getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int __posix_getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
}
else version (CRuntime_Bionic)
@@ -258,12 +259,12 @@ else version (CRuntime_Bionic)
}
else version (CRuntime_Musl)
{
- int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+ int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
}
else version (CRuntime_UClibc)
{
- int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);
+ int getpwnam_r(const scope char*, passwd*, char*, size_t, passwd**);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
}
else
diff --git a/libphobos/libdruntime/core/sys/posix/sched.d b/libphobos/libdruntime/core/sys/posix/sched.d
index 9cf80bd..f9d2862 100644
--- a/libphobos/libdruntime/core/sys/posix/sched.d
+++ b/libphobos/libdruntime/core/sys/posix/sched.d
@@ -15,7 +15,7 @@
*/
module core.sys.posix.sched;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.time;
public import core.sys.posix.sys.types;
@@ -32,6 +32,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required
@@ -53,8 +54,8 @@ SCHED_OTHER
int sched_getparam(pid_t, sched_param*);
int sched_getscheduler(pid_t);
-int sched_setparam(pid_t, in sched_param*);
-int sched_setscheduler(pid_t, int, in sched_param*);
+int sched_setparam(pid_t, const scope sched_param*);
+int sched_setscheduler(pid_t, int, const scope sched_param*);
*/
version (CRuntime_Glibc)
@@ -189,8 +190,8 @@ else
int sched_getparam(pid_t, sched_param*);
int sched_getscheduler(pid_t);
-int sched_setparam(pid_t, in sched_param*);
-int sched_setscheduler(pid_t, int, in sched_param*);
+int sched_setparam(pid_t, const scope sched_param*);
+int sched_setscheduler(pid_t, int, const scope sched_param*);
//
// Thread (THR)
diff --git a/libphobos/libdruntime/core/sys/posix/semaphore.d b/libphobos/libdruntime/core/sys/posix/semaphore.d
index cae4777..4f6f639 100644
--- a/libphobos/libdruntime/core/sys/posix/semaphore.d
+++ b/libphobos/libdruntime/core/sys/posix/semaphore.d
@@ -14,8 +14,8 @@
*/
module core.sys.posix.semaphore;
-private import core.sys.posix.config;
-private import core.sys.posix.time;
+import core.sys.posix.config;
+import core.sys.posix.time;
version (OSX)
version = Darwin;
@@ -30,6 +30,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required
@@ -42,10 +43,10 @@ int sem_close(sem_t*);
int sem_destroy(sem_t*);
int sem_getvalue(sem_t*, int*);
int sem_init(sem_t*, int, uint);
-sem_t* sem_open(in char*, int, ...);
+sem_t* sem_open(const scope char*, int, ...);
int sem_post(sem_t*);
int sem_trywait(sem_t*);
-int sem_unlink(in char*);
+int sem_unlink(const scope char*);
int sem_wait(sem_t*);
*/
@@ -169,58 +170,58 @@ int sem_close(sem_t*);
int sem_destroy(sem_t*);
int sem_getvalue(sem_t*, int*);
int sem_init(sem_t*, int, uint);
-sem_t* sem_open(in char*, int, ...);
+sem_t* sem_open(const scope char*, int, ...);
int sem_post(sem_t*);
int sem_trywait(sem_t*);
-int sem_unlink(in char*);
+int sem_unlink(const scope char*);
int sem_wait(sem_t*);
//
// Timeouts (TMO)
//
/*
-int sem_timedwait(sem_t*, in timespec*);
+int sem_timedwait(sem_t*, const scope timespec*);
*/
version (CRuntime_Glibc)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (Darwin)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (FreeBSD)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (NetBSD)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (OpenBSD)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (DragonFlyBSD)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (Solaris)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (CRuntime_Bionic)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (CRuntime_Musl)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else version (CRuntime_UClibc)
{
- int sem_timedwait(sem_t*, in timespec*);
+ int sem_timedwait(sem_t*, const scope timespec*);
}
else
{
diff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d
index 38d4f70..b98d321 100644
--- a/libphobos/libdruntime/core/sys/posix/setjmp.d
+++ b/libphobos/libdruntime/core/sys/posix/setjmp.d
@@ -14,11 +14,12 @@
*/
module core.sys.posix.setjmp;
-private import core.sys.posix.config;
-private import core.sys.posix.signal; // for sigset_t
+import core.sys.posix.config;
+import core.sys.posix.signal; // for sigset_t
version (Posix):
extern (C) nothrow @nogc:
+@system:
version (RISCV32) version = RISCV_Any;
version (RISCV64) version = RISCV_Any;
@@ -151,7 +152,8 @@ version (CRuntime_Glibc)
c_long __pc;
c_long[12] __regs;
c_long __sp;
- double[12] __fpregs;
+ static if (__traits(getTargetInfo, "floatAbi") == "double")
+ double[12] __fpregs;
}
alias __jmp_buf = __riscv_jmp_buf[1];
}
@@ -210,7 +212,7 @@ else version (FreeBSD)
{
enum _JBLEN = 31;
// __int128_t
- struct _jmp_buf { long[2][_JBLEN + 1] _jb; };
+ struct _jmp_buf { long[2][_JBLEN + 1] _jb; }
}
else version (PPC_Any)
{
@@ -362,7 +364,7 @@ else version (CRuntime_UClibc)
double[8] __fpregs;
else
double[6] __fpregs;
- };
+ }
}
else
static assert(0, "unimplemented");
@@ -422,7 +424,7 @@ else version (FreeBSD)
else version (AArch64)
{
// __int128_t
- struct _sigjmp_buf { long[2][_JBLEN + 1] _jb; };
+ struct _sigjmp_buf { long[2][_JBLEN + 1] _jb; }
}
else version (PPC_Any)
{
diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d
index 9a97709..0dce8c5 100644
--- a/libphobos/libdruntime/core/sys/posix/signal.d
+++ b/libphobos/libdruntime/core/sys/posix/signal.d
@@ -11,7 +11,7 @@
module core.sys.posix.signal;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.signal;
public import core.sys.posix.sys.types; // for pid_t
//public import core.sys.posix.time; // for timespec, now defined here
@@ -43,7 +43,8 @@ version (X86_64) version = X86_Any;
version (Posix):
extern (C):
-//nothrow: // this causes Issue 12738
+//nothrow: // this causes http://issues.dlang.org/show_bug.cgi?id=12738 (which has been fixed)
+//@system:
//
// Required
@@ -150,30 +151,6 @@ version (Solaris)
return sig;
}
}
-else version (CRuntime_Glibc)
-{
- private extern (C) nothrow @nogc
- {
- int __libc_current_sigrtmin();
- int __libc_current_sigrtmax();
- }
-
- @property int SIGRTMIN() nothrow @nogc {
- __gshared static int sig = -1;
- if (sig == -1) {
- sig = __libc_current_sigrtmin();
- }
- return sig;
- }
-
- @property int SIGRTMAX() nothrow @nogc {
- __gshared static int sig = -1;
- if (sig == -1) {
- sig = __libc_current_sigrtmax();
- }
- return sig;
- }
-}
else version (FreeBSD) {
// Note: it appears that FreeBSD (prior to 7) and OSX do not support realtime signals
// https://github.com/freebsd/freebsd/blob/e79c62ff68fc74d88cb6f479859f6fae9baa5101/sys/sys/signal.h#L117
@@ -189,9 +166,11 @@ else version (NetBSD)
enum SIGRTMIN = 33;
enum SIGRTMAX = 63;
}
-else version (CRuntime_Bionic)
+else version (linux)
{
- // Switched to calling these functions since Lollipop
+ // Note: CRuntime_Bionic switched to calling these functions
+ // since Lollipop, and Glibc, UClib and Musl all implement them
+ // the same way since it's part of LSB.
private extern (C) nothrow @nogc
{
int __libc_current_sigrtmin();
@@ -214,24 +193,6 @@ else version (CRuntime_Bionic)
return sig;
}
}
-else version (CRuntime_UClibc)
-{
- private extern (C) nothrow @nogc
- {
- int __libc_current_sigrtmin();
- int __libc_current_sigrtmax();
- }
-
- @property int SIGRTMIN() nothrow @nogc
- {
- return __libc_current_sigrtmin();
- }
-
- @property int SIGRTMAX() nothrow @nogc
- {
- return __libc_current_sigrtmax();
- }
-}
version (linux)
{
@@ -874,16 +835,16 @@ SI_ASYNCIO
SI_MESGQ
int kill(pid_t, int);
-int sigaction(int, in sigaction_t*, sigaction_t*);
+int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t*);
int sigfillset(sigset_t*);
-int sigismember(in sigset_t*, int);
+int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t*);
-int sigprocmask(int, in sigset_t*, sigset_t*);
-int sigsuspend(in sigset_t*);
-int sigwait(in sigset_t*, int*);
+int sigprocmask(int, const scope sigset_t*, sigset_t*);
+int sigsuspend(const scope sigset_t*);
+int sigwait(const scope sigset_t*, int*);
*/
nothrow @nogc
@@ -1007,16 +968,16 @@ version (CRuntime_Glibc)
}
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t*);
int sigfillset(sigset_t*);
- int sigismember(in sigset_t*, int);
+ int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t*);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else version (Darwin)
{
@@ -1059,16 +1020,16 @@ else version (Darwin)
enum SI_MESGQ = 0x10005;
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t*);
int sigfillset(sigset_t*);
- int sigismember(in sigset_t*, int);
+ int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t*);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else version (FreeBSD)
{
@@ -1137,16 +1098,16 @@ else version (FreeBSD)
enum SI_MESGQ = 0x10005;
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t *);
int sigfillset(sigset_t *);
- int sigismember(in sigset_t*, int);
+ int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t *);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else version (NetBSD)
{
@@ -1223,16 +1184,16 @@ else version (NetBSD)
enum SI_MESGQ = -4;
int kill(pid_t, int);
- int __sigaction14(int, in sigaction_t*, sigaction_t*);
+ int __sigaction14(int, const scope sigaction_t*, sigaction_t*);
int __sigaddset14(sigset_t*, int);
int __sigdelset14(sigset_t*, int);
int __sigemptyset14(sigset_t *);
int __sigfillset14(sigset_t *);
- int __sigismember14(in sigset_t*, int);
+ int __sigismember14(const scope sigset_t*, int);
int __sigpending14(sigset_t *);
- int __sigprocmask14(int, in sigset_t*, sigset_t*);
- int __sigsuspend14(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int __sigprocmask14(int, const scope sigset_t*, sigset_t*);
+ int __sigsuspend14(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
alias __sigaction14 sigaction;
alias __sigaddset14 sigaddset;
@@ -1309,16 +1270,16 @@ else version (OpenBSD)
enum SI_TIMER = -3;
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t *);
int sigfillset(sigset_t *);
- int sigismember(in sigset_t*, int);
+ int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t *);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else version (DragonFlyBSD)
{
@@ -1358,16 +1319,16 @@ else version (DragonFlyBSD)
enum SI_MESGQ = -4;
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t *);
int sigfillset(sigset_t *);
- int sigismember(in sigset_t*, int);
+ int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t *);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else version (Solaris)
{
@@ -1467,21 +1428,21 @@ else version (Solaris)
}
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t*);
int sigfillset(sigset_t*);
- int sigismember(in sigset_t*, int);
+ int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t*);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else version (CRuntime_Bionic)
{
public import core.sys.posix.time: timer_t;
- private import core.stdc.string : memset;
+ import core.stdc.string : memset;
version (X86)
{
@@ -1581,7 +1542,7 @@ else version (CRuntime_Bionic)
}
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
// These functions are defined inline in bionic.
int sigaddset(sigset_t* set, int signum)
@@ -1612,9 +1573,9 @@ else version (CRuntime_Bionic)
}
int sigpending(sigset_t*);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else version (CRuntime_Musl)
{
@@ -1724,16 +1685,16 @@ else version (CRuntime_Musl)
}
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t*);
int sigfillset(sigset_t*);
- int sigismember(in sigset_t*, int);
+ int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t*);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else version (CRuntime_UClibc)
{
@@ -1967,16 +1928,16 @@ else version (CRuntime_UClibc)
}
int kill(pid_t, int);
- int sigaction(int, in sigaction_t*, sigaction_t*);
+ int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigemptyset(sigset_t*);
int sigfillset(sigset_t*);
- int sigismember(in sigset_t*, int);
+ int sigismember(const scope sigset_t*, int);
int sigpending(sigset_t*);
- int sigprocmask(int, in sigset_t*, sigset_t*);
- int sigsuspend(in sigset_t*);
- int sigwait(in sigset_t*, int*);
+ int sigprocmask(int, const scope sigset_t*, sigset_t*);
+ int sigsuspend(const scope sigset_t*);
+ int sigwait(const scope sigset_t*, int*);
}
else
{
@@ -2069,7 +2030,7 @@ sigfn_t bsd_signal(int sig, sigfn_t func);
sigfn_t sigset(int sig, sigfn_t func);
int killpg(pid_t, int);
-int sigaltstack(in stack_t*, stack_t*);
+int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -2261,7 +2222,7 @@ version (CRuntime_Glibc)
sigfn_t2 sigset(int sig, sigfn_t2 func);
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -2371,7 +2332,7 @@ else version (Darwin)
sigfn_t2 sigset(int sig, sigfn_t2 func);
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -2406,7 +2367,7 @@ else version (FreeBSD)
enum MINSIGSTKSZ = 512 * 4;
enum SIGSTKSZ = (MINSIGSTKSZ + 32768);
-;
+
//ucontext_t (defined in core.sys.posix.ucontext)
//mcontext_t (defined in core.sys.posix.ucontext)
@@ -2495,7 +2456,7 @@ else version (FreeBSD)
sigfn_t2 sigset(int sig, sigfn_t2 func);
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -2530,7 +2491,7 @@ else version (NetBSD)
enum MINSIGSTKSZ = 8192;
enum SIGSTKSZ = (MINSIGSTKSZ + 32768);
-;
+
//ucontext_t (defined in core.sys.posix.ucontext)
//mcontext_t (defined in core.sys.posix.ucontext)
@@ -2619,7 +2580,7 @@ else version (NetBSD)
sigfn_t2 sigset(int sig, sigfn_t2 func);
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -2738,7 +2699,7 @@ else version (OpenBSD)
nothrow:
@nogc:
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int siginterrupt(int, int);
int sigpause(int);
}
@@ -2770,7 +2731,7 @@ else version (DragonFlyBSD)
enum MINSIGSTKSZ = 8192;
enum SIGSTKSZ = (MINSIGSTKSZ + 32768);
-;
+
//ucontext_t (defined in core.sys.posix.ucontext)
//mcontext_t (defined in core.sys.posix.ucontext)
@@ -2859,7 +2820,7 @@ else version (DragonFlyBSD)
sigfn_t2 sigset(int sig, sigfn_t2 func);
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -2983,7 +2944,7 @@ else version (Solaris)
sigfn_t2 sigset(int sig, sigfn_t2 func);
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -3088,7 +3049,7 @@ else version (CRuntime_Bionic)
sigfn_t2 bsd_signal(int, sigfn_t2);
int killpg(int, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int siginterrupt(int, int);
}
else version (CRuntime_Musl)
@@ -3258,7 +3219,7 @@ else version (CRuntime_Musl)
sigfn_t2 sigset(int sig, sigfn_t2 func);
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -3440,7 +3401,7 @@ else version (CRuntime_UClibc)
sigfn_t2 sigset(int sig, sigfn_t2 func);
int killpg(pid_t, int);
- int sigaltstack(in stack_t*, stack_t*);
+ int sigaltstack(const scope stack_t*, stack_t*);
int sighold(int);
int sigignore(int);
int siginterrupt(int, int);
@@ -3542,9 +3503,9 @@ struct sigevent
pthread_attr_t* sigev_notify_attributes;
}
-int sigqueue(pid_t, int, in sigval);
-int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);
-int sigwaitinfo(in sigset_t*, siginfo_t*);
+int sigqueue(pid_t, int, const sigval);
+int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*);
+int sigwaitinfo(const scope sigset_t*, siginfo_t*);
*/
nothrow:
@@ -3582,9 +3543,9 @@ version (CRuntime_Glibc)
} _sigev_un_t _sigev_un;
}
- int sigqueue(pid_t, int, in sigval);
- int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);
- int sigwaitinfo(in sigset_t*, siginfo_t*);
+ int sigqueue(pid_t, int, const sigval);
+ int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*);
+ int sigwaitinfo(const scope sigset_t*, siginfo_t*);
}
else version (FreeBSD)
{
@@ -3605,9 +3566,9 @@ else version (FreeBSD)
}
}
- int sigqueue(pid_t, int, in sigval);
- int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);
- int sigwaitinfo(in sigset_t*, siginfo_t*);
+ int sigqueue(pid_t, int, const sigval);
+ int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*);
+ int sigwaitinfo(const scope sigset_t*, siginfo_t*);
}
else version (NetBSD)
{
@@ -3620,9 +3581,9 @@ else version (NetBSD)
void /* pthread_attr_t */*sigev_notify_attributes;
}
- int sigqueue(pid_t, int, in sigval);
- int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);
- int sigwaitinfo(in sigset_t*, siginfo_t*);
+ int sigqueue(pid_t, int, const sigval);
+ int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*);
+ int sigwaitinfo(const scope sigset_t*, siginfo_t*);
}
else version (OpenBSD)
{
@@ -3636,14 +3597,14 @@ else version (DragonFlyBSD)
int sigev_signo;
int sigev_notify_kqueue;
void /*pthread_attr_t*/ * sigev_notify_attributes;
- };
+ }
union _sigval_t
{
int sival_int;
void * sival_ptr;
int sigval_int;
void * sigval_ptr;
- };
+ }
struct sigevent
{
int sigev_notify;
@@ -3652,9 +3613,9 @@ else version (DragonFlyBSD)
void function(_sigval_t) sigev_notify_function;
}
- int sigqueue(pid_t, int, in sigval);
- int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);
- int sigwaitinfo(in sigset_t*, siginfo_t*);
+ int sigqueue(pid_t, int, const sigval);
+ int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*);
+ int sigwaitinfo(const scope sigset_t*, siginfo_t*);
}
else version (Darwin)
{
@@ -3679,9 +3640,9 @@ else version (Solaris)
int __sigev_pad2;
}
- int sigqueue(pid_t, int, in sigval);
- int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);
- int sigwaitinfo(in sigset_t*, siginfo_t*);
+ int sigqueue(pid_t, int, const sigval);
+ int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*);
+ int sigwaitinfo(const scope sigset_t*, siginfo_t*);
}
else version (CRuntime_Bionic)
{
@@ -3756,9 +3717,9 @@ else version (CRuntime_UClibc)
@property void function(sigval) sigev_notify_function(ref sigevent _sigevent) { return _sigevent._sigev_un._sigev_thread._function; }
@property void* sigev_notify_attributes(ref sigevent _sigevent) { return _sigevent._sigev_un._sigev_thread._attribute; }
- int sigqueue(pid_t, int, in sigval);
- int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);
- int sigwaitinfo(in sigset_t*, siginfo_t*);
+ int sigqueue(pid_t, int, const sigval);
+ int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*);
+ int sigwaitinfo(const scope sigset_t*, siginfo_t*);
}
else
{
@@ -3770,58 +3731,58 @@ else
//
/*
int pthread_kill(pthread_t, int);
-int pthread_sigmask(int, in sigset_t*, sigset_t*);
+int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
*/
version (CRuntime_Glibc)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (Darwin)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (FreeBSD)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (NetBSD)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (OpenBSD)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (DragonFlyBSD)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (Solaris)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (CRuntime_Bionic)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (CRuntime_Musl)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
}
else version (CRuntime_UClibc)
{
int pthread_kill(pthread_t, int);
- int pthread_sigmask(int, in sigset_t*, sigset_t*);
+ int pthread_sigmask(int, const scope sigset_t*, sigset_t*);
int pthread_sigqueue(pthread_t, int, sigval);
}
else
diff --git a/libphobos/libdruntime/core/sys/posix/spawn.d b/libphobos/libdruntime/core/sys/posix/spawn.d
index aa59c2f..86b1751 100644
--- a/libphobos/libdruntime/core/sys/posix/spawn.d
+++ b/libphobos/libdruntime/core/sys/posix/spawn.d
@@ -49,6 +49,7 @@ public import core.sys.posix.sched : sched_param;
extern(C):
@nogc:
nothrow:
+@system:
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int);
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int, int);
diff --git a/libphobos/libdruntime/core/sys/posix/stdc/time.d b/libphobos/libdruntime/core/sys/posix/stdc/time.d
new file mode 100644
index 0000000..89029de
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/posix/stdc/time.d
@@ -0,0 +1,191 @@
+/**
+ * D header file for C99.
+ *
+ * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_time.h.html, _time.h)
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2009.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly,
+ * Alex Rønne Petersen
+ * Source: $(DRUNTIMESRC core/stdc/_time.d)
+ * Standards: ISO/IEC 9899:1999 (E)
+ */
+
+module core.sys.posix.stdc.time;
+
+version (Posix):
+
+import core.stdc.config;
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+extern (C):
+@trusted: // There are only a few functions here that use unsafe C strings.
+nothrow:
+@nogc:
+
+///
+struct tm
+{
+ int tm_sec; /// seconds after the minute [0-60]
+ int tm_min; /// minutes after the hour [0-59]
+ int tm_hour; /// hours since midnight [0-23]
+ int tm_mday; /// day of the month [1-31]
+ int tm_mon; /// months since January [0-11]
+ int tm_year; /// years since 1900
+ int tm_wday; /// days since Sunday [0-6]
+ int tm_yday; /// days since January 1 [0-365]
+ int tm_isdst; /// Daylight Savings Time flag
+ c_long tm_gmtoff; /// offset from CUT in seconds
+ char* tm_zone; /// timezone abbreviation
+}
+
+public import core.sys.posix.sys.types : time_t, clock_t;
+
+///
+version (OSX)
+{
+ enum clock_t CLOCKS_PER_SEC = 1_000_000; // was 100 until OSX 10.4/10.5
+ version (X86)
+ extern (C) pragma(mangle, "clock$UNIX2003") clock_t clock();
+ else
+ clock_t clock();
+}
+else version (Darwin) // other Darwins (iOS, TVOS, WatchOS)
+{
+ enum clock_t CLOCKS_PER_SEC = 1_000_000;
+ clock_t clock();
+}
+else version (FreeBSD)
+{
+ enum clock_t CLOCKS_PER_SEC = 128;
+ clock_t clock();
+}
+else version (NetBSD)
+{
+ enum clock_t CLOCKS_PER_SEC = 100;
+ clock_t clock();
+}
+else version (OpenBSD)
+{
+ enum clock_t CLOCKS_PER_SEC = 100;
+ clock_t clock();
+}
+else version (DragonFlyBSD)
+{
+ enum clock_t CLOCKS_PER_SEC = 128;
+ clock_t clock();
+}
+else version (Solaris)
+{
+ enum clock_t CLOCKS_PER_SEC = 1_000_000;
+ clock_t clock();
+}
+else version (CRuntime_Glibc)
+{
+ enum clock_t CLOCKS_PER_SEC = 1_000_000;
+ clock_t clock();
+}
+else version (CRuntime_Musl)
+{
+ enum clock_t CLOCKS_PER_SEC = 1_000_000;
+ clock_t clock();
+}
+else version (CRuntime_Bionic)
+{
+ enum clock_t CLOCKS_PER_SEC = 1_000_000;
+ clock_t clock();
+}
+else version (CRuntime_UClibc)
+{
+ enum clock_t CLOCKS_PER_SEC = 1_000_000;
+ clock_t clock();
+}
+else
+{
+ static assert(0, "unsupported system");
+}
+
+version (Darwin)
+{
+ ///
+ void tzset(); // non-standard
+ ///
+ extern __gshared const(char)*[2] tzname; // non-standard
+}
+else version (CRuntime_Glibc)
+{
+ ///
+ void tzset(); // non-standard
+ ///
+ extern __gshared const(char)*[2] tzname; // non-standard
+}
+else version (FreeBSD)
+{
+ ///
+ void tzset(); // non-standard
+ ///
+ extern __gshared const(char)*[2] tzname; // non-standard
+}
+else version (NetBSD)
+{
+ ///
+ void tzset(); // non-standard
+ ///
+ extern __gshared const(char)*[2] tzname; // non-standard
+}
+else version (OpenBSD)
+{
+ ///
+ void tzset(); // non-standard
+ ///
+ extern __gshared const(char)*[2] tzname; // non-standard
+}
+else version (DragonFlyBSD)
+{
+ ///
+ void tzset(); // non-standard
+ ///
+ extern __gshared const(char)*[2] tzname; // non-standard
+}
+else version (Solaris)
+{
+ ///
+ void tzset();
+ ///
+ extern __gshared const(char)*[2] tzname;
+}
+else version (CRuntime_Bionic)
+{
+ ///
+ void tzset();
+ ///
+ extern __gshared const(char)*[2] tzname;
+}
+else version (CRuntime_Musl)
+{
+ ///
+ void tzset(); // non-standard
+ ///
+ extern __gshared const(char)*[2] tzname; // non-standard
+}
+else version (CRuntime_UClibc)
+{
+ ///
+ void tzset();
+ ///
+ extern __gshared const(char)*[2] tzname;
+}
+else
+{
+ static assert(false, "Unsupported platform");
+}
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index bc2329e..41b52da 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.stdio;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.stdio;
public import core.sys.posix.sys.types; // for off_t
@@ -32,6 +32,7 @@ extern (C):
nothrow:
@nogc:
+@system:
//
// Required (defined in core.stdc.stdio)
@@ -65,44 +66,44 @@ int fflush(FILE*);
int fgetc(FILE*);
int fgetpos(FILE*, fpos_t *);
char* fgets(char*, int, FILE*);
-FILE* fopen(in char*, in char*);
-int fprintf(FILE*, in char*, ...);
+FILE* fopen(const scope char*, const scope char*);
+int fprintf(FILE*, const scope char*, ...);
int fputc(int, FILE*);
-int fputs(in char*, FILE*);
+int fputs(const scope char*, FILE*);
size_t fread(void *, size_t, size_t, FILE*);
-FILE* freopen(in char*, in char*, FILE*);
-int fscanf(FILE*, in char*, ...);
+FILE* freopen(const scope char*, const scope char*, FILE*);
+int fscanf(FILE*, const scope char*, ...);
int fseek(FILE*, c_long, int);
-int fsetpos(FILE*, in fpos_t*);
+int fsetpos(FILE*, const scope fpos_t*);
c_long ftell(FILE*);
size_t fwrite(in void *, size_t, size_t, FILE*);
int getc(FILE*);
int getchar();
char* gets(char*);
-void perror(in char*);
-int printf(in char*, ...);
+void perror(const scope char*);
+int printf(const scope char*, ...);
int putc(int, FILE*);
int putchar(int);
-int puts(in char*);
-int remove(in char*);
-int rename(in char*, in char*);
+int puts(const scope char*);
+int remove(const scope char*);
+int rename(const scope char*, const scope char*);
void rewind(FILE*);
-int scanf(in char*, ...);
+int scanf(const scope char*, ...);
void setbuf(FILE*, char*);
int setvbuf(FILE*, char*, int, size_t);
-int snprintf(char*, size_t, in char*, ...);
-int sprintf(char*, in char*, ...);
-int sscanf(in char*, in char*, int ...);
+int snprintf(char*, size_t, const scope char*, ...);
+int sprintf(char*, const scope char*, ...);
+int sscanf(const scope char*, const scope char*, int ...);
FILE* tmpfile();
char* tmpnam(char*);
int ungetc(int, FILE*);
-int vfprintf(FILE*, in char*, va_list);
-int vfscanf(FILE*, in char*, va_list);
-int vprintf(in char*, va_list);
-int vscanf(in char*, va_list);
-int vsnprintf(char*, size_t, in char*, va_list);
-int vsprintf(char*, in char*, va_list);
-int vsscanf(in char*, in char*, va_list arg);
+int vfprintf(FILE*, const scope char*, va_list);
+int vfscanf(FILE*, const scope char*, va_list);
+int vprintf(const scope char*, va_list);
+int vscanf(const scope char*, va_list);
+int vsnprintf(char*, size_t, const scope char*, va_list);
+int vsprintf(char*, const scope char*, va_list);
+int vsscanf(const scope char*, const scope char*, va_list arg);
*/
version (CRuntime_Glibc)
@@ -117,15 +118,15 @@ version (CRuntime_Glibc)
int fgetpos64(FILE*, fpos_t *);
alias fgetpos64 fgetpos;
- FILE* fopen64(in char*, in char*);
+ FILE* fopen64(const scope char*, const scope char*);
alias fopen64 fopen;
- FILE* freopen64(in char*, in char*, FILE*);
+ FILE* freopen64(const scope char*, const scope char*, FILE*);
alias freopen64 freopen;
int fseek(FILE*, c_long, int);
- int fsetpos64(FILE*, in fpos_t*);
+ int fsetpos64(FILE*, const scope fpos_t*);
alias fsetpos64 fsetpos;
FILE* tmpfile64();
@@ -134,20 +135,20 @@ version (CRuntime_Glibc)
else
{
int fgetpos(FILE*, fpos_t *);
- FILE* fopen(in char*, in char*);
- FILE* freopen(in char*, in char*, FILE*);
+ FILE* fopen(const scope char*, const scope char*);
+ FILE* freopen(const scope char*, const scope char*, FILE*);
int fseek(FILE*, c_long, int);
- int fsetpos(FILE*, in fpos_t*);
+ int fsetpos(FILE*, const scope fpos_t*);
FILE* tmpfile();
}
}
else version (CRuntime_Bionic)
{
int fgetpos(FILE*, fpos_t *);
- FILE* fopen(in char*, in char*);
- FILE* freopen(in char*, in char*, FILE*);
+ FILE* fopen(const scope char*, const scope char*);
+ FILE* freopen(const scope char*, const scope char*, FILE*);
int fseek(FILE*, c_long, int);
- int fsetpos(FILE*, in fpos_t*);
+ int fsetpos(FILE*, const scope fpos_t*);
}
else version (CRuntime_UClibc)
{
@@ -156,15 +157,15 @@ else version (CRuntime_UClibc)
int fgetpos64(FILE*, fpos_t *);
alias fgetpos64 fgetpos;
- FILE* fopen64(in char*, in char*);
+ FILE* fopen64(const scope char*, const scope char*);
alias fopen64 fopen;
- FILE* freopen64(in char*, in char*, FILE*);
+ FILE* freopen64(const scope char*, const scope char*, FILE*);
alias freopen64 freopen;
int fseek(FILE*, c_long, int);
- int fsetpos64(FILE*, in fpos_t*);
+ int fsetpos64(FILE*, const scope fpos_t*);
alias fsetpos64 fsetpos;
FILE* tmpfile64();
@@ -173,10 +174,10 @@ else version (CRuntime_UClibc)
else
{
int fgetpos(FILE*, fpos_t *);
- FILE* fopen(in char*, in char*);
- FILE* freopen(in char*, in char*, FILE*);
+ FILE* fopen(const scope char*, const scope char*);
+ FILE* freopen(const scope char*, const scope char*, FILE*);
int fseek(FILE*, c_long, int);
- int fsetpos(FILE*, in fpos_t*);
+ int fsetpos(FILE*, const scope fpos_t*);
FILE* tmpfile();
}
}
@@ -187,15 +188,15 @@ else version (CRuntime_Musl)
int fgetpos64(FILE*, fpos_t *);
alias fgetpos64 fgetpos;
- FILE* fopen64(in char*, in char*);
+ FILE* fopen64(const scope char*, const scope char*);
alias fopen64 fopen;
- FILE* freopen64(in char*, in char*, FILE*);
+ FILE* freopen64(const scope char*, const scope char*, FILE*);
alias freopen64 freopen;
int fseek(FILE*, c_long, int);
- int fsetpos64(FILE*, in fpos_t*);
+ int fsetpos64(FILE*, const scope fpos_t*);
alias fsetpos64 fsetpos;
FILE* tmpfile64();
@@ -204,10 +205,10 @@ else version (CRuntime_Musl)
else
{
int fgetpos(FILE*, fpos_t *);
- FILE* fopen(in char*, in char*);
- FILE* freopen(in char*, in char*, FILE*);
+ FILE* fopen(const scope char*, const scope char*);
+ FILE* freopen(const scope char*, const scope char*, FILE*);
int fseek(FILE*, c_long, int);
- int fsetpos(FILE*, in fpos_t*);
+ int fsetpos(FILE*, const scope fpos_t*);
FILE* tmpfile();
}
}
@@ -218,15 +219,15 @@ else version (Solaris)
int fgetpos64(FILE*, fpos_t *);
alias fgetpos = fgetpos64;
- FILE* fopen64(in char*, in char*);
+ FILE* fopen64(const scope char*, const scope char*);
alias fopen = fopen64;
- FILE* freopen64(in char*, in char*, FILE*);
+ FILE* freopen64(const scope char*, const scope char*, FILE*);
alias freopen = freopen64;
int fseek(FILE*, c_long, int);
- int fsetpos64(FILE*, in fpos_t*);
+ int fsetpos64(FILE*, const scope fpos_t*);
alias fsetpos = fsetpos64;
FILE* tmpfile64();
@@ -235,10 +236,10 @@ else version (Solaris)
else
{
int fgetpos(FILE*, fpos_t *);
- FILE* fopen(in char*, in char*);
- FILE* freopen(in char*, in char*, FILE*);
+ FILE* fopen(const scope char*, const scope char*);
+ FILE* freopen(const scope char*, const scope char*, FILE*);
int fseek(FILE*, c_long, int);
- int fsetpos(FILE*, in fpos_t*);
+ int fsetpos(FILE*, const scope fpos_t*);
FILE* tmpfile();
}
}
@@ -249,64 +250,72 @@ else version (Solaris)
/*
L_ctermid
-char* ctermid(char*);
-FILE* fdopen(int, in char*);
-int fileno(FILE*);
-int fseeko(FILE*, off_t, int);
-off_t ftello(FILE*);
-char* gets(char*);
-int pclose(FILE*);
-FILE* popen(in char*, in char*);
+char* ctermid(char*);
+FILE* fdopen(int, const scope char*);
+int fileno(FILE*);
+int fseeko(FILE*, off_t, int);
+off_t ftello(FILE*);
+ssize_t getdelim(char**, size_t*, int, FILE*);
+ssize_t getline(char**, size_t*, FILE*);
+char* gets(char*);
+int pclose(FILE*);
+FILE* popen(const scope char*, const scope char*);
*/
version (CRuntime_Glibc)
{
enum L_ctermid = 9;
- static if ( __USE_FILE_OFFSET64 )
- {
- int fseeko64(FILE*, off_t, int);
- alias fseeko64 fseeko;
- }
- else
- {
- int fseeko(FILE*, off_t, int);
- }
-
- static if ( __USE_FILE_OFFSET64 )
- {
- off_t ftello64(FILE*);
- alias ftello64 ftello;
- }
- else
- {
- off_t ftello(FILE*);
- }
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (CRuntime_UClibc)
{
enum L_ctermid = 9;
enum L_cuserid = 9;
- static if ( __USE_FILE_OFFSET64 )
- {
- int fseeko64(FILE*, off_t, int);
- alias fseeko64 fseeko;
- }
- else
- {
- int fseeko(FILE*, off_t, int);
- }
-
- static if ( __USE_FILE_OFFSET64 )
- {
- off_t ftello64(FILE*);
- alias ftello64 ftello;
- }
- else
- {
- off_t ftello(FILE*);
- }
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (CRuntime_Musl)
{
@@ -331,6 +340,91 @@ else version (CRuntime_Musl)
{
off_t ftello(FILE*);
}
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (CRuntime_Bionic)
+{
+ enum L_ctermid = 1024;
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ int fseeko64(FILE*, off_t, int);
+ alias fseeko64 fseeko;
+ }
+ else
+ {
+ int fseeko(FILE*, off_t, int);
+ }
+
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ off_t ftello64(FILE*);
+ alias ftello64 ftello;
+ }
+ else
+ {
+ off_t ftello(FILE*);
+ }
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (Darwin)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (FreeBSD)
+{
+ import core.sys.freebsd.config;
+
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ static if (__FreeBSD_version >= 800000)
+ {
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+ }
+}
+else version (NetBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (OpenBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
+}
+else version (DragonFlyBSD)
+{
+ enum L_ctermid = 1024;
+
+ int fseeko(FILE*, off_t, int);
+ off_t ftello(FILE*);
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (Solaris)
{
@@ -356,6 +450,9 @@ else version (Solaris)
{
off_t ftello(FILE*);
}
+
+ ssize_t getdelim(char**, size_t*, int, FILE*);
+ ssize_t getline(char**, size_t*, FILE*);
}
else version (Posix)
{
@@ -364,13 +461,11 @@ else version (Posix)
}
char* ctermid(char*);
-FILE* fdopen(int, in char*);
+FILE* fdopen(int, const scope char*);
int fileno(FILE*);
-//int fseeko(FILE*, off_t, int);
-//off_t ftello(FILE*);
char* gets(char*);
int pclose(FILE*);
-FILE* popen(in char*, in char*);
+FILE* popen(const scope char*, const scope char*);
// memstream functions are conforming to POSIX.1-2008. These functions are
@@ -392,7 +487,7 @@ else version (CRuntime_Musl)
version (HaveMemstream)
{
- FILE* fmemopen(in void* buf, in size_t size, in char* mode);
+ FILE* fmemopen(const scope void* buf, in size_t size, const scope char* mode);
FILE* open_memstream(char** ptr, size_t* sizeloc);
version (CRuntime_UClibc) {} else
FILE* open_wmemstream(wchar_t** ptr, size_t* sizeloc);
@@ -421,6 +516,46 @@ version (CRuntime_Glibc)
int putc_unlocked(int, FILE*);
int putchar_unlocked(int);
}
+else version (CRuntime_Musl)
+{
+ void flockfile(FILE*);
+ int ftrylockfile(FILE*);
+ void funlockfile(FILE*);
+ int getc_unlocked(FILE*);
+ int getchar_unlocked();
+ int putc_unlocked(int, FILE*);
+ int putchar_unlocked(int);
+}
+else version (Darwin)
+{
+ void flockfile(FILE*);
+ int ftrylockfile(FILE*);
+ void funlockfile(FILE*);
+ int getc_unlocked(FILE*);
+ int getchar_unlocked();
+ int putc_unlocked(int, FILE*);
+ int putchar_unlocked(int);
+}
+else version (FreeBSD)
+{
+ void flockfile(FILE*);
+ int ftrylockfile(FILE*);
+ void funlockfile(FILE*);
+ int getc_unlocked(FILE*);
+ int getchar_unlocked();
+ int putc_unlocked(int, FILE*);
+ int putchar_unlocked(int);
+}
+else version (NetBSD)
+{
+ void flockfile(FILE*);
+ int ftrylockfile(FILE*);
+ void funlockfile(FILE*);
+ int getc_unlocked(FILE*);
+ int getchar_unlocked();
+ int putc_unlocked(int, FILE*);
+ int putchar_unlocked(int);
+}
else version (OpenBSD)
{
void flockfile(FILE*);
@@ -431,6 +566,16 @@ else version (OpenBSD)
int putc_unlocked(int, FILE*);
int putchar_unlocked(int);
}
+else version (DragonFlyBSD)
+{
+ void flockfile(FILE*);
+ int ftrylockfile(FILE*);
+ void funlockfile(FILE*);
+ int getc_unlocked(FILE*);
+ int getchar_unlocked();
+ int putc_unlocked(int, FILE*);
+ int putchar_unlocked(int);
+}
else version (Solaris)
{
void flockfile(FILE*);
@@ -459,10 +604,10 @@ else version (CRuntime_UClibc)
P_tmpdir
va_list (defined in core.stdc.stdarg)
-char* tempnam(in char*, in char*);
+char* tempnam(const scope char*, const scope char*);
*/
-char* tempnam(in char*, in char*);
+char* tempnam(const scope char*, const scope char*);
version (CRuntime_Glibc)
{
@@ -546,7 +691,3 @@ unittest
assert(memcmp(ptr, testdata.ptr, testdata.length*wchar_t.sizeof) == 0);
assert(fclose(f) == 0);
}
-
-
-ssize_t getdelim (char** lineptr, size_t* n, int delimiter, FILE* stream);
-ssize_t getline (char** lineptr, size_t* n, FILE* stream);
diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d
index a218f95..4c10d4e 100644
--- a/libphobos/libdruntime/core/sys/posix/stdlib.d
+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.stdlib;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.stdlib;
public import core.sys.posix.sys.wait;
@@ -31,6 +31,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required (defined in core.stdc.stdlib)
@@ -51,37 +52,37 @@ void _Exit(int);
void abort();
int abs(int);
int atexit(void function());
-double atof(in char*);
-int atoi(in char*);
-c_long atol(in char*);
-long atoll(in char*);
-void* bsearch(in void*, in void*, size_t, size_t, int function(in void*, in void*));
+double atof(const scope char*);
+int atoi(const scope char*);
+c_long atol(const scope char*);
+long atoll(const scope char*);
+void* bsearch(const scope void*, const scope void*, size_t, size_t, int function(const scope void*, const scope void*));
void* calloc(size_t, size_t);
div_t div(int, int);
void exit(int);
void free(void*);
-char* getenv(in char*);
+char* getenv(const scope char*);
c_long labs(c_long);
ldiv_t ldiv(c_long, c_long);
long llabs(long);
lldiv_t lldiv(long, long);
void* malloc(size_t);
-int mblen(in char*, size_t);
-size_t mbstowcs(wchar_t*, in char*, size_t);
-int mbtowc(wchar_t*, in char*, size_t);
-void qsort(void*, size_t, size_t, int function(in void*, in void*));
+int mblen(const scope char*, size_t);
+size_t mbstowcs(wchar_t*, const scope char*, size_t);
+int mbtowc(wchar_t*, const scope char*, size_t);
+void qsort(void*, size_t, size_t, int function(const scope void*, const scope void*));
int rand();
void* realloc(void*, size_t);
void srand(uint);
-double strtod(in char*, char**);
-float strtof(in char*, char**);
-c_long strtol(in char*, char**, int);
-real strtold(in char*, char**);
-long strtoll(in char*, char**, int);
-c_ulong strtoul(in char*, char**, int);
-ulong strtoull(in char*, char**, int);
-int system(in char*);
-size_t wcstombs(char*, in wchar_t*, size_t);
+double strtod(const scope char*, char**);
+float strtof(const scope char*, char**);
+c_long strtol(const scope char*, char**, int);
+real strtold(const scope char*, char**);
+long strtoll(const scope char*, char**, int);
+c_ulong strtoul(const scope char*, char**, int);
+ulong strtoull(const scope char*, char**, int);
+int system(const scope char*);
+size_t wcstombs(char*, const scope wchar_t*, size_t);
int wctomb(char*, wchar_t);
*/
@@ -138,75 +139,75 @@ else version (CRuntime_UClibc)
// C Extension (CX)
//
/*
-int setenv(in char*, in char*, int);
-int unsetenv(in char*);
+int setenv(const scope char*, const scope char*, int);
+int unsetenv(const scope char*);
*/
version (CRuntime_Glibc)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
void* valloc(size_t); // LEGACY non-standard
}
else version (Darwin)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
void* valloc(size_t); // LEGACY non-standard
}
else version (FreeBSD)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
void* valloc(size_t); // LEGACY non-standard
}
else version (NetBSD)
{
- int setenv(in char*, in char*, int);
- int __unsetenv13(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int __unsetenv13(const scope char*);
alias __unsetenv13 unsetenv;
void* valloc(size_t); // LEGACY non-standard
}
else version (OpenBSD)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
void* valloc(size_t); // LEGACY non-standard
}
else version (DragonFlyBSD)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
void* valloc(size_t); // LEGACY non-standard
}
else version (CRuntime_Bionic)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
void* valloc(size_t);
}
else version (Solaris)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
void* valloc(size_t); // LEGACY non-standard
}
else version (CRuntime_Musl)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
}
else version (CRuntime_UClibc)
{
- int setenv(in char*, in char*, int);
- int unsetenv(in char*);
+ int setenv(const scope char*, const scope char*, int);
+ int unsetenv(const scope char*);
void* valloc(size_t);
}
@@ -263,14 +264,14 @@ WIFSTOPPED (defined in core.sys.posix.sys.wait)
WSTOPSIG (defined in core.sys.posix.sys.wait)
WTERMSIG (defined in core.sys.posix.sys.wait)
-c_long a64l(in char*);
+c_long a64l(const scope char*);
double drand48();
char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
char* fcvt(double, int, int *, int *); // LEGACY
char* gcvt(double, int, char*); // LEGACY
// per spec: int getsubopt(char** char* const*, char**);
-int getsubopt(char**, in char**, char**);
+int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -286,10 +287,10 @@ int posix_openpt(int);
char* ptsname(int);
int putenv(char*);
c_long random();
-char* realpath(in char*, char*);
+char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
-void setkey(in char*);
-char* setstate(in char*);
+void setkey(const scope char*);
+char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -306,13 +307,13 @@ version (CRuntime_Glibc)
//WSTOPSIG (defined in core.sys.posix.sys.wait)
//WTERMSIG (defined in core.sys.posix.sys.wait)
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
char* fcvt(double, int, int *, int *); // LEGACY
char* gcvt(double, int, char*); // LEGACY
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -328,10 +329,10 @@ version (CRuntime_Glibc)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
- void setkey(in char*);
- char* setstate(in char*);
+ void setkey(const scope char*);
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -357,13 +358,13 @@ else version (Darwin)
//WSTOPSIG (defined in core.sys.posix.sys.wait)
//WTERMSIG (defined in core.sys.posix.sys.wait)
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
char* fcvt(double, int, int *, int *); // LEGACY
char* gcvt(double, int, char*); // LEGACY
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -379,10 +380,10 @@ else version (Darwin)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
- void setkey(in char*);
- char* setstate(in char*);
+ void setkey(const scope char*);
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -398,13 +399,13 @@ else version (FreeBSD)
//WSTOPSIG (defined in core.sys.posix.sys.wait)
//WTERMSIG (defined in core.sys.posix.sys.wait)
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
//char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
//char* fcvt(double, int, int *, int *); // LEGACY
//char* gcvt(double, int, char*); // LEGACY
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -420,10 +421,10 @@ else version (FreeBSD)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
- void setkey(in char*);
- char* setstate(in char*);
+ void setkey(const scope char*);
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -439,13 +440,13 @@ else version (NetBSD)
//WSTOPSIG (defined in core.sys.posix.sys.wait)
//WTERMSIG (defined in core.sys.posix.sys.wait)
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
//char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
//char* fcvt(double, int, int *, int *); // LEGACY
//char* gcvt(double, int, char*); // LEGACY
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -461,10 +462,10 @@ else version (NetBSD)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
- void setkey(in char*);
- char* setstate(in char*);
+ void setkey(const scope char*);
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -480,13 +481,13 @@ else version (OpenBSD)
//WSTOPSIG (defined in core.sys.posix.sys.wait)
//WTERMSIG (defined in core.sys.posix.sys.wait)
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
//char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
//char* fcvt(double, int, int *, int *); // LEGACY
//char* gcvt(double, int, char*); // LEGACY
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -502,10 +503,10 @@ else version (OpenBSD)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
- // void setkey(in char*); // not implemented
- char* setstate(in char*);
+ // void setkey(const scope char*); // not implemented
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -521,13 +522,13 @@ else version (DragonFlyBSD)
//WSTOPSIG (defined in core.sys.posix.sys.wait)
//WTERMSIG (defined in core.sys.posix.sys.wait)
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
//char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
//char* fcvt(double, int, int *, int *); // LEGACY
//char* gcvt(double, int, char*); // LEGACY
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -543,10 +544,10 @@ else version (DragonFlyBSD)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
- void setkey(in char*);
- char* setstate(in char*);
+ void setkey(const scope char*);
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -564,9 +565,9 @@ else version (CRuntime_Bionic)
c_long mrand48();
c_long nrand48(ref ushort[3]);
char* ptsname(int);
- int putenv(in char*);
+ int putenv(const scope char*);
c_long random() { return lrand48(); }
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort* seed48(ref ushort[3]);
void srand48(c_long);
void srandom(uint s) { srand48(s); }
@@ -574,13 +575,13 @@ else version (CRuntime_Bionic)
}
else version (CRuntime_Musl)
{
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
char* fcvt(double, int, int *, int *); // LEGACY
char* gcvt(double, int, char*); // LEGACY
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -596,10 +597,10 @@ else version (CRuntime_Musl)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
- void setkey(in char*);
- char* setstate(in char*);
+ void setkey(const scope char*);
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -626,13 +627,13 @@ else version (Solaris)
//WSTOPSIG (defined in core.sys.posix.sys.wait)
//WTERMSIG (defined in core.sys.posix.sys.wait)
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
char* ecvt(double, int, int *, int *); // LEGACY
double erand48(ref ushort[3]);
char* fcvt(double, int, int *, int *); // LEGACY
char* gcvt(double, int, char*); // LEGACY
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -648,10 +649,10 @@ else version (Solaris)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort *seed48(ref ushort[3]);
- void setkey(in char*);
- char* setstate(in char*);
+ void setkey(const scope char*);
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
@@ -675,13 +676,13 @@ else version (Solaris)
}
else version (CRuntime_UClibc)
{
- c_long a64l(in char*);
+ c_long a64l(const scope char*);
double drand48();
char* ecvt(double, int, int *, int *);
double erand48(ref ushort[3]);
char* fcvt(double, int, int *, int *);
char* gcvt(double, int, char*);
- int getsubopt(char**, in char**, char**);
+ int getsubopt(char**, const scope char**, char**);
int grantpt(int);
char* initstate(uint, char*, size_t);
c_long jrand48(ref ushort[3]);
@@ -696,10 +697,10 @@ else version (CRuntime_UClibc)
char* ptsname(int);
int putenv(char*);
c_long random();
- char* realpath(in char*, char*);
+ char* realpath(const scope char*, char*);
ushort* seed48(ref ushort[3]);
- void setkey(in char*);
- char* setstate(in char*);
+ void setkey(const scope char*);
+ char* setstate(const scope char*);
void srand48(c_long);
void srandom(uint);
int unlockpt(int);
diff --git a/libphobos/libdruntime/core/sys/posix/string.d b/libphobos/libdruntime/core/sys/posix/string.d
new file mode 100644
index 0000000..e17dfc6
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/posix/string.d
@@ -0,0 +1,52 @@
+/**
+ * D header file for POSIX's <string.h>.
+ *
+ * Note:
+ * - The <string.h> header shall define NULL and size_t as described in <stddef.h>.
+ * However, D has builtin `null` and `size_t` is defined in `object`.
+ *
+ * See_Also: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/string.h.html
+ * Copyright: D Language Foundation, 2019
+ * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Authors: Mathias 'Geod24' Lang
+ * Standards: The Open Group Base Specifications Issue 7, 2018 edition
+ * Source: $(DRUNTIMESRC core/sys/posix/_string.d)
+ */
+module core.sys.posix.string;
+
+version (Posix):
+extern(C):
+@system:
+nothrow:
+@nogc:
+
+/// Exposes `locale_t` as defined in `core.sys.posix.locale` (`<locale.h>`)
+public import core.sys.posix.locale : locale_t;
+
+/**
+ * Exposes the C99 functions
+ *
+ * C extensions and XSI extensions are missing
+ */
+public import core.stdc.string;
+
+/// Copy string until character found
+void* memccpy(return void* dst, scope const void* src, int c, size_t n);
+/// Copy string (including terminating '\0')
+char* stpcpy(return char* dst, scope const char* src);
+/// Ditto
+char* stpncpy(return char* dst, const char* src, size_t len);
+/// Compare strings according to current collation
+int strcoll_l(scope const char* s1, scope const char* s2, locale_t locale);
+///
+char* strerror_l(int, locale_t);
+/// Save a copy of a string
+char* strndup(scope const char* str, size_t len);
+/// Find length of string up to `maxlen`
+size_t strnlen(scope const char* str, size_t maxlen);
+/// System signal messages
+const(char)* strsignal(int);
+/// Isolate sequential tokens in a null-terminated string
+char* strtok_r(return char* str, scope const char* sep, char** context) pure;
+/// Transform a string under locale
+size_t strxfrm_l(char* s1, scope const char* s2, size_t n, locale_t locale);
diff --git a/libphobos/libdruntime/core/sys/posix/strings.d b/libphobos/libdruntime/core/sys/posix/strings.d
new file mode 100644
index 0000000..96fbccc
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/posix/strings.d
@@ -0,0 +1,34 @@
+/**
+ * D header file for POSIX's <strings.h>.
+ *
+ * Note: Do not mistake this module for <string.h> (singular),
+ * available at `core.sys.posix.string`.
+ *
+ * See_Also: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/strings.h.html
+ * Copyright: D Language Foundation, 2019
+ * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Authors: Mathias 'Geod24' Lang
+ * Standards: The Open Group Base Specifications Issue 7, 2018 edition
+ * Source: $(DRUNTIMESRC core/sys/posix/_strings.d)
+ */
+module core.sys.posix.strings;
+
+version (Posix):
+extern(C):
+@system:
+nothrow:
+@nogc:
+
+///
+public import core.sys.posix.locale : locale_t;
+
+/// Find first bit set in a word
+int ffs(int i) @safe pure;
+/// Compare two strings ignoring case
+int strcasecmp(scope const char* s1, scope const char* s2);
+/// Compare two strings ignoring case, with the specified locale
+int strcasecmp_l(scope const char* s1, scope const char* s2, scope locale_t locale);
+/// Compare two strings ignoring case, up to n characters
+int strncasecmp(scope const char* s1, scope const char* s2, size_t n);
+/// Compare two strings ignoring case, with the specified locale, up to n characters
+int strncasecmp_l(scope const char* s1, const char* s2, size_t n, locale_t locale);
diff --git a/libphobos/libdruntime/core/sys/posix/sys/filio.d b/libphobos/libdruntime/core/sys/posix/sys/filio.d
index 3574bc6..afb6f82 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/filio.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/filio.d
@@ -20,6 +20,7 @@ else version (WatchOS)
version (Posix):
nothrow @nogc:
+@system:
version (Darwin)
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/ioccom.d b/libphobos/libdruntime/core/sys/posix/sys/ioccom.d
index 51f1d22..4c1a820 100644..100755
--- a/libphobos/libdruntime/core/sys/posix/sys/ioccom.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/ioccom.d
@@ -18,6 +18,7 @@ else version (WatchOS)
version (Posix):
nothrow @nogc:
+@system:
version (Darwin)
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/ioctl.d b/libphobos/libdruntime/core/sys/posix/sys/ioctl.d
index 7c77e80..0266200 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/ioctl.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/ioctl.d
@@ -29,6 +29,7 @@ else version (WatchOS)
version (Posix):
extern (C) nothrow @nogc:
+@system:
version (CRuntime_Glibc)
{
@@ -213,7 +214,7 @@ version (CRuntime_Glibc)
enum TIOCGSID = 0x5429;
enum TCGETS2 = _IOR!termios2('T', 0x2A);
- enum TCSETS2 = _IOR!termios2('T', 0x2B);
+ enum TCSETS2 = _IOW!termios2('T', 0x2B);
enum TCSETSW2 = _IOW!termios2('T', 0x2C);
enum TCSETSF2 = _IOW!termios2('T', 0x2D);
@@ -624,7 +625,7 @@ else version (CRuntime_UClibc)
enum TIOCGSID = 0x5429;
enum TCGETS2 = _IOR!termios2('T', 0x2A);
- enum TCSETS2 = _IOR!termios2('T', 0x2B);
+ enum TCSETS2 = _IOW!termios2('T', 0x2B);
enum TCSETSW2 = _IOW!termios2('T', 0x2C);
enum TCSETSF2 = _IOW!termios2('T', 0x2D);
diff --git a/libphobos/libdruntime/core/sys/posix/sys/ipc.d b/libphobos/libdruntime/core/sys/posix/sys/ipc.d
index 04601f2..d397a28 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/ipc.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/ipc.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.sys.ipc;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for uid_t, gid_t, mode_t, key_t
version (OSX)
@@ -28,6 +28,7 @@ else version (WatchOS)
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// XOpen (XSI)
@@ -52,7 +53,7 @@ IPC_RMID
IPC_SET
IPC_STAT
-key_t ftok(in char*, int);
+key_t ftok(const scope char*, int);
*/
version (CRuntime_Glibc)
@@ -82,7 +83,7 @@ version (CRuntime_Glibc)
enum IPC_SET = 1;
enum IPC_STAT = 2;
- key_t ftok(in char*, int);
+ key_t ftok(const scope char*, int);
}
else version (Darwin)
{
@@ -122,7 +123,7 @@ else version (FreeBSD)
enum IPC_SET = 1;
enum IPC_STAT = 2;
- key_t ftok(in char*, int);
+ key_t ftok(const scope char*, int);
}
else version (NetBSD)
{
@@ -147,7 +148,7 @@ else version (NetBSD)
enum IPC_SET = 1;
enum IPC_STAT = 2;
- key_t ftok(in char*, int);
+ key_t ftok(const scope char*, int);
}
else version (OpenBSD)
{
@@ -172,7 +173,7 @@ else version (OpenBSD)
enum IPC_SET = 1;
enum IPC_STAT = 2;
- key_t ftok(in char*, int);
+ key_t ftok(const scope char*, int);
}
else version (DragonFlyBSD)
{
@@ -197,7 +198,7 @@ else version (DragonFlyBSD)
enum IPC_SET = 1;
enum IPC_STAT = 2;
- key_t ftok(in char*, int);
+ key_t ftok(const scope char*, int);
}
else version (CRuntime_Bionic)
{
@@ -240,7 +241,7 @@ else version (CRuntime_Bionic)
enum IPC_SET = 1;
enum IPC_STAT = 2;
- key_t ftok(in char*, int);
+ key_t ftok(const scope char*, int);
}
else version (CRuntime_UClibc)
{
@@ -270,5 +271,5 @@ else version (CRuntime_UClibc)
enum IPC_STAT = 2;
enum IPC_INFO = 3;
- key_t ftok(in char*, int);
+ key_t ftok(const scope char*, int);
}
diff --git a/libphobos/libdruntime/core/sys/posix/sys/mman.d b/libphobos/libdruntime/core/sys/posix/sys/mman.d
index f682320..a74a213 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/mman.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/mman.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.sys.mman;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for off_t, mode_t
version (OSX)
@@ -45,6 +45,7 @@ version (X86_64) version = X86_Any;
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// Advisory Information (ADV)
@@ -511,7 +512,7 @@ else version (CRuntime_Bionic)
enum MS_ASYNC = 1;
enum MS_INVALIDATE = 2;
- int msync(in void*, size_t, int);
+ int msync(const scope void*, size_t, int);
}
else version (CRuntime_Musl)
{
@@ -694,59 +695,59 @@ else
// Range Memory Locking (MLR)
//
/*
-int mlock(in void*, size_t);
-int munlock(in void*, size_t);
+int mlock(const scope void*, size_t);
+int munlock(const scope void*, size_t);
*/
version (CRuntime_Glibc)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (Darwin)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (FreeBSD)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (NetBSD)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (OpenBSD)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (DragonFlyBSD)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (Solaris)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (CRuntime_Bionic)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (CRuntime_Musl)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else version (CRuntime_UClibc)
{
- int mlock(in void*, size_t);
- int munlock(in void*, size_t);
+ int mlock(const scope void*, size_t);
+ int munlock(const scope void*, size_t);
}
else
{
@@ -790,7 +791,7 @@ else version (Solaris)
}
else version (CRuntime_Bionic)
{
- int mprotect(in void*, size_t, int);
+ int mprotect(const scope void*, size_t, int);
}
else version (CRuntime_Musl)
{
@@ -809,57 +810,57 @@ else
// Shared Memory Objects (SHM)
//
/*
-int shm_open(in char*, int, mode_t);
-int shm_unlink(in char*);
+int shm_open(const scope char*, int, mode_t);
+int shm_unlink(const scope char*);
*/
version (CRuntime_Glibc)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else version (Darwin)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else version (FreeBSD)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else version (NetBSD)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else version (OpenBSD)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else version (DragonFlyBSD)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else version (Solaris)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else version (CRuntime_Bionic)
{
}
else version (CRuntime_Musl)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else version (CRuntime_UClibc)
{
- int shm_open(in char*, int, mode_t);
- int shm_unlink(in char*);
+ int shm_open(const scope char*, int, mode_t);
+ int shm_unlink(const scope char*);
}
else
{
@@ -879,7 +880,7 @@ struct posix_typed_mem_info
size_t posix_tmi_length;
}
-int posix_mem_offset(in void*, size_t, off_t *, size_t *, int *);
+int posix_mem_offset(const scope void*, size_t, off_t *, size_t *, int *);
int posix_typed_mem_get_info(int, struct posix_typed_mem_info *);
-int posix_typed_mem_open(in char*, int, int);
+int posix_typed_mem_open(const scope char*, int, int);
*/
diff --git a/libphobos/libdruntime/core/sys/posix/sys/msg.d b/libphobos/libdruntime/core/sys/posix/sys/msg.d
index 208e5c2..4760f2e 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/msg.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/msg.d
@@ -14,6 +14,7 @@ import core.stdc.config;
version (CRuntime_Glibc):
// Some of these may be from linux kernel headers.
extern (C):
+@system:
version (ARM) version = ARM_Any;
version (AArch64) version = ARM_Any;
diff --git a/libphobos/libdruntime/core/sys/posix/sys/resource.d b/libphobos/libdruntime/core/sys/posix/sys/resource.d
index 56a8fd4..c5d584c 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/resource.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/resource.d
@@ -23,6 +23,7 @@ else version (WatchOS)
version = Darwin;
nothrow @nogc extern(C):
+@system:
//
// XOpen (XSI)
@@ -528,7 +529,7 @@ else version (CRuntime_Musl)
enum RLIM_INFINITY = cast(c_ulong)(~0UL);
int getrlimit(int, rlimit*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
alias getrlimit getrlimit64;
alias setrlimit setrlimit64;
enum
@@ -677,14 +678,14 @@ version (CRuntime_Glibc)
static if (__USE_FILE_OFFSET64)
{
int getrlimit64(int, rlimit*);
- int setrlimit64(int, in rlimit*);
+ int setrlimit64(int, const scope rlimit*);
alias getrlimit = getrlimit64;
alias setrlimit = setrlimit64;
}
else
{
int getrlimit(int, rlimit*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
int getrusage(int, rusage*);
}
@@ -692,57 +693,57 @@ else version (CRuntime_Bionic)
{
int getrlimit(int, rlimit*);
int getrusage(int, rusage*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
else version (Darwin)
{
int getrlimit(int, rlimit*);
int getrusage(int, rusage*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
else version (FreeBSD)
{
int getrlimit(int, rlimit*);
int getrusage(int, rusage*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
else version (NetBSD)
{
int getrlimit(int, rlimit*);
int getrusage(int, rusage*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
else version (OpenBSD)
{
int getrlimit(int, rlimit*);
int getrusage(int, rusage*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
else version (DragonFlyBSD)
{
int getrlimit(int, rlimit*);
int getrusage(int, rusage*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
else version (Solaris)
{
int getrlimit(int, rlimit*);
int getrusage(int, rusage*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
else version (CRuntime_UClibc)
{
static if (__USE_FILE_OFFSET64)
{
int getrlimit64(int, rlimit*);
- int setrlimit64(int, in rlimit*);
+ int setrlimit64(int, const scope rlimit*);
alias getrlimit = getrlimit64;
alias setrlimit = setrlimit64;
}
else
{
int getrlimit(int, rlimit*);
- int setrlimit(int, in rlimit*);
+ int setrlimit(int, const scope rlimit*);
}
int getrusage(int, rusage*);
}
diff --git a/libphobos/libdruntime/core/sys/posix/sys/select.d b/libphobos/libdruntime/core/sys/posix/sys/select.d
index 83e4758..2a659c3 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/select.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/select.d
@@ -8,7 +8,7 @@
*/
module core.sys.posix.sys.select;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.time; // for timespec
public import core.sys.posix.sys.time; // for timeval
public import core.sys.posix.sys.types; // for time_t
@@ -27,6 +27,7 @@ else version (WatchOS)
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// Required
@@ -46,7 +47,7 @@ void FD_ZERO(fd_set* fdset);
FD_SETSIZE
-int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
*/
@@ -130,7 +131,7 @@ version (CRuntime_Glibc)
__result; }))
+/
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else version (Darwin)
@@ -168,7 +169,7 @@ else version (Darwin)
fdset.fds_bits[0 .. $] = 0;
}
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else version (FreeBSD)
@@ -217,7 +218,7 @@ else version (FreeBSD)
_p.__fds_bits[--_n] = 0;
}
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else version (NetBSD)
@@ -266,7 +267,7 @@ else version (NetBSD)
_p.__fds_bits[--_n] = 0;
}
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else version (OpenBSD)
@@ -313,7 +314,7 @@ else version (OpenBSD)
_p.__fds_bits[--_n] = 0;
}
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else version (DragonFlyBSD)
@@ -362,7 +363,7 @@ else version (DragonFlyBSD)
_p.__fds_bits[--_n] = 0;
}
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else version (Solaris)
@@ -406,7 +407,7 @@ else version (Solaris)
}
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
}
else version (CRuntime_Bionic)
{
@@ -454,7 +455,7 @@ else version (CRuntime_Bionic)
fdset.fds_bits[0 .. $] = 0;
}
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else version (CRuntime_Musl)
@@ -501,7 +502,7 @@ else version (CRuntime_Musl)
{
fdset.fds_bits[0 .. $] = 0;
}
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else version (CRuntime_UClibc)
@@ -549,7 +550,7 @@ else version (CRuntime_UClibc)
fdset.fds_bits[0 .. $] = 0;
}
- int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);
+ int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*);
}
else
diff --git a/libphobos/libdruntime/core/sys/posix/sys/shm.d b/libphobos/libdruntime/core/sys/posix/sys/shm.d
index 8902451..2e85096 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/shm.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/shm.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.sys.shm;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for pid_t, time_t, key_t
public import core.sys.posix.sys.ipc;
@@ -29,6 +29,7 @@ else version (WatchOS)
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// XOpen (XSI)
@@ -53,9 +54,9 @@ struct shmid_ds
time_t shm_ctime;
}
-void* shmat(int, in void*, int);
+void* shmat(int, const scope void*, int);
int shmctl(int, int, shmid_ds*);
-int shmdt(in void*);
+int shmdt(const scope void*);
int shmget(key_t, size_t, int);
*/
@@ -87,9 +88,9 @@ version (CRuntime_Glibc)
c_ulong __unused5;
}
- void* shmat(int, in void*, int);
+ void* shmat(int, const scope void*, int);
int shmctl(int, int, shmid_ds*);
- int shmdt(in void*);
+ int shmdt(const scope void*);
int shmget(key_t, size_t, int);
}
else version (FreeBSD)
@@ -125,9 +126,9 @@ else version (FreeBSD)
time_t shm_ctime;
}
- void* shmat(int, in void*, int);
+ void* shmat(int, const scope void*, int);
int shmctl(int, int, shmid_ds*);
- int shmdt(in void*);
+ int shmdt(const scope void*);
int shmget(key_t, size_t, int);
}
else version (NetBSD)
@@ -151,9 +152,9 @@ else version (NetBSD)
void* shm_internal;
}
- void* shmat(int, in void*, int);
+ void* shmat(int, const scope void*, int);
int shmctl(int, int, shmid_ds*);
- int shmdt(in void*);
+ int shmdt(const scope void*);
int shmget(key_t, size_t, int);
}
else version (OpenBSD)
@@ -180,9 +181,9 @@ else version (OpenBSD)
void* shm_internal;
}
- void* shmat(int, in void*, int);
+ void* shmat(int, const scope void*, int);
int shmctl(int, int, shmid_ds*);
- int shmdt(in void*);
+ int shmdt(const scope void*);
int shmget(key_t, size_t, int);
}
else version (DragonFlyBSD)
@@ -206,9 +207,9 @@ else version (DragonFlyBSD)
private void* shm_internal;
}
- void* shmat(int, in void*, int);
+ void* shmat(int, const scope void*, int);
int shmctl(int, int, shmid_ds*);
- int shmdt(in void*);
+ int shmdt(const scope void*);
int shmget(key_t, size_t, int);
}
else version (Darwin)
@@ -273,8 +274,8 @@ else version (CRuntime_UClibc)
c_ulong swap_successes;
}
- void* shmat(int, in void*, int);
+ void* shmat(int, const scope void*, int);
int shmctl(int, int, shmid_ds*);
- int shmdt(in void*);
+ int shmdt(const scope void*);
int shmget(key_t, size_t, int);
}
diff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d
index 05f52fc..430d0c0 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/socket.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.sys.socket;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for ssize_t
public import core.sys.posix.sys.uio; // for iovec
@@ -45,6 +45,7 @@ version (X86_64) version = X86_Any;
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// Required
@@ -138,8 +139,8 @@ SHUT_RDWR
SHUT_WR
int accept(int, sockaddr*, socklen_t*);
-int bind(int, in sockaddr*, socklen_t);
-int connect(int, in sockaddr*, socklen_t);
+int bind(int, const scope sockaddr*, socklen_t);
+int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, sockaddr*, socklen_t*);
int getsockname(int, sockaddr*, socklen_t*);
int getsockopt(int, int, int, void*, socklen_t*);
@@ -147,10 +148,10 @@ int listen(int, int);
ssize_t recv(int, void*, size_t, int);
ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
ssize_t recvmsg(int, msghdr*, int);
-ssize_t send(int, in void*, size_t, int);
-ssize_t sendmsg(int, in msghdr*, int);
-ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
-int setsockopt(int, int, int, in void*, socklen_t);
+ssize_t send(int, const scope void*, size_t, int);
+ssize_t sendmsg(int, const scope msghdr*, int);
+ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int);
int socket(int, int, int);
int sockatmark(int);
@@ -216,7 +217,7 @@ version (CRuntime_Glibc)
}
else
{
- extern (D) inout(ubyte)* CMSG_DATA( inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
+ extern (D) inout(ubyte)* CMSG_DATA( return inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
}
private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;
@@ -571,8 +572,8 @@ version (CRuntime_Glibc)
}
int accept(int, scope sockaddr*, scope socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, scope sockaddr*, scope socklen_t*);
int getsockname(int, scope sockaddr*, scope socklen_t*);
int getsockopt(int, int, int, scope void*, scope socklen_t*);
@@ -580,10 +581,10 @@ version (CRuntime_Glibc)
ssize_t recv(int, scope void*, size_t, int);
ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
ssize_t recvmsg(int, scope msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int) @safe;
int socket(int, int, int) @safe;
int sockatmark(int) @safe;
@@ -727,8 +728,8 @@ else version (Darwin)
}
int accept(int, scope sockaddr*, scope socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, scope sockaddr*, scope socklen_t*);
int getsockname(int, scope sockaddr*, scope socklen_t*);
int getsockopt(int, int, int, scope void*, scope socklen_t*);
@@ -736,10 +737,10 @@ else version (Darwin)
ssize_t recv(int, scope void*, size_t, int);
ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
ssize_t recvmsg(int, scope msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int) @safe;
int socket(int, int, int) @safe;
int sockatmark(int) @safe;
@@ -904,8 +905,8 @@ else version (FreeBSD)
}
int accept(int, scope sockaddr*, scope socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, scope sockaddr*, scope socklen_t*);
int getsockname(int, scope sockaddr*, scope socklen_t*);
int getsockopt(int, int, int, scope void*, scope socklen_t*);
@@ -913,10 +914,10 @@ else version (FreeBSD)
ssize_t recv(int, scope void*, size_t, int);
ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
ssize_t recvmsg(int, scope msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int) @safe;
int socket(int, int, int) @safe;
int sockatmark(int) @safe;
@@ -1101,8 +1102,8 @@ else version (NetBSD)
}
int accept(int, scope sockaddr*, scope socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, scope sockaddr*, scope socklen_t*);
int getsockname(int, scope sockaddr*, scope socklen_t*);
int getsockopt(int, int, int, scope void*, scope socklen_t*);
@@ -1110,10 +1111,10 @@ else version (NetBSD)
ssize_t recv(int, scope void*, size_t, int);
ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
ssize_t recvmsg(int, scope msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int) @safe;
int socket(int, int, int) @safe;
int sockatmark(int) @safe;
@@ -1274,8 +1275,8 @@ else version (OpenBSD)
}
int accept(int, scope sockaddr*, scope socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, scope sockaddr*, scope socklen_t*);
int getsockname(int, scope sockaddr*, scope socklen_t*);
int getsockopt(int, int, int, scope void*, scope socklen_t*);
@@ -1283,10 +1284,10 @@ else version (OpenBSD)
ssize_t recv(int, scope void*, size_t, int);
ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
ssize_t recvmsg(int, scope msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int) @safe;
int socket(int, int, int) @safe;
int sockatmark(int) @safe;
@@ -1446,7 +1447,7 @@ else version (DragonFlyBSD)
gid_t cmcred_gid;
short cmcred_ngroups;
gid_t[CMGROUP_MAX] cmcred_groups;
- };
+ }
enum : uint
{
@@ -1499,13 +1500,13 @@ else version (DragonFlyBSD)
int hdr_cnt;
iovec * trailers;
int trl_cnt;
- };
+ }
*/
int accept(int, sockaddr*, socklen_t*);
// int accept4(int, sockaddr*, socklen_t*, int);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
// int extconnect(int, int, sockaddr*, socklen_t);
int getpeername(int, sockaddr*, socklen_t*);
int getsockname(int, sockaddr*, socklen_t*);
@@ -1514,11 +1515,11 @@ else version (DragonFlyBSD)
ssize_t recv(int, void*, size_t, int);
ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
ssize_t recvmsg(int, msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- ssize_t sendmsg(int, in msghdr*, int);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ ssize_t sendmsg(int, const scope msghdr*, int);
// int sendfile(int, int, off_t, size_t, sf_hdtr *, off_t *, int);
- int setsockopt(int, int, int, in void*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int);
int sockatmark(int);
int socket(int, int, int);
@@ -1655,8 +1656,8 @@ else version (Solaris)
}
int accept(int, scope sockaddr*, scope socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, scope sockaddr*, scope socklen_t*);
int getsockname(int, scope sockaddr*, scope socklen_t*);
int getsockopt(int, int, int, scope void*, scope socklen_t*);
@@ -1664,10 +1665,10 @@ else version (Solaris)
ssize_t recv(int, scope void*, size_t, int);
ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
ssize_t recvmsg(int, scope msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int) @safe;
int socket(int, int, int) @safe;
int sockatmark(int) @safe;
@@ -1816,8 +1817,8 @@ else version (CRuntime_Bionic)
enum SOCK_RDM = 4;
int accept(int, scope sockaddr*, scope socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, scope sockaddr*, scope socklen_t*);
int getsockname(int, scope sockaddr*, scope socklen_t*);
int getsockopt(int, int, int, scope void*, scope socklen_t*);
@@ -1825,10 +1826,10 @@ else version (CRuntime_Bionic)
ssize_t recv(int, scope void*, size_t, int);
ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
int recvmsg(int, scope msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- int sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ int sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int) @safe;
int socket(int, int, int) @safe;
int sockatmark(int) @safe;
@@ -1970,8 +1971,8 @@ else version (CRuntime_Musl)
int msg_flags;
}
int accept(int, sockaddr*, socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, sockaddr*, socklen_t*);
int getsockname(int, sockaddr*, socklen_t*);
int getsockopt(int, int, int, void*, socklen_t*);
@@ -1979,10 +1980,10 @@ else version (CRuntime_Musl)
ssize_t recv(int, void*, size_t, int);
ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
ssize_t recvmsg(int, msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int);
int socket(int, int, int);
int sockatmark(int);
@@ -2167,8 +2168,8 @@ else version (CRuntime_UClibc)
}
int accept(int, sockaddr*, socklen_t*);
- int bind(int, in sockaddr*, socklen_t);
- int connect(int, in sockaddr*, socklen_t);
+ int bind(int, const scope sockaddr*, socklen_t);
+ int connect(int, const scope sockaddr*, socklen_t);
int getpeername(int, sockaddr*, socklen_t*);
int getsockname(int, sockaddr*, socklen_t*);
int getsockopt(int, int, int, void*, socklen_t*);
@@ -2176,10 +2177,10 @@ else version (CRuntime_UClibc)
ssize_t recv(int, void*, size_t, int);
ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
ssize_t recvmsg(int, msghdr*, int);
- ssize_t send(int, in void*, size_t, int);
- ssize_t sendmsg(int, in msghdr*, int);
- ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
- int setsockopt(int, int, int, in void*, socklen_t);
+ ssize_t send(int, const scope void*, size_t, int);
+ ssize_t sendmsg(int, const scope msghdr*, int);
+ ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
+ int setsockopt(int, int, int, const scope void*, socklen_t);
int shutdown(int, int);
int socket(int, int, int);
int sockatmark(int);
diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d
index 35b1f1c..6b4d022 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/stat.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d
@@ -14,9 +14,9 @@
*/
module core.sys.posix.sys.stat;
-private import core.sys.posix.config;
-private import core.stdc.stdint;
-private import core.sys.posix.time; // for timespec
+import core.sys.posix.config;
+import core.stdc.stdint;
+import core.sys.posix.time; // for timespec
public import core.sys.posix.sys.types; // for off_t, mode_t
version (OSX)
@@ -30,9 +30,12 @@ else version (WatchOS)
version (RISCV32) version = RISCV_Any;
version (RISCV64) version = RISCV_Any;
+version (SPARC) version = SPARC_Any;
+version (SPARC64) version = SPARC_Any;
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// Required
@@ -80,13 +83,13 @@ S_TYPEISMQ(buf)
S_TYPEISSEM(buf)
S_TYPEISSHM(buf)
-int chmod(in char*, mode_t);
+int chmod(const scope char*, mode_t);
int fchmod(int, mode_t);
int fstat(int, stat*);
-int lstat(in char*, stat*);
-int mkdir(in char*, mode_t);
-int mkfifo(in char*, mode_t);
-int stat(in char*, stat*);
+int lstat(const scope char*, stat*);
+int mkdir(const scope char*, mode_t);
+int mkfifo(const scope char*, mode_t);
+int stat(const scope char*, stat*);
mode_t umask(mode_t);
*/
@@ -120,11 +123,11 @@ version (CRuntime_Glibc)
timespec st_atim;
timespec st_mtim;
timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -167,11 +170,11 @@ version (CRuntime_Glibc)
timespec st_atim;
timespec st_mtim;
timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -249,11 +252,11 @@ version (CRuntime_Glibc)
__timespec st_atim;
__timespec st_mtim;
__timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -309,11 +312,11 @@ version (CRuntime_Glibc)
timespec st_atim;
timespec st_mtim;
timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -373,11 +376,11 @@ version (CRuntime_Glibc)
timespec st_atim;
timespec st_mtim;
timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -514,11 +517,11 @@ version (CRuntime_Glibc)
__timespec st_atim;
__timespec st_mtim;
__timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -596,11 +599,11 @@ version (CRuntime_Glibc)
__timespec st_atim;
__timespec st_mtim;
__timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -691,11 +694,11 @@ version (CRuntime_Glibc)
__timespec st_atim;
__timespec st_mtim;
__timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -714,7 +717,7 @@ version (CRuntime_Glibc)
else
static assert(stat_t.sizeof == 104);
}
- else version (SPARC64)
+ else version (SPARC_Any)
{
private
{
@@ -736,8 +739,15 @@ version (CRuntime_Glibc)
struct stat_t
{
__dev_t st_dev;
- ushort __pad1;
- __ino_t st_ino;
+ static if (__WORDSIZE == 64 || !__USE_FILE_OFFSET64)
+ {
+ ushort __pad1;
+ __ino_t st_ino;
+ }
+ else
+ {
+ __ino64_t st_ino;
+ }
__mode_t st_mode;
__nlink_t st_nlink;
__uid_t st_uid;
@@ -769,11 +779,11 @@ version (CRuntime_Glibc)
__timespec st_atim;
__timespec st_mtim;
__timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -789,7 +799,15 @@ version (CRuntime_Glibc)
c_ulong __unused4;
c_ulong __unused5;
}
- static assert(stat_t.sizeof == 144);
+ static if (__USE_LARGEFILE64) alias stat_t stat64_t;
+
+ static if (__WORDSIZE == 64)
+ static assert(stat_t.sizeof == 144);
+ else static if (__USE_FILE_OFFSET64)
+ static assert(stat_t.sizeof == 104);
+ else
+ static assert(stat_t.sizeof == 88);
+
}
else version (S390)
{
@@ -838,11 +856,11 @@ version (CRuntime_Glibc)
__timespec st_atim;
__timespec st_mtim;
__timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -902,11 +920,11 @@ version (CRuntime_Glibc)
__timespec st_atim;
__timespec st_mtim;
__timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -1264,11 +1282,11 @@ else version (OpenBSD)
timespec st_atim;
timespec st_mtim;
timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -1348,7 +1366,7 @@ else version (DragonFlyBSD)
int32_t st_lspare;
int64_t st_qspare1; /* was recursive change detect */
int64_t st_qspare2;
- };
+ }
enum S_IRUSR = 0x100; // octal 0000400
enum S_IWUSR = 0x080; // octal 0000200
@@ -2001,11 +2019,11 @@ else version (CRuntime_UClibc)
timespec st_atim;
timespec st_mtim;
timespec st_ctim;
- extern(D)
+ extern(D) @safe @property inout pure nothrow
{
- @property ref time_t st_atime() { return st_atim.tv_sec; }
- @property ref time_t st_mtime() { return st_mtim.tv_sec; }
- @property ref time_t st_ctime() { return st_ctim.tv_sec; }
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
}
}
else
@@ -2167,13 +2185,13 @@ else
static assert(false, "Unsupported platform");
}
-int chmod(in char*, mode_t);
+int chmod(const scope char*, mode_t);
int fchmod(int, mode_t);
//int fstat(int, stat_t*);
-//int lstat(in char*, stat_t*);
-int mkdir(in char*, mode_t);
-int mkfifo(in char*, mode_t);
-//int stat(in char*, stat_t*);
+//int lstat(const scope char*, stat_t*);
+int mkdir(const scope char*, mode_t);
+int mkfifo(const scope char*, mode_t);
+//int stat(const scope char*, stat_t*);
mode_t umask(mode_t);
version (CRuntime_Glibc)
@@ -2183,17 +2201,17 @@ version (CRuntime_Glibc)
int fstat64(int, stat_t*) @trusted;
alias fstat64 fstat;
- int lstat64(in char*, stat_t*);
+ int lstat64(const scope char*, stat_t*);
alias lstat64 lstat;
- int stat64(in char*, stat_t*);
+ int stat64(const scope char*, stat_t*);
alias stat64 stat;
}
else
{
int fstat(int, stat_t*) @trusted;
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
}
}
else version (Solaris)
@@ -2201,8 +2219,8 @@ else version (Solaris)
version (D_LP64)
{
int fstat(int, stat_t*) @trusted;
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
static if (__USE_LARGEFILE64)
{
@@ -2218,17 +2236,17 @@ else version (Solaris)
int fstat64(int, stat_t*) @trusted;
alias fstat64 fstat;
- int lstat64(in char*, stat_t*);
+ int lstat64(const scope char*, stat_t*);
alias lstat64 lstat;
- int stat64(in char*, stat_t*);
+ int stat64(const scope char*, stat_t*);
alias stat64 stat;
}
else
{
int fstat(int, stat_t*) @trusted;
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
}
}
}
@@ -2238,28 +2256,55 @@ else version (Darwin)
// inode functions by appending $INODE64 to newer 64-bit inode functions.
version (OSX)
{
- pragma(mangle, "fstat$INODE64") int fstat(int, stat_t*);
- pragma(mangle, "lstat$INODE64") int lstat(in char*, stat_t*);
- pragma(mangle, "stat$INODE64") int stat(in char*, stat_t*);
+ version (AArch64)
+ {
+ int fstat(int, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
+ }
+ else
+ {
+ pragma(mangle, "fstat$INODE64") int fstat(int, stat_t*);
+ pragma(mangle, "lstat$INODE64") int lstat(const scope char*, stat_t*);
+ pragma(mangle, "stat$INODE64") int stat(const scope char*, stat_t*);
+ }
}
else
{
int fstat(int, stat_t*);
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
}
}
else version (FreeBSD)
{
- int fstat(int, stat_t*);
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ version (GNU)
+ {
+ int fstat(int, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
+ }
+ else
+ {
+ static if (__FreeBSD_version >= INO64_FIRST)
+ {
+ pragma(mangle, "fstat@FBSD_1.5") int fstat(int, stat_t*);
+ pragma(mangle, "lstat@FBSD_1.5") int lstat(const scope char*, stat_t*);
+ pragma(mangle, "stat@FBSD_1.5") int stat(const scope char*, stat_t*);
+ }
+ else
+ {
+ pragma(mangle, "fstat@FBSD_1.0") int fstat(int, stat_t*);
+ pragma(mangle, "lstat@FBSD_1.0") int lstat(const scope char*, stat_t*);
+ pragma(mangle, "stat@FBSD_1.0") int stat(const scope char*, stat_t*);
+ }
+ }
}
else version (NetBSD)
{
int __fstat50(int, stat_t*);
- int __lstat50(in char*, stat_t*);
- int __stat50(in char*, stat_t*);
+ int __lstat50(const scope char*, stat_t*);
+ int __stat50(const scope char*, stat_t*);
alias __fstat50 fstat;
alias __lstat50 lstat;
alias __stat50 stat;
@@ -2267,26 +2312,26 @@ else version (NetBSD)
else version (OpenBSD)
{
int fstat(int, stat_t*);
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
}
else version (DragonFlyBSD)
{
int fstat(int, stat_t*);
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
}
else version (CRuntime_Bionic)
{
int fstat(int, stat_t*) @trusted;
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
}
else version (CRuntime_Musl)
{
- int stat(in char*, stat_t*);
+ int stat(const scope char*, stat_t*);
int fstat(int, stat_t*);
- int lstat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
alias fstat fstat64;
alias lstat lstat64;
@@ -2299,17 +2344,17 @@ else version (CRuntime_UClibc)
int fstat64(int, stat_t*) @trusted;
alias fstat64 fstat;
- int lstat64(in char*, stat_t*);
+ int lstat64(const scope char*, stat_t*);
alias lstat64 lstat;
- int stat64(in char*, stat_t*);
+ int stat64(const scope char*, stat_t*);
alias stat64 stat;
}
else
{
int fstat(int, stat_t*) @trusted;
- int lstat(in char*, stat_t*);
- int stat(in char*, stat_t*);
+ int lstat(const scope char*, stat_t*);
+ int stat(const scope char*, stat_t*);
}
}
@@ -2347,7 +2392,7 @@ version (CRuntime_Glibc)
enum S_IFLNK = 0xA000; // octal 0120000
enum S_IFSOCK = 0xC000; // octal 0140000
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else version (Darwin)
{
@@ -2360,7 +2405,7 @@ else version (Darwin)
enum S_IFLNK = 0xA000; // octal 0120000
enum S_IFSOCK = 0xC000; // octal 0140000
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else version (FreeBSD)
{
@@ -2373,7 +2418,17 @@ else version (FreeBSD)
enum S_IFLNK = 0xA000; // octal 0120000
enum S_IFSOCK = 0xC000; // octal 0140000
- int mknod(in char*, mode_t, dev_t);
+ version (GNU)
+ {
+ int mknod(const scope char*, mode_t, dev_t);
+ }
+ else
+ {
+ static if (__FreeBSD_version >= INO64_FIRST)
+ pragma(mangle, "mknod@FBSD_1.5") int mknod(const scope char*, mode_t, dev_t);
+ else
+ pragma(mangle, "mknod@FBSD_1.0") int mknod(const scope char*, mode_t, dev_t);
+ }
}
else version (NetBSD)
{
@@ -2386,7 +2441,7 @@ else version (NetBSD)
enum S_IFLNK = 0xA000; // octal 0120000
enum S_IFSOCK = 0xC000; // octal 0140000
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else version (OpenBSD)
{
@@ -2399,7 +2454,7 @@ else version (OpenBSD)
enum S_IFLNK = 0xA000; // octal 0120000
enum S_IFSOCK = 0xC000; // octal 0140000
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else version (DragonFlyBSD)
{
@@ -2412,7 +2467,7 @@ else version (DragonFlyBSD)
enum S_IFLNK = 0xA000; // octal 0120000
enum S_IFSOCK = 0xC000; // octal 0140000
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else version (Solaris)
{
@@ -2427,7 +2482,7 @@ else version (Solaris)
enum S_IFDOOR = 0xD000;
enum S_IFPORT = 0xE000;
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else version (CRuntime_Bionic)
{
@@ -2440,7 +2495,7 @@ else version (CRuntime_Bionic)
enum S_IFLNK = 0xA000; // octal 0120000
enum S_IFSOCK = 0xC000; // octal 0140000
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else version (CRuntime_Musl)
{
@@ -2455,7 +2510,7 @@ else version (CRuntime_Musl)
S_IFSOCK = 0xC000, // octal 0140000
}
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else version (CRuntime_UClibc)
{
@@ -2468,7 +2523,7 @@ else version (CRuntime_UClibc)
enum S_IFLNK = 0xA000; // octal 0120000
enum S_IFSOCK = 0xC000; // octal 0140000
- int mknod(in char*, mode_t, dev_t);
+ int mknod(const scope char*, mode_t, dev_t);
}
else
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/statvfs.d b/libphobos/libdruntime/core/sys/posix/sys/statvfs.d
index 795d96d..49c8450 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/statvfs.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/statvfs.d
@@ -8,14 +8,15 @@
The Open Group Base Specifications Issue 7 IEEE Std 1003.1, 2018 Edition)
+/
module core.sys.posix.sys.statvfs;
-private import core.stdc.config;
-private import core.sys.posix.config;
+import core.stdc.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types;
version (Posix):
extern (C) :
nothrow:
@nogc:
+@system:
version (CRuntime_Glibc) {
static if (__WORDSIZE == 32)
@@ -158,89 +159,6 @@ else version (OpenBSD)
}
else version (FreeBSD)
{
- import core.sys.freebsd.sys.mount;
-
- // @@@DEPRECATED_2.091@@@
- deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h")
- alias MFSNAMELEN = core.sys.freebsd.sys.mount.MFSNAMELEN;
-
- // @@@DEPRECATED_2.091@@@
- deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h")
- alias MNAMELEN = core.sys.freebsd.sys.mount.MNAMELEN;
-
- // @@@DEPRECATED_2.091@@@
- deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h")
- alias fsid_t = core.sys.freebsd.sys.mount.fsid_t;
-
- // @@@DEPRECATED_2.091@@@
- deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h")
- alias statfs_t = core.sys.freebsd.sys.mount.statfs_t;
-
- // @@@DEPRECATED_2.091@@@
- deprecated("Values moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h")
- enum FFlag
- {
- // @@@DEPRECATED_2.091@@@
- MNT_RDONLY = 1, /* read only filesystem */
-
- // @@@DEPRECATED_2.091@@@
- MNT_SYNCHRONOUS = 2, /* fs written synchronously */
-
- // @@@DEPRECATED_2.091@@@
- MNT_NOEXEC = 4, /* can't exec from filesystem */
-
- // @@@DEPRECATED_2.091@@@
- MNT_NOSUID = 8, /* don't honor setuid fs bits */
-
- // @@@DEPRECATED_2.091@@@
- MNT_NFS4ACLS = 16, /* enable NFS version 4 ACLs */
-
- // @@@DEPRECATED_2.091@@@
- MNT_UNION = 32, /* union with underlying fs */
-
- // @@@DEPRECATED_2.091@@@
- MNT_ASYNC = 64, /* fs written asynchronously */
-
- // @@@DEPRECATED_2.091@@@
- MNT_SUIDDIR = 128, /* special SUID dir handling */
-
- // @@@DEPRECATED_2.091@@@
- MNT_SOFTDEP = 256, /* using soft updates */
-
- // @@@DEPRECATED_2.091@@@
- MNT_NOSYMFOLLOW = 512, /* do not follow symlinks */
-
- // @@@DEPRECATED_2.091@@@
- MNT_GJOURNAL = 1024, /* GEOM journal support enabled */
-
- // @@@DEPRECATED_2.091@@@
- MNT_MULTILABEL = 2048, /* MAC support for objects */
-
- // @@@DEPRECATED_2.091@@@
- MNT_ACLS = 4096, /* ACL support enabled */
-
- // @@@DEPRECATED_2.091@@@
- MNT_NOATIME = 8192, /* dont update file access time */
-
- // @@@DEPRECATED_2.091@@@
- MNT_NOCLUSTERR = 16384, /* disable cluster read */
-
- // @@@DEPRECATED_2.091@@@
- MNT_NOCLUSTERW = 32768, /* disable cluster write */
-
- // @@@DEPRECATED_2.091@@@
- MNT_SUJ = 65536, /* using journaled soft updates */
-
- // @@@DEPRECATED_2.091@@@
- MNT_AUTOMOUNTED = 131072 /* mounted by automountd(8) */
- }
-
- deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h")
- alias statfs = core.sys.freebsd.sys.mount.statfs;
-
- deprecated("Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h")
- alias fstatfs = core.sys.freebsd.sys.mount.fstatfs;
-
struct statvfs_t
{
fsblkcnt_t f_bavail;
@@ -259,8 +177,16 @@ else version (FreeBSD)
enum uint ST_RDONLY = 0x1;
enum uint ST_NOSUID = 0x2;
- int fstatvfs(int, statvfs_t*);
- int statvfs(const char*, statvfs_t*);
+ version (GNU)
+ {
+ int fstatvfs(int, statvfs_t*);
+ int statvfs(const char*, statvfs_t*);
+ }
+ else
+ {
+ pragma(mangle, "fstatvfs@FBSD_1.0") int fstatvfs(int, statvfs_t*);
+ pragma(mangle, "statvfs@FBSD_1.0") int statvfs(const char*, statvfs_t*);
+ }
}
else
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/time.d b/libphobos/libdruntime/core/sys/posix/sys/time.d
index 4c82930..95cf883 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/time.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/time.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.sys.time;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for time_t, suseconds_t
public import core.sys.posix.sys.select; // for fd_set, FD_CLR() FD_ISSET() FD_SET() FD_ZERO() FD_SETSIZE, select()
@@ -31,6 +31,7 @@ version (linux) public import core.sys.linux.sys.time;
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// XOpen (XSI)
@@ -55,8 +56,8 @@ ITIMER_PROF
int getitimer(int, itimerval*);
int gettimeofday(timeval*, void*);
int select(int, fd_set*, fd_set*, fd_set*, timeval*); (defined in core.sys.posix.sys.signal)
-int setitimer(int, in itimerval*, itimerval*);
-int utimes(in char*, ref const(timeval)[2]); // LEGACY
+int setitimer(int, const scope itimerval*, itimerval*);
+int utimes(const scope char*, ref const(timeval)[2]); // LEGACY
*/
version (CRuntime_Glibc)
@@ -79,8 +80,8 @@ version (CRuntime_Glibc)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, void*);
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]); // LEGACY
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]); // LEGACY
}
else version (CRuntime_Musl)
{
@@ -90,7 +91,7 @@ else version (CRuntime_Musl)
suseconds_t tv_usec;
}
int gettimeofday(timeval*, void*);
- int utimes(in char*, ref const(timeval)[2]);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else version (Darwin)
{
@@ -115,8 +116,8 @@ else version (Darwin)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void*
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]);
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else version (FreeBSD)
{
@@ -141,8 +142,8 @@ else version (FreeBSD)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void*
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]);
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else version (NetBSD)
{
@@ -160,8 +161,8 @@ else version (NetBSD)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, void*); // timezone_t* is normally void*
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]);
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else version (OpenBSD)
{
@@ -186,8 +187,8 @@ else version (OpenBSD)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, timezone_t*);
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]);
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else version (DragonFlyBSD)
{
@@ -212,8 +213,8 @@ else version (DragonFlyBSD)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void*
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]);
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else version (Solaris)
{
@@ -231,8 +232,8 @@ else version (Solaris)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, void*);
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]);
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else version (CRuntime_Bionic)
{
@@ -260,8 +261,8 @@ else version (CRuntime_Bionic)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, timezone_t*);
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]);
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else version (CRuntime_UClibc)
{
@@ -283,8 +284,8 @@ else version (CRuntime_UClibc)
int getitimer(int, itimerval*);
int gettimeofday(timeval*, void*);
- int setitimer(int, in itimerval*, itimerval*);
- int utimes(in char*, ref const(timeval)[2]);
+ int setitimer(int, const scope itimerval*, itimerval*);
+ int utimes(const scope char*, ref const(timeval)[2]);
}
else
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/ttycom.d b/libphobos/libdruntime/core/sys/posix/sys/ttycom.d
index 38abb2f..1a6c11b 100644..100755
--- a/libphobos/libdruntime/core/sys/posix/sys/ttycom.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/ttycom.d
@@ -22,6 +22,7 @@ else version (WatchOS)
version (Posix):
nothrow @nogc:
+@system:
version (Darwin)
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d
index 2d8ef92..abcea99 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/types.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/types.d
@@ -15,8 +15,8 @@
*/
module core.sys.posix.sys.types;
-private import core.sys.posix.config;
-private import core.stdc.stdint;
+import core.sys.posix.config;
+import core.stdc.stdint;
public import core.stdc.stddef;
version (OSX)
@@ -30,6 +30,7 @@ else version (WatchOS)
version (Posix):
extern (C):
+@system:
//
// bits/typesizes.h -- underlying types for *_t.
@@ -139,10 +140,33 @@ else version (CRuntime_Musl)
alias int pid_t;
alias uint uid_t;
alias uint gid_t;
+
+ /**
+ * Musl versions before v1.2.0 (up to v1.1.24) had different
+ * definitions for `time_t` for 32 bits.
+ * This was changed to always be 64 bits in v1.2.0:
+ * https://musl.libc.org/time64.html
+ * This change was only for 32 bits system and
+ * didn't affect 64 bits systems
+ *
+ * To check previous definitions, `grep` for `time_t` in `arch/`,
+ * and the result should be (in v1.1.24):
+ * ---
+ * // arch/riscv64/bits/alltypes.h.in:20:TYPEDEF long time_t;
+ * // arch/s390x/bits/alltypes.h.in:17:TYPEDEF long time_t;
+ * // arch/sh/bits/alltypes.h.in:21:TYPEDEF long time_t;
+ * ---
+ *
+ * In order to be compatible with old versions of Musl,
+ * one can recompile druntime with `CRuntime_Musl_Pre_Time64`.
+ */
version (D_X32)
alias long time_t;
- else
+ else version (CRuntime_Musl_Pre_Time64)
alias c_long time_t;
+ else
+ alias long time_t;
+
alias c_long clock_t;
alias c_ulong pthread_t;
version (D_LP64)
@@ -688,6 +712,18 @@ version (CRuntime_Glibc)
enum __SIZEOF_PTHREAD_BARRIER_T = 32;
enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
}
+ else version (SPARC)
+ {
+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
+ enum __SIZEOF_PTHREAD_COND_T = 48;
+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
+ }
else version (SPARC64)
{
enum __SIZEOF_PTHREAD_ATTR_T = 56;
@@ -1067,7 +1103,14 @@ else version (DragonFlyBSD)
alias void* pthread_key_t;
alias void* pthread_mutex_t;
alias void* pthread_mutexattr_t;
- alias void* pthread_once_t;
+
+ private struct pthread_once
+ {
+ int state;
+ pthread_mutex_t mutex;
+ }
+ alias pthread_once pthread_once_t;
+
alias void* pthread_rwlock_t;
alias void* pthread_rwlockattr_t;
alias void* pthread_t;
diff --git a/libphobos/libdruntime/core/sys/posix/sys/uio.d b/libphobos/libdruntime/core/sys/posix/sys/uio.d
index df34ef3..2563c6d 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/uio.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/uio.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.sys.uio;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for ssize_t
version (OSX)
@@ -28,6 +28,7 @@ else version (WatchOS)
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// Required
@@ -42,8 +43,8 @@ struct iovec
ssize_t // from core.sys.posix.sys.types
size_t // from core.sys.posix.sys.types
-ssize_t readv(int, in iovec*, int);
-ssize_t writev(int, in iovec*, int);
+ssize_t readv(int, const scope iovec*, int);
+ssize_t writev(int, const scope iovec*, int);
*/
version (CRuntime_Glibc)
@@ -54,8 +55,8 @@ version (CRuntime_Glibc)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else version (Darwin)
{
@@ -65,8 +66,8 @@ else version (Darwin)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else version (FreeBSD)
{
@@ -76,8 +77,8 @@ else version (FreeBSD)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else version (NetBSD)
{
@@ -87,8 +88,8 @@ else version (NetBSD)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else version (OpenBSD)
{
@@ -98,8 +99,8 @@ else version (OpenBSD)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else version (DragonFlyBSD)
{
@@ -109,8 +110,8 @@ else version (DragonFlyBSD)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else version (Solaris)
{
@@ -120,8 +121,8 @@ else version (Solaris)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else version (CRuntime_Bionic)
{
@@ -131,8 +132,8 @@ else version (CRuntime_Bionic)
size_t iov_len;
}
- int readv(int, in iovec*, int);
- int writev(int, in iovec*, int);
+ int readv(int, const scope iovec*, int);
+ int writev(int, const scope iovec*, int);
}
else version (CRuntime_Musl)
{
@@ -142,8 +143,8 @@ else version (CRuntime_Musl)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else version (CRuntime_UClibc)
{
@@ -153,8 +154,8 @@ else version (CRuntime_UClibc)
size_t iov_len;
}
- ssize_t readv(int, in iovec*, int);
- ssize_t writev(int, in iovec*, int);
+ ssize_t readv(int, const scope iovec*, int);
+ ssize_t writev(int, const scope iovec*, int);
}
else
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/un.d b/libphobos/libdruntime/core/sys/posix/sys/un.d
index 11e98a7..5030e16 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/un.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/un.d
@@ -25,6 +25,7 @@ else version (WatchOS)
version (Posix):
extern(C):
+@system:
public import core.sys.posix.sys.socket: sa_family_t;
diff --git a/libphobos/libdruntime/core/sys/posix/sys/utsname.d b/libphobos/libdruntime/core/sys/posix/sys/utsname.d
index 5de50ac..0abbf14 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/utsname.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/utsname.d
@@ -16,6 +16,7 @@ version (Posix):
extern(C):
nothrow:
@nogc:
+@system:
version (CRuntime_Glibc)
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/wait.d b/libphobos/libdruntime/core/sys/posix/sys/wait.d
index 322326d..dada64f 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/wait.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/wait.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.sys.wait;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for id_t, pid_t
public import core.sys.posix.signal; // for siginfo_t (XSI)
//public import core.sys.posix.resource; // for rusage (XSI)
@@ -30,6 +30,7 @@ else version (WatchOS)
version (Posix):
extern (C) nothrow @nogc:
+@system:
//
// Required
@@ -52,6 +53,8 @@ pid_t waitpid(pid_t, int*, int);
version (CRuntime_Glibc)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -80,6 +83,8 @@ version (CRuntime_Glibc)
}
else version (Darwin)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -102,6 +107,8 @@ else version (Darwin)
}
else version (FreeBSD)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -124,6 +131,8 @@ else version (FreeBSD)
}
else version (NetBSD)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -146,6 +155,8 @@ else version (NetBSD)
}
else version (OpenBSD)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -169,6 +180,8 @@ else version (OpenBSD)
}
else version (DragonFlyBSD)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -191,6 +204,8 @@ else version (DragonFlyBSD)
}
else version (Solaris)
{
+ @safe pure:
+
enum WNOHANG = 64;
enum WUNTRACED = 4;
@@ -204,6 +219,8 @@ else version (Solaris)
}
else version (CRuntime_Bionic)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -216,6 +233,8 @@ else version (CRuntime_Bionic)
}
else version (CRuntime_Musl)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -229,6 +248,8 @@ else version (CRuntime_Musl)
}
else version (CRuntime_UClibc)
{
+ @safe pure:
+
enum WNOHANG = 1;
enum WUNTRACED = 2;
@@ -326,8 +347,30 @@ else version (FreeBSD)
enum WSTOPPED = WUNTRACED;
enum WCONTINUED = 4;
enum WNOWAIT = 8;
+ enum WEXITED = 16;
+ enum WTRAPPED = 32;
+
+ enum idtype_t
+ {
+ P_UID,
+ P_GID,
+ P_SID,
+ P_JAILID,
+ P_PID,
+ P_PPID,
+ P_PGID,
+ P_CID,
+ P_ALL,
+ P_LWPID,
+ P_TASKID,
+ P_PROJID,
+ P_POOLID,
+ P_CTID,
+ P_CPUID,
+ P_PSETID
+ }
- // http://www.freebsd.org/projects/c99/
+ int waitid(idtype_t, id_t, siginfo_t*, int);
}
else version (NetBSD)
{
diff --git a/libphobos/libdruntime/core/sys/posix/syslog.d b/libphobos/libdruntime/core/sys/posix/syslog.d
index a319b01..cf85664 100644
--- a/libphobos/libdruntime/core/sys/posix/syslog.d
+++ b/libphobos/libdruntime/core/sys/posix/syslog.d
@@ -27,6 +27,7 @@ else version (WatchOS)
version (Posix):
extern (C) nothrow @nogc:
+@system:
version (CRuntime_Glibc)
{
@@ -40,7 +41,7 @@ version (CRuntime_Glibc)
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
- };
+ }
//OPTIONS
enum {
@@ -50,7 +51,7 @@ version (CRuntime_Glibc)
LOG_NDELAY = 0x08, /* don't delay open */
LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */
LOG_PERROR = 0x20, /* log to stderr as well */
- };
+ }
//FACILITY
enum {
@@ -78,7 +79,7 @@ version (CRuntime_Glibc)
LOG_LOCAL7 = (23<<3), /* reserved for local use */
LOG_NFACILITIES = 24, /* current number of facilities */
- };
+ }
int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */
int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */
@@ -102,7 +103,7 @@ else version (Darwin)
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
- };
+ }
//OPTIONS
enum {
@@ -111,7 +112,7 @@ else version (Darwin)
LOG_ODELAY = 0x04, /* delay open until first syslog() (default) */
LOG_NDELAY = 0x08, /* don't delay open */
LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */
- };
+ }
//FACILITY
enum {
@@ -136,7 +137,7 @@ else version (Darwin)
LOG_LOCAL7 = (23<<3), /* reserved for local use */
LOG_NFACILITIES = 24, /* current number of facilities */
- };
+ }
int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */
int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */
@@ -160,7 +161,7 @@ else version (FreeBSD)
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
- };
+ }
//OPTIONS
enum {
@@ -170,7 +171,7 @@ else version (FreeBSD)
LOG_NDELAY = 0x08, /* don't delay open */
LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */
LOG_PERROR = 0x20, /* log to stderr as well */
- };
+ }
//FACILITY
enum {
@@ -201,7 +202,7 @@ else version (FreeBSD)
LOG_LOCAL7 = (23<<3), /* reserved for local use */
LOG_NFACILITIES = 24, /* current number of facilities */
- };
+ }
int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */
int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */
@@ -225,7 +226,7 @@ else version (NetBSD)
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
- };
+ }
//OPTIONS
enum {
@@ -235,7 +236,7 @@ else version (NetBSD)
LOG_NDELAY = 0x08, /* don't delay open */
LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */
LOG_PERROR = 0x20, /* log to stderr as well */
- };
+ }
//FACILITY
enum {
@@ -266,7 +267,7 @@ else version (NetBSD)
LOG_LOCAL7 = (23<<3), /* reserved for local use */
LOG_NFACILITIES = 24, /* current number of facilities */
- };
+ }
int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */
int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */
@@ -355,7 +356,7 @@ else version (DragonFlyBSD)
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
- };
+ }
//OPTIONS
enum {
@@ -365,7 +366,7 @@ else version (DragonFlyBSD)
LOG_NDELAY = 0x08, /* don't delay open */
LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */
LOG_PERROR = 0x20, /* log to stderr as well */
- };
+ }
//FACILITY
enum {
@@ -396,7 +397,7 @@ else version (DragonFlyBSD)
LOG_LOCAL7 = (23<<3), /* reserved for local use */
LOG_NFACILITIES = 24, /* current number of facilities */
- };
+ }
int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */
int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */
@@ -420,7 +421,7 @@ else version (Solaris)
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
- };
+ }
//OPTIONS
enum {
@@ -428,7 +429,7 @@ else version (Solaris)
LOG_CONS = 0x02, /* log on the console if errors in sending */
LOG_NDELAY = 0x08, /* don't delay open */
LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */
- };
+ }
//FACILITY
enum {
@@ -456,7 +457,7 @@ else version (Solaris)
LOG_LOCAL7 = (23<<3), /* reserved for local use */
LOG_NFACILITIES = 24, /* current number of facilities */
- };
+ }
int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */
int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */
@@ -478,7 +479,7 @@ else version (CRuntime_UClibc)
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
- };
+ }
//OPTIONS
enum {
@@ -488,7 +489,7 @@ else version (CRuntime_UClibc)
LOG_NDELAY = 0x08, /* don't delay open */
LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */
LOG_PERROR = 0x20, /* log to stderr as well */
- };
+ }
//FACILITY
enum {
@@ -516,7 +517,7 @@ else version (CRuntime_UClibc)
LOG_LOCAL7 = (23<<3), /* reserved for local use */
LOG_NFACILITIES = 24, /* current number of facilities */
- };
+ }
int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */
int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */
@@ -538,7 +539,7 @@ else version (CRuntime_Musl)
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
- };
+ }
//OPTIONS
enum {
@@ -548,7 +549,7 @@ else version (CRuntime_Musl)
LOG_NDELAY = 0x08, /* don't delay open */
LOG_NOWAIT = 0x10, /* don't wait for console forks: DEPRECATED */
LOG_PERROR = 0x20, /* log to stderr as well */
- };
+ }
//FACILITY
enum {
@@ -576,7 +577,7 @@ else version (CRuntime_Musl)
LOG_LOCAL7 = (23<<3), /* reserved for local use */
LOG_NFACILITIES = 24, /* current number of facilities */
- };
+ }
int LOG_MASK(int pri) { return 1 << pri; } /* mask for one priority */
int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; } /* all priorities through pri */
diff --git a/libphobos/libdruntime/core/sys/posix/termios.d b/libphobos/libdruntime/core/sys/posix/termios.d
index f296a7f..5de6785 100644
--- a/libphobos/libdruntime/core/sys/posix/termios.d
+++ b/libphobos/libdruntime/core/sys/posix/termios.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.termios;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for pid_t
version (OSX)
@@ -31,6 +31,7 @@ extern (C):
nothrow:
@nogc:
+@system:
//
// Required
@@ -129,8 +130,8 @@ TCION
TCOOFF
TCOON
-speed_t cfgetispeed(in termios*);
-speed_t cfgetospeed(in termios*);
+speed_t cfgetispeed(const scope termios*);
+speed_t cfgetospeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int cfsetospeed(termios*, speed_t);
int tcdrain(int);
@@ -138,7 +139,7 @@ int tcflow(int, int);
int tcflush(int, int);
int tcgetattr(int, termios*);
int tcsendbreak(int, int);
-int tcsetattr(int, int, in termios*);
+int tcsetattr(int, int, const scope termios*);
*/
version (CRuntime_Glibc)
@@ -239,8 +240,8 @@ version (CRuntime_Glibc)
enum TCOOFF = 0;
enum TCOON = 1;
- speed_t cfgetispeed(in termios*);
- speed_t cfgetospeed(in termios*);
+ speed_t cfgetispeed(const scope termios*);
+ speed_t cfgetospeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int cfsetospeed(termios*, speed_t);
int tcdrain(int);
@@ -248,7 +249,7 @@ version (CRuntime_Glibc)
int tcflush(int, int);
int tcgetattr(int, termios*);
int tcsendbreak(int, int);
- int tcsetattr(int, int, in termios*);
+ int tcsetattr(int, int, const scope termios*);
}
else version (Darwin)
{
@@ -347,8 +348,8 @@ else version (Darwin)
enum TCOOFF = 1;
enum TCOON = 2;
- speed_t cfgetispeed(in termios*);
- speed_t cfgetospeed(in termios*);
+ speed_t cfgetispeed(const scope termios*);
+ speed_t cfgetospeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int cfsetospeed(termios*, speed_t);
int tcdrain(int);
@@ -356,7 +357,7 @@ else version (Darwin)
int tcflush(int, int);
int tcgetattr(int, termios*);
int tcsendbreak(int, int);
- int tcsetattr(int, int, in termios*);
+ int tcsetattr(int, int, const scope termios*);
}
else version (FreeBSD)
@@ -456,8 +457,8 @@ else version (FreeBSD)
enum TCOOFF = 1;
enum TCOON = 2;
- speed_t cfgetispeed(in termios*);
- speed_t cfgetospeed(in termios*);
+ speed_t cfgetispeed(const scope termios*);
+ speed_t cfgetospeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int cfsetospeed(termios*, speed_t);
int tcdrain(int);
@@ -465,7 +466,7 @@ else version (FreeBSD)
int tcflush(int, int);
int tcgetattr(int, termios*);
int tcsendbreak(int, int);
- int tcsetattr(int, int, in termios*);
+ int tcsetattr(int, int, const scope termios*);
}
else version (DragonFlyBSD)
{
@@ -564,8 +565,8 @@ else version (DragonFlyBSD)
enum TCOOFF = 1;
enum TCOON = 2;
- speed_t cfgetispeed(in termios*);
- speed_t cfgetospeed(in termios*);
+ speed_t cfgetispeed(const scope termios*);
+ speed_t cfgetospeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int cfsetospeed(termios*, speed_t);
int tcdrain(int);
@@ -573,7 +574,7 @@ else version (DragonFlyBSD)
int tcflush(int, int);
int tcgetattr(int, termios*);
int tcsendbreak(int, int);
- int tcsetattr(int, int, in termios*);
+ int tcsetattr(int, int, const scope termios*);
}
else version (NetBSD)
{
@@ -672,8 +673,8 @@ else version (NetBSD)
enum TCOOFF = 1;
enum TCOON = 2;
- speed_t cfgetispeed(in termios*);
- speed_t cfgetospeed(in termios*);
+ speed_t cfgetispeed(const scope termios*);
+ speed_t cfgetospeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int cfsetospeed(termios*, speed_t);
int tcdrain(int);
@@ -681,7 +682,7 @@ else version (NetBSD)
int tcflush(int, int);
int tcgetattr(int, termios*);
int tcsendbreak(int, int);
- int tcsetattr(int, int, in termios*);
+ int tcsetattr(int, int, const scope termios*);
}
else version (OpenBSD)
{
@@ -780,8 +781,8 @@ else version (OpenBSD)
enum TCOOFF = 1;
enum TCOON = 2;
- speed_t cfgetispeed(in termios*);
- speed_t cfgetospeed(in termios*);
+ speed_t cfgetispeed(const scope termios*);
+ speed_t cfgetospeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int cfsetospeed(termios*, speed_t);
int tcdrain(int);
@@ -789,7 +790,7 @@ else version (OpenBSD)
int tcflush(int, int);
int tcgetattr(int, termios*);
int tcsendbreak(int, int);
- int tcsetattr(int, int, in termios*);
+ int tcsetattr(int, int, const scope termios*);
}
else version (Solaris)
{
@@ -913,12 +914,12 @@ else version (Solaris)
* POSIX termios functions
* These functions get mapped into ioctls.
*/
- speed_t cfgetospeed(in termios*);
+ speed_t cfgetospeed(const scope termios*);
int cfsetospeed(termios*, speed_t);
- speed_t cfgetispeed(in termios*);
+ speed_t cfgetispeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int tcgetattr(int, termios*);
- int tcsetattr(int, int, in termios*);
+ int tcsetattr(int, int, const scope termios*);
int tcsendbreak(int, int);
int tcdrain(int);
int tcflush(int, int);
@@ -1028,8 +1029,8 @@ else version (CRuntime_UClibc)
enum TCOOFF = 0;
enum TCOON = 1;
- speed_t cfgetispeed(in termios*);
- speed_t cfgetospeed(in termios*);
+ speed_t cfgetispeed(const scope termios*);
+ speed_t cfgetospeed(const scope termios*);
int cfsetispeed(termios*, speed_t);
int cfsetospeed(termios*, speed_t);
int tcdrain(int);
@@ -1037,7 +1038,7 @@ else version (CRuntime_UClibc)
int tcflush(int, int);
int tcgetattr(int, termios*);
int tcsendbreak(int, int);
- int tcsetattr(int, int, in termios*);
+ int tcsetattr(int, int, const scope termios*);
}
//
diff --git a/libphobos/libdruntime/core/sys/posix/time.d b/libphobos/libdruntime/core/sys/posix/time.d
index 82a3f19..52a6f92 100644
--- a/libphobos/libdruntime/core/sys/posix/time.d
+++ b/libphobos/libdruntime/core/sys/posix/time.d
@@ -15,7 +15,7 @@
*/
module core.sys.posix.time;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.stdc.time;
public import core.sys.posix.sys.types;
public import core.sys.posix.signal; // for sigevent
@@ -33,19 +33,20 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required (defined in core.stdc.time)
//
/*
-char* asctime(in tm*);
+char* asctime(const scope tm*);
clock_t clock();
-char* ctime(in time_t*);
+char* ctime(const scope time_t*);
double difftime(time_t, time_t);
-tm* gmtime(in time_t*);
-tm* localtime(in time_t*);
+tm* gmtime(const scope time_t*);
+tm* localtime(const scope time_t*);
time_t mktime(tm*);
-size_t strftime(char*, size_t, in char*, in tm*);
+size_t strftime(char*, size_t, const scope char*, const scope tm*);
time_t time(time_t*);
*/
@@ -114,7 +115,7 @@ int clock_getcpuclockid(pid_t, clockid_t*);
// Clock Selection (CS)
//
/*
-int clock_nanosleep(clockid_t, int, in timespec*, timespec*);
+int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*);
*/
//
@@ -189,13 +190,13 @@ timer_t
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
-int clock_settime(clockid_t, in timespec*);
-int nanosleep(in timespec*, timespec*);
+int clock_settime(clockid_t, const scope timespec*);
+int nanosleep(const scope timespec*, timespec*);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
int timer_getoverrun(timer_t);
-int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
*/
version (CRuntime_Glibc)
@@ -225,17 +226,17 @@ version (CRuntime_Glibc)
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
- int clock_settime(clockid_t, in timespec*);
- int nanosleep(in timespec*, timespec*);
+ int clock_settime(clockid_t, const scope timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
int timer_getoverrun(timer_t);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
}
else version (Darwin)
{
- int nanosleep(in timespec*, timespec*);
+ int nanosleep(const scope timespec*, timespec*);
}
else version (FreeBSD)
{
@@ -264,13 +265,13 @@ else version (FreeBSD)
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
- int clock_settime(clockid_t, in timespec*);
- int nanosleep(in timespec*, timespec*);
+ int clock_settime(clockid_t, const scope timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
int timer_getoverrun(timer_t);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
}
else version (DragonFlyBSD)
{
@@ -290,13 +291,13 @@ else version (DragonFlyBSD)
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
- int clock_settime(clockid_t, in timespec*);
- int nanosleep(in timespec*, timespec*);
+ int clock_settime(clockid_t, const scope timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
int timer_getoverrun(timer_t);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
}
else version (NetBSD)
{
@@ -314,13 +315,13 @@ else version (NetBSD)
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
- int clock_settime(clockid_t, in timespec*);
- int nanosleep(in timespec*, timespec*);
+ int clock_settime(clockid_t, const scope timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
int timer_getoverrun(timer_t);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
}
else version (OpenBSD)
{
@@ -338,13 +339,13 @@ else version (OpenBSD)
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
- int clock_settime(clockid_t, in timespec*);
- int nanosleep(in timespec*, timespec*);
+ int clock_settime(clockid_t, const scope timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
int timer_getoverrun(timer_t);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
}
else version (Solaris)
{
@@ -365,16 +366,16 @@ else version (Solaris)
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
- int clock_settime(clockid_t, in timespec*);
- int clock_nanosleep(clockid_t, int, in timespec*, timespec*);
+ int clock_settime(clockid_t, const scope timespec*);
+ int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*);
- int nanosleep(in timespec*, timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_getoverrun(timer_t);
int timer_gettime(timer_t, itimerspec*);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
}
else version (CRuntime_Bionic)
{
@@ -396,12 +397,12 @@ else version (CRuntime_Bionic)
int clock_getres(int, timespec*);
int clock_gettime(int, timespec*);
- int nanosleep(in timespec*, timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int timer_create(int, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
int timer_getoverrun(timer_t);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
}
else version (CRuntime_Musl)
{
@@ -426,18 +427,18 @@ else version (CRuntime_Musl)
enum CLOCK_SGI_CYCLE = 10;
enum CLOCK_TAI = 11;
- int nanosleep(in timespec*, timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
- int clock_settime(clockid_t, in timespec*);
- int clock_nanosleep(clockid_t, int, in timespec*, timespec*);
+ int clock_settime(clockid_t, const scope timespec*);
+ int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*);
int clock_getcpuclockid(pid_t, clockid_t *);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
int timer_getoverrun(timer_t);
}
else version (CRuntime_UClibc)
@@ -459,13 +460,13 @@ else version (CRuntime_UClibc)
int clock_getres(clockid_t, timespec*);
int clock_gettime(clockid_t, timespec*);
- int clock_settime(clockid_t, in timespec*);
- int nanosleep(in timespec*, timespec*);
+ int clock_settime(clockid_t, const scope timespec*);
+ int nanosleep(const scope timespec*, timespec*);
int timer_create(clockid_t, sigevent*, timer_t*);
int timer_delete(timer_t);
int timer_gettime(timer_t, itimerspec*);
int timer_getoverrun(timer_t);
- int timer_settime(timer_t, int, in itimerspec*, itimerspec*);
+ int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
}
else
{
@@ -476,81 +477,81 @@ else
// Thread-Safe Functions (TSF)
//
/*
-char* asctime_r(in tm*, char*);
-char* ctime_r(in time_t*, char*);
-tm* gmtime_r(in time_t*, tm*);
-tm* localtime_r(in time_t*, tm*);
+char* asctime_r(const scope tm*, char*);
+char* ctime_r(const scope time_t*, char*);
+tm* gmtime_r(const scope time_t*, tm*);
+tm* localtime_r(const scope time_t*, tm*);
*/
version (CRuntime_Glibc)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (Darwin)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (FreeBSD)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (NetBSD)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (OpenBSD)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (DragonFlyBSD)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (Solaris)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (CRuntime_Bionic)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (CRuntime_Musl)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else version (CRuntime_UClibc)
{
- char* asctime_r(in tm*, char*);
- char* ctime_r(in time_t*, char*);
- tm* gmtime_r(in time_t*, tm*);
- tm* localtime_r(in time_t*, tm*);
+ char* asctime_r(const scope tm*, char*);
+ char* ctime_r(const scope time_t*, char*);
+ tm* gmtime_r(const scope time_t*, tm*);
+ tm* localtime_r(const scope time_t*, tm*);
}
else
{
@@ -566,8 +567,8 @@ getdate_err
int daylight;
int timezone;
-tm* getdate(in char*);
-char* strptime(in char*, in char*, tm*);
+tm* getdate(const scope char*);
+char* strptime(const scope char*, const scope char*, tm*);
*/
version (CRuntime_Glibc)
@@ -575,44 +576,44 @@ version (CRuntime_Glibc)
extern __gshared int daylight;
extern __gshared c_long timezone;
- tm* getdate(in char*);
- char* strptime(in char*, in char*, tm*);
+ tm* getdate(const scope char*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else version (Darwin)
{
extern __gshared c_long timezone;
extern __gshared int daylight;
- tm* getdate(in char*);
- char* strptime(in char*, in char*, tm*);
+ tm* getdate(const scope char*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else version (FreeBSD)
{
- //tm* getdate(in char*);
- char* strptime(in char*, in char*, tm*);
+ //tm* getdate(const scope char*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else version (NetBSD)
{
- tm* getdate(in char*);
- char* strptime(in char*, in char*, tm*);
+ tm* getdate(const scope char*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else version (OpenBSD)
{
- //tm* getdate(in char*);
- char* strptime(in char*, in char*, tm*);
+ //tm* getdate(const scope char*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else version (DragonFlyBSD)
{
- //tm* getdate(in char*);
- char* strptime(in char*, in char*, tm*);
+ //tm* getdate(const scope char*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else version (Solaris)
{
extern __gshared c_long timezone, altzone;
extern __gshared int daylight;
- tm* getdate(in char*);
- char* __strptime_dontzero(in char*, in char*, tm*);
+ tm* getdate(const scope char*);
+ char* __strptime_dontzero(const scope char*, const scope char*, tm*);
alias __strptime_dontzero strptime;
}
else version (CRuntime_Bionic)
@@ -620,23 +621,23 @@ else version (CRuntime_Bionic)
extern __gshared int daylight;
extern __gshared c_long timezone;
- char* strptime(in char*, in char*, tm*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else version (CRuntime_Musl)
{
extern __gshared int daylight;
extern __gshared c_long timezone;
- tm* getdate(in char*);
- char* strptime(in char*, in char*, tm*);
+ tm* getdate(const scope char*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else version (CRuntime_UClibc)
{
extern __gshared int daylight;
extern __gshared c_long timezone;
- tm* getdate(in char*);
- char* strptime(in char*, in char*, tm*);
+ tm* getdate(const scope char*);
+ char* strptime(const scope char*, const scope char*, tm*);
}
else
{
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
index 2e518ae..e38aa96 100644
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -14,15 +14,27 @@
*/
module core.sys.posix.ucontext;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.signal; // for sigset_t, stack_t
-private import core.stdc.stdint : uintptr_t;
+import core.stdc.stdint : uintptr_t;
version (Posix):
extern (C):
nothrow:
@nogc:
-
+@system:
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (ARM) version = ARM_Any;
+version (AArch64) version = ARM_Any;
version (MIPS32) version = MIPS_Any;
version (MIPS64) version = MIPS_Any;
version (PPC) version = PPC_Any;
@@ -648,7 +660,7 @@ version (CRuntime_Glibc)
mcontext_t uc_mcontext;
}
}
- else version (SPARC64)
+ else version (SPARC_Any)
{
enum MC_NGREG = 19;
alias mc_greg_t = c_ulong;
@@ -909,6 +921,72 @@ else version (CRuntime_Musl)
else
static assert(0, "unimplemented");
}
+else version (Darwin)
+{
+ private
+ {
+ version (X86_64)
+ {
+ struct __darwin_mcontext
+ {
+ ulong[89] __opaque;
+ }
+ static assert(__darwin_mcontext.sizeof == 712);
+ }
+ else version (X86)
+ {
+ struct __darwin_mcontext
+ {
+ uint[150] __opaque;
+ }
+ static assert(__darwin_mcontext.sizeof == 600);
+ }
+ else version (AArch64)
+ {
+ struct __darwin_mcontext
+ {
+ align(16) ulong[102] __opaque;
+ }
+ static assert(__darwin_mcontext.sizeof == 816);
+ }
+ else version (ARM)
+ {
+ struct __darwin_mcontext
+ {
+ uint[85] __opaque;
+ }
+ static assert(__darwin_mcontext.sizeof == 340);
+ }
+ else version (PPC_Any)
+ {
+ struct __darwin_mcontext
+ {
+ version (PPC64)
+ ulong[129] __opaque;
+ else
+ uint[258] __opaque;
+ }
+ static assert(__darwin_mcontext.sizeof == 1032);
+ }
+ else
+ static assert(false, "mcontext_t unimplemented for this platform.");
+ }
+
+ alias mcontext_t = __darwin_mcontext*;
+
+ struct ucontext
+ {
+ int uc_onstack;
+ sigset_t uc_sigmask;
+ stack_t uc_stack;
+ ucontext* uc_link;
+ size_t uc_mcsize;
+ __darwin_mcontext* uc_mcontext;
+ __darwin_mcontext __mcontext_data;
+ }
+
+ alias ucontext_t = ucontext;
+}
else version (FreeBSD)
{
// <machine/ucontext.h>
@@ -1278,7 +1356,7 @@ else version (OpenBSD)
int sc_trapno;
int sc_err;
void* sc_fpstate; // union savefpu*
- };
+ }
}
else version (PPC)
{
@@ -1365,7 +1443,7 @@ else version (DragonFlyBSD)
uint mc_reserved;
uint[8] mc_unused;
int[256] mc_fpregs;
- }; // __attribute__((aligned(64)));
+ } // __attribute__((aligned(64)));
}
else
{
@@ -1389,7 +1467,7 @@ else version (DragonFlyBSD)
}
else version (Solaris)
{
- private import core.stdc.stdint;
+ import core.stdc.stdint;
alias uint[4] upad128_t;
@@ -1479,7 +1557,7 @@ else version (Solaris)
{
uint[32] fpu_regs;
double[16] fpu_dregs;
- };
+ }
fq *fpu_q;
uint fpu_fsr;
ubyte fpu_qcnt;
@@ -1831,8 +1909,8 @@ else version (CRuntime_UClibc)
/*
int getcontext(ucontext_t*);
void makecontext(ucontext_t*, void function(), int, ...);
-int setcontext(in ucontext_t*);
-int swapcontext(ucontext_t*, in ucontext_t*);
+int setcontext(const scope ucontext_t*);
+int swapcontext(ucontext_t*, const scope ucontext_t*);
*/
static if ( is( ucontext_t ) )
@@ -1852,13 +1930,13 @@ static if ( is( ucontext_t ) )
else
void makecontext(ucontext_t*, void function(), int, ...);
- int setcontext(in ucontext_t*);
- int swapcontext(ucontext_t*, in ucontext_t*);
+ int setcontext(const scope ucontext_t*);
+ int swapcontext(ucontext_t*, const scope ucontext_t*);
}
version (Solaris)
{
- int walkcontext(in ucontext_t*, int function(uintptr_t, int, void*), void*);
+ int walkcontext(const scope ucontext_t*, int function(uintptr_t, int, void*), void*);
int addrtosymstr(uintptr_t, char*, int);
int printstack(int);
}
diff --git a/libphobos/libdruntime/core/sys/posix/unistd.d b/libphobos/libdruntime/core/sys/posix/unistd.d
index 418d63d..d996556 100644
--- a/libphobos/libdruntime/core/sys/posix/unistd.d
+++ b/libphobos/libdruntime/core/sys/posix/unistd.d
@@ -14,8 +14,8 @@
*/
module core.sys.posix.unistd;
-private import core.sys.posix.config;
-private import core.stdc.stddef;
+import core.sys.posix.config;
+import core.stdc.stddef;
public import core.sys.posix.inttypes; // for intptr_t
public import core.sys.posix.sys.types; // for ssize_t, uid_t, gid_t, off_t, pid_t, useconds_t
@@ -32,6 +32,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
enum STDIN_FILENO = 0;
enum STDOUT_FILENO = 1;
@@ -42,20 +43,20 @@ extern __gshared int optind;
extern __gshared int opterr;
extern __gshared int optopt;
-int access(in char*, int);
+int access(const scope char*, int);
uint alarm(uint) @trusted;
-int chdir(in char*);
-int chown(in char*, uid_t, gid_t);
+int chdir(const scope char*);
+int chown(const scope char*, uid_t, gid_t);
int close(int) @trusted;
size_t confstr(int, char*, size_t);
int dup(int) @trusted;
int dup2(int, int) @trusted;
-int execl(in char*, in char*, ...);
-int execle(in char*, in char*, ...);
-int execlp(in char*, in char*, ...);
-int execv(in char*, in char**);
-int execve(in char*, in char**, in char**);
-int execvp(in char*, in char**);
+int execl(const scope char*, const scope char*, ...);
+int execle(const scope char*, const scope char*, ...);
+int execlp(const scope char*, const scope char*, ...);
+int execv(const scope char*, const scope char**);
+int execve(const scope char*, const scope char**, const scope char**);
+int execvp(const scope char*, const scope char**);
void _exit(int) @trusted;
int fchown(int, uid_t, gid_t) @trusted;
pid_t fork() @trusted;
@@ -69,36 +70,36 @@ int getgroups(int, gid_t *);
int gethostname(char*, size_t);
char* getlogin() @trusted;
int getlogin_r(char*, size_t);
-int getopt(int, in char**, in char*);
+int getopt(int, const scope char**, const scope char*);
pid_t getpgrp() @trusted;
pid_t getpid() @trusted;
pid_t getppid() @trusted;
uid_t getuid() @trusted;
int isatty(int) @trusted;
-int link(in char*, in char*);
+int link(const scope char*, const scope char*);
//off_t lseek(int, off_t, int);
-c_long pathconf(in char*, int);
+c_long pathconf(const scope char*, int);
int pause() @trusted;
int pipe(ref int[2]) @trusted;
ssize_t read(int, void*, size_t);
-ssize_t readlink(in char*, char*, size_t);
-int rmdir(in char*);
+ssize_t readlink(const scope char*, char*, size_t);
+int rmdir(const scope char*);
int setegid(gid_t) @trusted;
int seteuid(uid_t) @trusted;
int setgid(gid_t) @trusted;
-int setgroups(size_t, in gid_t*) @trusted;
+int setgroups(size_t, const scope gid_t*) @trusted;
int setpgid(pid_t, pid_t) @trusted;
pid_t setsid() @trusted;
int setuid(uid_t) @trusted;
uint sleep(uint) @trusted;
-int symlink(in char*, in char*);
+int symlink(const scope char*, const scope char*);
c_long sysconf(int) @trusted;
pid_t tcgetpgrp(int) @trusted;
int tcsetpgrp(int, pid_t) @trusted;
char* ttyname(int) @trusted;
int ttyname_r(int, char*, size_t);
-int unlink(in char*);
-ssize_t write(int, in void*, size_t);
+int unlink(const scope char*);
+ssize_t write(int, const scope void*, size_t);
version (CRuntime_Glibc)
{
@@ -2400,7 +2401,7 @@ else version (CRuntime_UClibc)
// XOpen (XSI)
//
/*
-char* crypt(in char*, in char*);
+char* crypt(const scope char*, const scope char*);
char* ctermid(char*);
void encrypt(ref char[64], int);
int fchdir(int);
@@ -2408,17 +2409,17 @@ c_long gethostid();
pid_t getpgid(pid_t);
pid_t getsid(pid_t);
char* getwd(char*); // LEGACY
-int lchown(in char*, uid_t, gid_t);
+int lchown(const scope char*, uid_t, gid_t);
int lockf(int, int, off_t);
int nice(int);
ssize_t pread(int, void*, size_t, off_t);
-ssize_t pwrite(int, in void*, size_t, off_t);
+ssize_t pwrite(int, const scope void*, size_t, off_t);
pid_t setpgrp();
int setregid(gid_t, gid_t);
int setreuid(uid_t, uid_t);
-void swab(in void*, void*, ssize_t);
+void swab(const scope void*, void*, ssize_t);
void sync();
-int truncate(in char*, off_t);
+int truncate(const scope char*, off_t);
useconds_t ualarm(useconds_t, useconds_t);
int usleep(useconds_t);
pid_t vfork();
@@ -2426,7 +2427,7 @@ pid_t vfork();
version (CRuntime_Glibc)
{
- char* crypt(in char*, in char*);
+ char* crypt(const scope char*, const scope char*);
char* ctermid(char*);
void encrypt(ref char[64], int) @trusted;
int fchdir(int) @trusted;
@@ -2434,17 +2435,17 @@ version (CRuntime_Glibc)
pid_t getpgid(pid_t) @trusted;
pid_t getsid(pid_t) @trusted;
char* getwd(char*); // LEGACY
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
//int lockf(int, int, off_t);
int nice(int) @trusted;
//ssize_t pread(int, void*, size_t, off_t);
- //ssize_t pwrite(int, in void*, size_t, off_t);
+ //ssize_t pwrite(int, const scope void*, size_t, off_t);
pid_t setpgrp() @trusted;
int setregid(gid_t, gid_t) @trusted;
int setreuid(uid_t, uid_t) @trusted;
- void swab(in void*, void*, ssize_t);
+ void swab(const scope void*, void*, ssize_t);
void sync() @trusted;
- //int truncate(in char*, off_t);
+ //int truncate(const scope char*, off_t);
useconds_t ualarm(useconds_t, useconds_t) @trusted;
int usleep(useconds_t) @trusted;
pid_t vfork();
@@ -2457,18 +2458,18 @@ version (CRuntime_Glibc)
ssize_t pread64(int, void*, size_t, off_t);
alias pread64 pread;
- ssize_t pwrite64(int, in void*, size_t, off_t);
+ ssize_t pwrite64(int, const scope void*, size_t, off_t);
alias pwrite64 pwrite;
- int truncate64(in char*, off_t);
+ int truncate64(const scope char*, off_t);
alias truncate64 truncate;
}
else
{
int lockf(int, int, off_t) @trusted;
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
- int truncate(in char*, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
+ int truncate(const scope char*, off_t);
}
}
else version (CRuntime_Musl)
@@ -2479,7 +2480,7 @@ else version (CRuntime_Musl)
}
else version (Darwin)
{
- char* crypt(in char*, in char*);
+ char* crypt(const scope char*, const scope char*);
char* ctermid(char*);
void encrypt(ref char[64], int) @trusted;
int fchdir(int) @trusted;
@@ -2487,24 +2488,24 @@ else version (Darwin)
pid_t getpgid(pid_t) @trusted;
pid_t getsid(pid_t) @trusted;
char* getwd(char*); // LEGACY
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
int lockf(int, int, off_t) @trusted;
int nice(int) @trusted;
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
pid_t setpgrp() @trusted;
int setregid(gid_t, gid_t) @trusted;
int setreuid(uid_t, uid_t) @trusted;
- void swab(in void*, void*, ssize_t);
+ void swab(const scope void*, void*, ssize_t);
void sync() @trusted;
- int truncate(in char*, off_t);
+ int truncate(const scope char*, off_t);
useconds_t ualarm(useconds_t, useconds_t) @trusted;
int usleep(useconds_t) @trusted;
pid_t vfork();
}
else version (FreeBSD)
{
- char* crypt(in char*, in char*);
+ char* crypt(const scope char*, const scope char*);
//char* ctermid(char*);
void encrypt(ref char[64], int) @trusted;
int fchdir(int) @trusted;
@@ -2512,24 +2513,24 @@ else version (FreeBSD)
int getpgid(pid_t) @trusted;
int getsid(pid_t) @trusted;
char* getwd(char*); // LEGACY
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
int lockf(int, int, off_t) @trusted;
int nice(int) @trusted;
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
int setpgrp(pid_t, pid_t) @trusted;
int setregid(gid_t, gid_t) @trusted;
int setreuid(uid_t, uid_t) @trusted;
- void swab(in void*, void*, ssize_t);
+ void swab(const scope void*, void*, ssize_t);
void sync() @trusted;
- int truncate(in char*, off_t);
+ int truncate(const scope char*, off_t);
useconds_t ualarm(useconds_t, useconds_t) @trusted;
int usleep(useconds_t) @trusted;
pid_t vfork();
}
else version (NetBSD)
{
- char* crypt(in char*, in char*);
+ char* crypt(const scope char*, const scope char*);
//char* ctermid(char*);
void encrypt(ref char[64], int) @trusted;
int fchdir(int) @trusted;
@@ -2537,24 +2538,24 @@ else version (NetBSD)
int getpgid(pid_t) @trusted;
int getsid(pid_t) @trusted;
char* getwd(char*); // LEGACY
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
int lockf(int, int, off_t) @trusted;
int nice(int) @trusted;
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
int setpgrp(pid_t, pid_t) @trusted;
int setregid(gid_t, gid_t) @trusted;
int setreuid(uid_t, uid_t) @trusted;
- void swab(in void*, void*, ssize_t);
+ void swab(const scope void*, void*, ssize_t);
void sync() @trusted;
- int truncate(in char*, off_t);
+ int truncate(const scope char*, off_t);
useconds_t ualarm(useconds_t, useconds_t) @trusted;
int usleep(useconds_t) @trusted;
pid_t vfork();
}
else version (OpenBSD)
{
- char* crypt(in char*, in char*);
+ char* crypt(const scope char*, const scope char*);
//char* ctermid(char*);
//void encrypt(ref char[64], int) @trusted;
int fchdir(int) @trusted;
@@ -2562,24 +2563,24 @@ else version (OpenBSD)
pid_t getpgid(pid_t) @trusted;
pid_t getsid(pid_t) @trusted;
char* getwd(char*);
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
int lockf(int, int, off_t) @trusted;
int nice(int) @trusted;
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
int setpgrp(pid_t, pid_t) @trusted;
int setregid(gid_t, gid_t) @trusted;
int setreuid(uid_t, uid_t) @trusted;
- void swab(in void*, void*, ssize_t);
+ void swab(const scope void*, void*, ssize_t);
void sync() @trusted;
- int truncate(in char*, off_t);
+ int truncate(const scope char*, off_t);
useconds_t ualarm(useconds_t, useconds_t) @trusted;
int usleep(useconds_t) @trusted;
pid_t vfork();
}
else version (DragonFlyBSD)
{
- char* crypt(in char*, in char*);
+ char* crypt(const scope char*, const scope char*);
//char* ctermid(char*);
void encrypt(ref char[64], int) @trusted;
int fchdir(int) @trusted;
@@ -2587,17 +2588,17 @@ else version (DragonFlyBSD)
int getpgid(pid_t) @trusted;
int getsid(pid_t) @trusted;
char* getwd(char*); // LEGACY
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
int lockf(int, int, off_t) @trusted;
int nice(int) @trusted;
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
int setpgrp(pid_t, pid_t) @trusted;
int setregid(gid_t, gid_t) @trusted;
int setreuid(uid_t, uid_t) @trusted;
- void swab(in void*, void*, ssize_t);
+ void swab(const scope void*, void*, ssize_t);
void sync() @trusted;
- int truncate(in char*, off_t);
+ int truncate(const scope char*, off_t);
useconds_t ualarm(useconds_t, useconds_t) @trusted;
int usleep(useconds_t) @trusted;
pid_t vfork();
@@ -2606,21 +2607,21 @@ else version (CRuntime_Bionic)
{
int fchdir(int) @trusted;
pid_t getpgid(pid_t) @trusted;
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
int nice(int) @trusted;
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
int setpgrp() @trusted;
int setregid(gid_t, gid_t) @trusted;
int setreuid(uid_t, uid_t) @trusted;
int sync() @trusted;
- int truncate(in char*, off_t);
+ int truncate(const scope char*, off_t);
int usleep(c_ulong) @trusted;
pid_t vfork();
}
else version (Solaris)
{
- char* crypt(in char*, in char*);
+ char* crypt(const scope char*, const scope char*);
char* ctermid(char*);
void encrypt(ref char[64], int);
int fchdir(int);
@@ -2628,12 +2629,12 @@ else version (Solaris)
pid_t getpgid(pid_t);
pid_t getsid(pid_t);
char* getwd(char*); // LEGACY
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
int nice(int);
pid_t setpgrp();
int setregid(gid_t, gid_t);
int setreuid(uid_t, uid_t);
- void swab(in void*, void*, ssize_t);
+ void swab(const scope void*, void*, ssize_t);
void sync();
useconds_t ualarm(useconds_t, useconds_t);
int usleep(useconds_t);
@@ -2647,10 +2648,10 @@ else version (Solaris)
ssize_t pread(int, void*, size_t, off_t);
alias pread pread64;
- ssize_t pwrite(int, in void*, size_t, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
alias pwrite pwrite64;
- int truncate(in char*, off_t);
+ int truncate(const scope char*, off_t);
alias truncate truncate64;
}
else
@@ -2663,24 +2664,24 @@ else version (Solaris)
ssize_t pread64(int, void*, size_t, off64_t);
alias pread64 pread;
- ssize_t pwrite64(int, in void*, size_t, off_t);
+ ssize_t pwrite64(int, const scope void*, size_t, off_t);
alias pwrite64 pwrite;
- int truncate64(in char*, off_t);
+ int truncate64(const scope char*, off_t);
alias truncate64 truncate;
}
else
{
int lockf(int, int, off_t);
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
- int truncate(in char*, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
+ int truncate(const scope char*, off_t);
}
}
}
else version (CRuntime_UClibc)
{
- char* crypt(in char*, in char*);
+ char* crypt(const scope char*, const scope char*);
char* ctermid(char*);
void encrypt(ref char[64], int) @trusted;
int fchdir(int) @trusted;
@@ -2688,12 +2689,12 @@ else version (CRuntime_UClibc)
pid_t getpgid(pid_t) @trusted;
pid_t getsid(pid_t) @trusted;
char* getwd(char*); // LEGACY
- int lchown(in char*, uid_t, gid_t);
+ int lchown(const scope char*, uid_t, gid_t);
int nice(int) @trusted;
pid_t setpgrp() @trusted;
int setregid(gid_t, gid_t) @trusted;
int setreuid(uid_t, uid_t) @trusted;
- void swab(in void*, void*, ssize_t);
+ void swab(const scope void*, void*, ssize_t);
void sync() @trusted;
useconds_t ualarm(useconds_t, useconds_t) @trusted;
int usleep(useconds_t) @trusted;
@@ -2707,17 +2708,65 @@ else version (CRuntime_UClibc)
ssize_t pread64(int, void*, size_t, off_t);
alias pread64 pread;
- ssize_t pwrite64(int, in void*, size_t, off_t);
+ ssize_t pwrite64(int, const scope void*, size_t, off_t);
alias pwrite64 pwrite;
- int truncate64(in char*, off_t);
+ int truncate64(const scope char*, off_t);
alias truncate64 truncate;
}
else
{
int lockf(int, int, off_t) @trusted;
ssize_t pread(int, void*, size_t, off_t);
- ssize_t pwrite(int, in void*, size_t, off_t);
- int truncate(in char*, off_t);
+ ssize_t pwrite(int, const scope void*, size_t, off_t);
+ int truncate(const scope char*, off_t);
}
}
+
+// Non-standard definition to access user process environment
+version (CRuntime_Glibc)
+{
+ extern __gshared const char** environ;
+}
+else version (Darwin)
+{
+ extern (D) @property const(char**) environ()()
+ {
+ pragma (inline, true);
+ import core.sys.darwin.crt_externs : _NSGetEnviron;
+ return *_NSGetEnviron();
+ }
+}
+else version (FreeBSD)
+{
+ extern __gshared const char** environ;
+}
+else version (NetBSD)
+{
+ extern __gshared const char** environ;
+}
+else version (OpenBSD)
+{
+ extern __gshared const char** environ;
+}
+else version (DragonFlyBSD)
+{
+ extern __gshared const char** environ;
+}
+else version (CRuntime_Bionic)
+{
+ extern __gshared const char** environ;
+}
+else version (CRuntime_Musl)
+{
+ extern __gshared const char** environ;
+}
+else version (Solaris)
+{
+ extern __gshared const char** environ;
+}
+else version (CRuntime_UClibc)
+{
+ extern __gshared const char** __environ;
+ alias environ = __environ;
+}
diff --git a/libphobos/libdruntime/core/sys/posix/utime.d b/libphobos/libdruntime/core/sys/posix/utime.d
index ae54c20..66aea58 100644
--- a/libphobos/libdruntime/core/sys/posix/utime.d
+++ b/libphobos/libdruntime/core/sys/posix/utime.d
@@ -14,7 +14,7 @@
*/
module core.sys.posix.utime;
-private import core.sys.posix.config;
+import core.sys.posix.config;
public import core.sys.posix.sys.types; // for time_t
version (OSX)
@@ -30,6 +30,7 @@ version (Posix):
extern (C):
nothrow:
@nogc:
+@system:
//
// Required
@@ -41,7 +42,7 @@ struct utimbuf
time_t modtime;
}
-int utime(in char*, in utimbuf*);
+int utime(const scope char*, const scope utimbuf*);
*/
version (CRuntime_Glibc)
@@ -52,7 +53,7 @@ version (CRuntime_Glibc)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (CRuntime_Musl)
{
@@ -62,7 +63,7 @@ else version (CRuntime_Musl)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (Darwin)
{
@@ -72,7 +73,7 @@ else version (Darwin)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (FreeBSD)
{
@@ -82,7 +83,7 @@ else version (FreeBSD)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (NetBSD)
{
@@ -92,7 +93,7 @@ else version (NetBSD)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (OpenBSD)
{
@@ -102,7 +103,7 @@ else version (OpenBSD)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (DragonFlyBSD)
{
@@ -112,7 +113,7 @@ else version (DragonFlyBSD)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (Solaris)
{
@@ -122,7 +123,7 @@ else version (Solaris)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (CRuntime_Bionic)
{
@@ -132,7 +133,7 @@ else version (CRuntime_Bionic)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
else version (CRuntime_UClibc)
{
@@ -142,5 +143,5 @@ else version (CRuntime_UClibc)
time_t modtime;
}
- int utime(in char*, in utimbuf*);
+ int utime(const scope char*, const scope utimbuf*);
}
diff --git a/libphobos/libdruntime/core/sys/solaris/dlfcn.d b/libphobos/libdruntime/core/sys/solaris/dlfcn.d
index d23bdaa..4f69bfd 100644
--- a/libphobos/libdruntime/core/sys/solaris/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/solaris/dlfcn.d
@@ -39,7 +39,7 @@ enum
alias c_ulong Lmid_t;
-void* dlmopen(Lmid_t, in char*, int);
+void* dlmopen(Lmid_t, const scope char*, int);
enum
{
@@ -56,7 +56,7 @@ enum
RTLD_CONFSET = 0x10000,
}
-int dldump(in char*, in char*, int);
+int dldump(const scope char*, const scope char*, int);
struct Dl_info
{
diff --git a/libphobos/libdruntime/core/sys/solaris/err.d b/libphobos/libdruntime/core/sys/solaris/err.d
new file mode 100644
index 0000000..f787643
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/solaris/err.d
@@ -0,0 +1,23 @@
+/**
+ * D header file for Solaris err.h.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Ernesto Castellotti
+ */
+module core.sys.solaris.err;
+import core.stdc.stdarg : va_list;
+
+version (Solaris):
+extern (C):
+nothrow:
+@nogc:
+
+void err(int eval, scope const char* fmt, ...);
+void errx(int eval, scope const char* fmt, ...);
+void warn(scope const char* fmt, ...);
+void warnx(scope const char* fmt, ...);
+void verr(int eval, scope const char* fmt, va_list args);
+void verrx(int eval, scope const char* fmt, va_list args);
+void vwarn(scope const char* fmt, va_list args);
+void vwarnx(scope const char* fmt, va_list args);
diff --git a/libphobos/libdruntime/core/sys/solaris/libelf.d b/libphobos/libdruntime/core/sys/solaris/libelf.d
index d0e6aa7..a8d3c1f 100644
--- a/libphobos/libdruntime/core/sys/solaris/libelf.d
+++ b/libphobos/libdruntime/core/sys/solaris/libelf.d
@@ -131,7 +131,7 @@ int elf_getshnum(Elf*, size_t*);
int elf_getshdrnum(Elf*, size_t*);
int elf_getshstrndx(Elf*, size_t*);
int elf_getshdrstrndx(Elf*, size_t*);
-c_ulong elf_hash(in char*);
+c_ulong elf_hash(const scope char*);
uint elf_sys_encoding();
long elf32_checksum(Elf*);
Elf_Kind elf_kind(Elf*);
@@ -149,8 +149,8 @@ char* elf_rawfile(Elf*, size_t*);
char* elf_strptr(Elf*, size_t, size_t);
off_t elf_update(Elf*, Elf_Cmd);
uint elf_version(uint);
-Elf_Data* elf32_xlatetof(Elf_Data*, in Elf_Data*, uint);
-Elf_Data* elf32_xlatetom(Elf_Data*, in Elf_Data*, uint);
+Elf_Data* elf32_xlatetof(Elf_Data*, const scope Elf_Data*, uint);
+Elf_Data* elf32_xlatetom(Elf_Data*, const scope Elf_Data*, uint);
version (D_LP64)
{
@@ -161,6 +161,6 @@ Elf64_Shdr* elf64_getshdr(Elf_Scn*);
long elf64_checksum(Elf*);
Elf64_Ehdr* elf64_newehdr(Elf*);
Elf64_Phdr* elf64_newphdr(Elf*, size_t);
-Elf_Data* elf64_xlatetof(Elf_Data*, in Elf_Data*, uint);
-Elf_Data* elf64_xlatetom(Elf_Data*, in Elf_Data*, uint);
-} \ No newline at end of file
+Elf_Data* elf64_xlatetof(Elf_Data*, const scope Elf_Data*, uint);
+Elf_Data* elf64_xlatetom(Elf_Data*, const scope Elf_Data*, uint);
+}
diff --git a/libphobos/libdruntime/core/sys/solaris/link.d b/libphobos/libdruntime/core/sys/solaris/link.d
index 2d908b1..1459783 100644
--- a/libphobos/libdruntime/core/sys/solaris/link.d
+++ b/libphobos/libdruntime/core/sys/solaris/link.d
@@ -18,21 +18,21 @@ import core.sys.solaris.sys.link;
uint ld_version(uint);
void ld_input_done(uint*);
-void ld_start(in char*, in Elf32_Half, in char*);
+void ld_start(const scope char*, const Elf32_Half, const scope char*);
void ld_atexit(int);
-void ld_open(in char**, in char**, int*, int, Elf**, Elf*, size_t, in Elf_Kind);
-void ld_file(in char*, in Elf_Kind, int, Elf*);
-void ld_input_section(in char*, Elf32_Shdr**, Elf32_Word, Elf_Data*, Elf*, uint*);
-void ld_section(in char*, Elf32_Shdr*, Elf32_Word, Elf_Data*, Elf*);
+void ld_open(const scope char**, const scope char**, int*, int, Elf**, Elf*, size_t, const Elf_Kind);
+void ld_file(const scope char*, const Elf_Kind, int, Elf*);
+void ld_input_section(const scope char*, Elf32_Shdr**, Elf32_Word, Elf_Data*, Elf*, uint*);
+void ld_section(const scope char*, Elf32_Shdr*, Elf32_Word, Elf_Data*, Elf*);
version (D_LP64)
{
- void ld_start64(in char*, in Elf64_Half, in char*);
+ void ld_start64(const scope char*, const Elf64_Half, const scope char*);
void ld_atexit64(int);
- void ld_open64(in char**, in char**, int*, int, Elf**, Elf*, size_t, in Elf_Kind);
- void ld_file64(in char*, in Elf_Kind, int, Elf*);
- void ld_input_section64(in char*, Elf64_Shdr**, Elf64_Word, Elf_Data*, Elf*, uint*);
- void ld_section64(in char*, Elf64_Shdr*, Elf64_Word, Elf_Data*, Elf*);
+ void ld_open64(const scope char**, const scope char**, int*, int, Elf**, Elf*, size_t, const Elf_Kind);
+ void ld_file64(const scope char*, const Elf_Kind, int, Elf*);
+ void ld_input_section64(const scope char*, Elf64_Shdr**, Elf64_Word, Elf_Data*, Elf*, uint*);
+ void ld_section64(const scope char*, Elf64_Shdr*, Elf64_Word, Elf_Data*, Elf*);
}
enum LD_SUP_VNONE = 0;
@@ -130,19 +130,19 @@ else
uint la_version(uint);
void la_activity(uintptr_t*, uint);
void la_preinit(uintptr_t*);
-char* la_objsearch(in char*, uintptr_t*, uint);
+char* la_objsearch(const scope char*, uintptr_t*, uint);
uint la_objopen(Link_map*, Lmid_t, uintptr_t*);
uint la_objclose(uintptr_t*);
-int la_objfilter(uintptr_t*, in char*, uintptr_t*, uint);
+int la_objfilter(uintptr_t*, const scope char*, uintptr_t*, uint);
version (D_LP64)
{
uintptr_t la_amd64_pltenter(Elf64_Sym*, uint, uintptr_t*, uintptr_t*,
- La_amd64_regs*, uint*, in char*);
- uintptr_t la_symbind64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uint*, in char*);
+ La_amd64_regs*, uint*, const scope char*);
+ uintptr_t la_symbind64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uint*, const scope char*);
uintptr_t la_sparcv9_pltenter(Elf64_Sym*, uint, uintptr_t*, uintptr_t*,
- La_sparcv9_regs*, uint*, in char*);
- uintptr_t la_pltexit64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uintptr_t, in char*);
+ La_sparcv9_regs*, uint*, const scope char*);
+ uintptr_t la_pltexit64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uintptr_t, const scope char*);
}
else
{
@@ -172,7 +172,7 @@ struct dl_phdr_info
uint64_t dlpi_subs;
size_t dlpi_tls_modid; // since Solaris 11.5
void* dlpi_tls_data; // since Solaris 11.5
-};
+}
private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;
private alias extern(C) int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc;
diff --git a/libphobos/libdruntime/core/sys/solaris/stdlib.d b/libphobos/libdruntime/core/sys/solaris/stdlib.d
new file mode 100644
index 0000000..0b6fffe
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/solaris/stdlib.d
@@ -0,0 +1,17 @@
+/**
+ * D header file for Solaris stdlib.h.
+ *
+ * Copyright: Copyright © 2021, The D Language Foundation
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Iain Buclaw
+ */
+module core.sys.solaris.stdlib;
+public import core.sys.posix.stdlib;
+
+version (Solaris):
+extern (C):
+nothrow:
+@nogc:
+
+const(char)* getprogname();
+void setprogname(scope const char* name);
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d b/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d
index 2d6fda0..81d0234 100644
--- a/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d
@@ -178,4 +178,4 @@ else
enum M_PLT_RESERVSZ = M32_PLT_RESERVSZ;
enum M_GOT_ENTSIZE = M32_GOT_ENTSIZE;
enum M_GOT_MAXSMALL = M32_GOT_MAXSMALL;
-} \ No newline at end of file
+}
diff --git a/libphobos/libdruntime/core/sys/windows/accctrl.d b/libphobos/libdruntime/core/sys/windows/accctrl.d
index e28f5df..77bc184 100644
--- a/libphobos/libdruntime/core/sys/windows/accctrl.d
+++ b/libphobos/libdruntime/core/sys/windows/accctrl.d
@@ -12,7 +12,7 @@ version (Windows):
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
+import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
// FIXME: check types and grouping of constants
// FIXME: check Windows version support
diff --git a/libphobos/libdruntime/core/sys/windows/aclapi.d b/libphobos/libdruntime/core/sys/windows/aclapi.d
index 762a4db..1e75d3f 100644
--- a/libphobos/libdruntime/core/sys/windows/aclapi.d
+++ b/libphobos/libdruntime/core/sys/windows/aclapi.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.aclapi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "advapi32");
diff --git a/libphobos/libdruntime/core/sys/windows/aclui.d b/libphobos/libdruntime/core/sys/windows/aclui.d
index 6000375..6ae37c6 100644
--- a/libphobos/libdruntime/core/sys/windows/aclui.d
+++ b/libphobos/libdruntime/core/sys/windows/aclui.d
@@ -9,16 +9,17 @@
*/
module core.sys.windows.aclui;
version (Windows):
+@system:
pragma(lib, "aclui");
-private import core.sys.windows.w32api;
+import core.sys.windows.w32api;
/*
static assert (_WIN32_WINNT >= 0x500,
"core.sys.windows.aclui is available only if version Windows2000, WindowsXP, Windows2003 "
"or WindowsVista is set");
*/
import core.sys.windows.accctrl, core.sys.windows.commctrl, core.sys.windows.objbase;
-private import core.sys.windows.basetyps, core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.windef,
+import core.sys.windows.basetyps, core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.windef,
core.sys.windows.winuser;
diff --git a/libphobos/libdruntime/core/sys/windows/basetsd.d b/libphobos/libdruntime/core/sys/windows/basetsd.d
index 8efacd0..97983c6 100644
--- a/libphobos/libdruntime/core/sys/windows/basetsd.d
+++ b/libphobos/libdruntime/core/sys/windows/basetsd.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.basetsd;
version (Windows):
+@system:
/* This template is used in these modules to declare constant pointer types,
* in order to support both D 1.x and 2.x.
diff --git a/libphobos/libdruntime/core/sys/windows/basetyps.d b/libphobos/libdruntime/core/sys/windows/basetyps.d
index bef4307..abe312e 100644
--- a/libphobos/libdruntime/core/sys/windows/basetyps.d
+++ b/libphobos/libdruntime/core/sys/windows/basetyps.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.basetyps;
version (Windows):
+@system:
-private import core.sys.windows.windef, core.sys.windows.basetsd;
+import core.sys.windows.windef, core.sys.windows.basetsd;
align(1) struct GUID { // size is 16
align(1):
diff --git a/libphobos/libdruntime/core/sys/windows/cguid.d b/libphobos/libdruntime/core/sys/windows/cguid.d
index b6db658..8d67b88 100644
--- a/libphobos/libdruntime/core/sys/windows/cguid.d
+++ b/libphobos/libdruntime/core/sys/windows/cguid.d
@@ -9,5 +9,5 @@
module core.sys.windows.cguid;
version (Windows):
-private import core.sys.windows.basetyps;
+import core.sys.windows.basetyps;
diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d
index 34aeccc..6935dd9 100644
--- a/libphobos/libdruntime/core/sys/windows/com.d
+++ b/libphobos/libdruntime/core/sys/windows/com.d
@@ -1,5 +1,6 @@
module core.sys.windows.com;
version (Windows):
+@system:
pragma(lib,"uuid");
@@ -38,16 +39,16 @@ public import core.sys.windows.winerror :
RPC_E_CHANGED_MODE;
public import core.sys.windows.wtypes :
- OLECHAR, LPOLESTR, LPCOLESTR;
+ CLSCTX, OLECHAR, LPOLESTR, LPCOLESTR;
-alias CLSCTX_INPROC_SERVER = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVER ;
-alias CLSCTX_INPROC_HANDLER = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLER ;
-alias CLSCTX_LOCAL_SERVER = core.sys.windows.wtypes.CLSCTX.CLSCTX_LOCAL_SERVER ;
-alias CLSCTX_INPROC_SERVER16 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVER16 ;
-alias CLSCTX_REMOTE_SERVER = core.sys.windows.wtypes.CLSCTX.CLSCTX_REMOTE_SERVER ;
-alias CLSCTX_INPROC_HANDLER16 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLER16 ;
-alias CLSCTX_INPROC_SERVERX86 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVERX86 ;
-alias CLSCTX_INPROC_HANDLERX86 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLERX86;
+alias CLSCTX_INPROC_SERVER = CLSCTX.CLSCTX_INPROC_SERVER ;
+alias CLSCTX_INPROC_HANDLER = CLSCTX.CLSCTX_INPROC_HANDLER ;
+alias CLSCTX_LOCAL_SERVER = CLSCTX.CLSCTX_LOCAL_SERVER ;
+alias CLSCTX_INPROC_SERVER16 = CLSCTX.CLSCTX_INPROC_SERVER16 ;
+alias CLSCTX_REMOTE_SERVER = CLSCTX.CLSCTX_REMOTE_SERVER ;
+alias CLSCTX_INPROC_HANDLER16 = CLSCTX.CLSCTX_INPROC_HANDLER16 ;
+alias CLSCTX_INPROC_SERVERX86 = CLSCTX.CLSCTX_INPROC_SERVERX86 ;
+alias CLSCTX_INPROC_HANDLERX86 = CLSCTX.CLSCTX_INPROC_HANDLERX86;
alias COINIT_APARTMENTTHREADED = COINIT.COINIT_APARTMENTTHREADED;
alias COINIT_MULTITHREADED = COINIT.COINIT_MULTITHREADED ;
@@ -56,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
public import core.sys.windows.uuid;
-extern (System)
+extern (Windows)
{
class ComObject : IUnknown
{
-extern (System):
+extern (Windows):
HRESULT QueryInterface(const(IID)* riid, void** ppv)
{
if (*riid == IID_IUnknown)
diff --git a/libphobos/libdruntime/core/sys/windows/comcat.d b/libphobos/libdruntime/core/sys/windows/comcat.d
index e6ef421..cb45ff5 100644
--- a/libphobos/libdruntime/core/sys/windows/comcat.d
+++ b/libphobos/libdruntime/core/sys/windows/comcat.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.comcat;
version (Windows):
+@system:
import core.sys.windows.ole2;
-private import core.sys.windows.basetyps, core.sys.windows.cguid, core.sys.windows.objbase, core.sys.windows.unknwn,
+import core.sys.windows.basetyps, core.sys.windows.cguid, core.sys.windows.objbase, core.sys.windows.unknwn,
core.sys.windows.windef, core.sys.windows.wtypes;
alias IEnumGUID LPENUMGUID;
diff --git a/libphobos/libdruntime/core/sys/windows/commctrl.d b/libphobos/libdruntime/core/sys/windows/commctrl.d
index bedf365..f008e75 100644
--- a/libphobos/libdruntime/core/sys/windows/commctrl.d
+++ b/libphobos/libdruntime/core/sys/windows/commctrl.d
@@ -8,13 +8,14 @@
*/
module core.sys.windows.commctrl;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "comctl32");
-private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser;
-private import core.sys.windows.winbase; // for SYSTEMTIME
-private import core.sys.windows.objfwd; // for LPSTREAM
+import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser;
+import core.sys.windows.winbase; // for SYSTEMTIME
+import core.sys.windows.objfwd; // for LPSTREAM
import core.sys.windows.prsht;
@@ -3898,7 +3899,7 @@ static if (_WIN32_WINNT >= 0x600) {
{
int iItem;
int iGroup;
- };
+ }
alias LVITEMINDEX* PLVITEMINDEX;
struct LVFOOTERINFO
diff --git a/libphobos/libdruntime/core/sys/windows/commdlg.d b/libphobos/libdruntime/core/sys/windows/commdlg.d
index c113f9e..1e8057c 100644
--- a/libphobos/libdruntime/core/sys/windows/commdlg.d
+++ b/libphobos/libdruntime/core/sys/windows/commdlg.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.commdlg;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "comdlg32");
-private import core.sys.windows.w32api;
+import core.sys.windows.w32api;
import core.sys.windows.windef, core.sys.windows.winuser;
import core.sys.windows.wingdi; // for LPLOGFONTA
diff --git a/libphobos/libdruntime/core/sys/windows/cpl.d b/libphobos/libdruntime/core/sys/windows/cpl.d
index 823a76b..b040aad 100644
--- a/libphobos/libdruntime/core/sys/windows/cpl.d
+++ b/libphobos/libdruntime/core/sys/windows/cpl.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.cpl;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.windef, core.sys.windows.winuser;
+import core.sys.windows.windef, core.sys.windows.winuser;
enum : uint {
WM_CPL_LAUNCH = WM_USER + 1000,
diff --git a/libphobos/libdruntime/core/sys/windows/cplext.d b/libphobos/libdruntime/core/sys/windows/cplext.d
index 89d892e..c9452fa 100644
--- a/libphobos/libdruntime/core/sys/windows/cplext.d
+++ b/libphobos/libdruntime/core/sys/windows/cplext.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.cplext;
version (Windows):
+@system:
enum : uint {
CPLPAGE_MOUSE_BUTTONS = 1,
diff --git a/libphobos/libdruntime/core/sys/windows/custcntl.d b/libphobos/libdruntime/core/sys/windows/custcntl.d
index 3f5284f..ccfc7ca 100644
--- a/libphobos/libdruntime/core/sys/windows/custcntl.d
+++ b/libphobos/libdruntime/core/sys/windows/custcntl.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.custcntl;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
// FIXME: check type
enum CCF_NOTEXT = 1;
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 44c1957..9848fb9 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -11,13 +11,14 @@
module core.sys.windows.dbghelp;
version (Windows):
+@system:
import core.sys.windows.winbase /+: FreeLibrary, GetProcAddress, LoadLibraryA+/;
import core.sys.windows.windef;
public import core.sys.windows.dbghelp_types;
-extern(System)
+extern(Windows)
{
alias BOOL function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
@@ -36,7 +37,7 @@ extern(System)
alias DWORD64 function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func;
alias BOOL function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULEA64 *ModuleInfo) SymGetModuleInfo64Func;
alias BOOL function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOLA64 *Symbol) SymGetSymFromAddr64Func;
- alias DWORD function(PCTSTR DecoratedName, PTSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc;
+ alias DWORD function(PCSTR DecoratedName, PSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc;
alias DWORD64 function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func;
alias BOOL function(HANDLE HProcess, PTSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;
alias BOOL function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func;
@@ -80,6 +81,7 @@ struct DbgHelp
sm_inst.SymGetModuleBase64 = cast(SymGetModuleBase64Func) GetProcAddress(sm_hndl,"SymGetModuleBase64");
sm_inst.SymGetModuleInfo64 = cast(SymGetModuleInfo64Func) GetProcAddress(sm_hndl,"SymGetModuleInfo64");
sm_inst.SymGetSymFromAddr64 = cast(SymGetSymFromAddr64Func) GetProcAddress(sm_hndl,"SymGetSymFromAddr64");
+ sm_inst.UnDecorateSymbolName = cast(UnDecorateSymbolNameFunc) GetProcAddress(sm_hndl,"UnDecorateSymbolName");
sm_inst.SymLoadModule64 = cast(SymLoadModule64Func) GetProcAddress(sm_hndl,"SymLoadModule64");
sm_inst.SymGetSearchPath = cast(SymGetSearchPathFunc) GetProcAddress(sm_hndl,"SymGetSearchPath");
sm_inst.SymUnloadModule64 = cast(SymUnloadModule64Func) GetProcAddress(sm_hndl,"SymUnloadModule64");
@@ -88,8 +90,8 @@ struct DbgHelp
assert( sm_inst.SymInitialize && sm_inst.SymCleanup && sm_inst.StackWalk64 && sm_inst.SymGetOptions &&
sm_inst.SymSetOptions && sm_inst.SymFunctionTableAccess64 && sm_inst.SymGetLineFromAddr64 &&
sm_inst.SymGetModuleBase64 && sm_inst.SymGetModuleInfo64 && sm_inst.SymGetSymFromAddr64 &&
- sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath && sm_inst.SymUnloadModule64 &&
- sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion);
+ sm_inst.UnDecorateSymbolName && sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath &&
+ sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion);
return &sm_inst;
}
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp_types.d b/libphobos/libdruntime/core/sys/windows/dbghelp_types.d
index f75f98b..64477df 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp_types.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp_types.d
@@ -11,6 +11,7 @@
module core.sys.windows.dbghelp_types;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
diff --git a/libphobos/libdruntime/core/sys/windows/dbt.d b/libphobos/libdruntime/core/sys/windows/dbt.d
index c43f789..a591152 100644
--- a/libphobos/libdruntime/core/sys/windows/dbt.d
+++ b/libphobos/libdruntime/core/sys/windows/dbt.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.dbt;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
diff --git a/libphobos/libdruntime/core/sys/windows/dde.d b/libphobos/libdruntime/core/sys/windows/dde.d
index 168cbd1..0e06227 100644
--- a/libphobos/libdruntime/core/sys/windows/dde.d
+++ b/libphobos/libdruntime/core/sys/windows/dde.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.dde;
version (Windows):
+@system:
pragma(lib, "user32");
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum : uint {
WM_DDE_FIRST = 0x03E0,
diff --git a/libphobos/libdruntime/core/sys/windows/ddeml.d b/libphobos/libdruntime/core/sys/windows/ddeml.d
index a0cce30..209772f 100644
--- a/libphobos/libdruntime/core/sys/windows/ddeml.d
+++ b/libphobos/libdruntime/core/sys/windows/ddeml.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.ddeml;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "user32");
-private import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winnt;
+import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winnt;
enum : int {
CP_WINANSI = 1004,
diff --git a/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d b/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d
index 4c0db44..7b412c1 100644
--- a/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d
+++ b/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.dhcpcsdk;
version (Windows):
+@system:
-private import core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.windef;
/*static assert (_WIN32_WINNT >= 0x500,
"core.sys.windows.dhcpcsdk is available only if version Windows2000, WindowsXP, Windows2003
diff --git a/libphobos/libdruntime/core/sys/windows/dlgs.d b/libphobos/libdruntime/core/sys/windows/dlgs.d
index f9306d6..796f027 100644
--- a/libphobos/libdruntime/core/sys/windows/dlgs.d
+++ b/libphobos/libdruntime/core/sys/windows/dlgs.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.dlgs;
version (Windows):
+@system:
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum : ushort {
FILEOPENORD = 1536,
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index c3c4db3..cc2422b 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -14,6 +14,7 @@
*/
module core.sys.windows.dll;
version (Windows):
+@system:
import core.sys.windows.winbase;
import core.sys.windows.winnt;
@@ -30,17 +31,7 @@ public import core.sys.windows.threadaux;
// not access tls_array[tls_index] as needed for thread local _tlsstart and _tlsend
extern (C)
{
- version (MinGW)
- {
- extern __gshared void* _tls_start;
- extern __gshared void* _tls_end;
- extern __gshared void* __xl_a;
-
- alias _tls_start _tlsstart;
- alias _tls_end _tlsend;
- alias __xl_a _tls_callbacks_a;
- }
- else version (Win32)
+ version (Win32)
{
version (CRuntime_DigitalMars)
{
@@ -68,11 +59,11 @@ extern (C) // rt.minfo
}
private:
-version (Win32)
-{
struct dll_aux
{
// don't let symbols leak into other modules
+version (Win32)
+{
struct LdrpTlsListEntry
{
LdrpTlsListEntry* next;
@@ -238,6 +229,7 @@ struct dll_aux
// let the old array leak, in case a oncurrent thread is still relying on it
return true;
}
+} // Win32
alias bool BOOLEAN;
@@ -254,7 +246,8 @@ struct dll_aux
LIST_ENTRY* prev;
}
- // the following structures can be found here: http://undocumented.ntinternals.net/
+ // the following structures can be found here:
+ // https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/ldr_data_table_entry.htm
// perhaps this should be same as LDR_DATA_TABLE_ENTRY, which is introduced with PEB_LDR_DATA
struct LDR_MODULE
{
@@ -267,10 +260,22 @@ struct dll_aux
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
- SHORT LoadCount;
+ SHORT LoadCount; // obsolete after Version 6.1
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
+ PVOID EntryPointActivationContext;
+ PVOID PatchInformation;
+ LDR_DDAG_NODE *DdagNode; // starting with Version 6.2
+ }
+
+ struct LDR_DDAG_NODE
+ {
+ LIST_ENTRY Modules;
+ void* ServiceTagList; // LDR_SERVICE_TAG_RECORD
+ ULONG LoadCount;
+ ULONG ReferenceCount; // Version 10: ULONG LoadWhileUnloadingCount;
+ ULONG DependencyCount; // Version 10: ULONG LowestLink;
}
struct PEB_LDR_DATA
@@ -283,7 +288,7 @@ struct dll_aux
LIST_ENTRY InInitializationOrderModuleList;
}
- static LDR_MODULE* findLdrModule( HINSTANCE hInstance, void** peb ) nothrow
+ static LDR_MODULE* findLdrModule( HINSTANCE hInstance, void** peb ) nothrow @nogc
{
PEB_LDR_DATA* ldrData = cast(PEB_LDR_DATA*) peb[3];
LIST_ENTRY* root = &ldrData.InLoadOrderModuleList;
@@ -307,7 +312,6 @@ struct dll_aux
return true;
}
}
-}
public:
/* *****************************************************
@@ -374,6 +378,78 @@ bool dll_fixTLS( HINSTANCE hInstance, void* tlsstart, void* tlsend, void* tls_ca
}
}
+private extern (Windows) ULONGLONG VerSetConditionMask(ULONGLONG, DWORD, BYTE) nothrow @nogc;
+
+private bool isWindows8OrLater() nothrow @nogc
+{
+ OSVERSIONINFOEXW osvi;
+ osvi.dwOSVersionInfoSize = osvi.sizeof;
+ DWORDLONG dwlConditionMask = VerSetConditionMask(
+ VerSetConditionMask(
+ VerSetConditionMask(
+ 0, VER_MAJORVERSION, VER_GREATER_EQUAL),
+ VER_MINORVERSION, VER_GREATER_EQUAL),
+ VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+
+ osvi.dwMajorVersion = 6;
+ osvi.dwMinorVersion = 2;
+ osvi.wServicePackMajor = 0;
+
+ return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
+}
+
+/* *****************************************************
+ * Get the process reference count for the given DLL handle
+ * Params:
+ * hInstance = DLL instance handle
+ * Returns:
+ * the reference count for the DLL in the current process,
+ * -1 if the DLL is implicitely loaded with the process
+ * or -2 if the DLL handle is invalid
+ */
+int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
+{
+ void** peb;
+ version (Win64)
+ {
+ version (GNU_InlineAsm)
+ {
+ asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" (peb); }
+ }
+ else
+ {
+ asm pure nothrow @nogc
+ {
+ mov RAX, 0x60;
+ mov RAX,GS:[RAX];
+ mov peb, RAX;
+ }
+ }
+
+ }
+ else version (Win32)
+ {
+ version (GNU_InlineAsm)
+ {
+ asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" (peb); }
+ }
+ else
+ {
+ asm pure nothrow @nogc
+ {
+ mov EAX,FS:[0x30];
+ mov peb, EAX;
+ }
+ }
+ }
+ dll_aux.LDR_MODULE *ldrMod = dll_aux.findLdrModule( hInstance, peb );
+ if ( !ldrMod )
+ return -2; // not in module list, bail out
+ if (isWindows8OrLater())
+ return ldrMod.DdagNode.LoadCount;
+ return ldrMod.LoadCount;
+}
+
// fixup TLS storage, initialize runtime and attach to threads
// to be called from DllMain with reason DLL_PROCESS_ATTACH
bool dll_process_attach( HINSTANCE hInstance, bool attach_threads,
@@ -393,7 +469,7 @@ bool dll_process_attach( HINSTANCE hInstance, bool attach_threads,
// attach to all other threads
return enumProcessThreads(
function (uint id, void* context) {
- if ( !thread_findByAddr( id ) )
+ if ( !thread_findByAddr( id ) && !findLowLevelThread( id ) )
{
// if the OS has not prepared TLS for us, don't attach to the thread
if ( GetTlsDataAddress( id ) )
@@ -424,14 +500,22 @@ bool dll_process_attach( HINSTANCE hInstance, bool attach_threads = true )
// to be called from DllMain with reason DLL_PROCESS_DETACH
void dll_process_detach( HINSTANCE hInstance, bool detach_threads = true )
{
+ // notify core.thread.joinLowLevelThread that the DLL is about to be unloaded
+ thread_DLLProcessDetaching = true;
+
// detach from all other threads
if ( detach_threads )
enumProcessThreads(
- function (uint id, void* context) {
- if ( id != GetCurrentThreadId() && thread_findByAddr( id ) )
+ function (uint id, void* context)
+ {
+ if ( id != GetCurrentThreadId() )
{
- thread_moduleTlsDtor( id );
- thread_detachByAddr( id );
+ if ( auto t = thread_findByAddr( id ) )
+ {
+ thread_moduleTlsDtor( id );
+ if ( !t.isMainThread() )
+ thread_detachByAddr( id );
+ }
}
return true;
}, null );
@@ -450,9 +534,10 @@ bool dll_thread_attach( bool attach_thread = true, bool initTls = true )
{
// if the OS has not prepared TLS for us, don't attach to the thread
// (happened when running under x64 OS)
- if ( !GetTlsDataAddress( GetCurrentThreadId() ) )
+ auto tid = GetCurrentThreadId();
+ if ( !GetTlsDataAddress( tid ) )
return false;
- if ( !thread_findByAddr( GetCurrentThreadId() ) )
+ if ( !thread_findByAddr( tid ) && !findLowLevelThread( tid ) )
{
// only attach to thread and initalize it if it is not in the thread list (so it's not created by "new Thread")
if ( attach_thread )
diff --git a/libphobos/libdruntime/core/sys/windows/docobj.d b/libphobos/libdruntime/core/sys/windows/docobj.d
index 0be79d7..89d5936 100644
--- a/libphobos/libdruntime/core/sys/windows/docobj.d
+++ b/libphobos/libdruntime/core/sys/windows/docobj.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.docobj;
version (Windows):
+@system:
-private import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.objidl, core.sys.windows.oleidl,
+import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.objidl, core.sys.windows.oleidl,
core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
// FIXME: remove inherited methods from interface definitions
diff --git a/libphobos/libdruntime/core/sys/windows/errorrep.d b/libphobos/libdruntime/core/sys/windows/errorrep.d
index b44d703..2b22e37 100644
--- a/libphobos/libdruntime/core/sys/windows/errorrep.d
+++ b/libphobos/libdruntime/core/sys/windows/errorrep.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.errorrep;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.windef;
static assert (_WIN32_WINNT >= 0x501,
"core.sys.windows.errorrep is available only if version WindowsXP, Windows2003 "
diff --git a/libphobos/libdruntime/core/sys/windows/exdisp.d b/libphobos/libdruntime/core/sys/windows/exdisp.d
index 6b953bf..1153112 100644
--- a/libphobos/libdruntime/core/sys/windows/exdisp.d
+++ b/libphobos/libdruntime/core/sys/windows/exdisp.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.exdisp;
version (Windows):
+@system:
import core.sys.windows.docobj, core.sys.windows.oaidl, core.sys.windows.ocidl;
-private import core.sys.windows.basetyps, core.sys.windows.windef, core.sys.windows.wtypes;
+import core.sys.windows.basetyps, core.sys.windows.windef, core.sys.windows.wtypes;
enum BrowserNavConstants {
diff --git a/libphobos/libdruntime/core/sys/windows/httpext.d b/libphobos/libdruntime/core/sys/windows/httpext.d
index 5465234..781d7ce 100644
--- a/libphobos/libdruntime/core/sys/windows/httpext.d
+++ b/libphobos/libdruntime/core/sys/windows/httpext.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.httpext;
version (Windows):
+@system:
/* Comment from MinGW
httpext.h - Header for ISAPI extensions.
@@ -19,9 +20,9 @@ version (Windows):
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
-private import core.sys.windows.basetsd /+: DECLARE_HANDLE, HANDLE+/;
-private import core.sys.windows.windef /+: BOOL, CHAR, DWORD, LPBYTE, LPDWORD+/;
-private import core.sys.windows.winnt /+: LPCSTR, LPSTR, LPVOID, PVOID, VOID+/;
+import core.sys.windows.basetsd /+: DECLARE_HANDLE, HANDLE+/;
+import core.sys.windows.windef /+: BOOL, CHAR, DWORD, LPBYTE, LPDWORD+/;
+import core.sys.windows.winnt /+: LPCSTR, LPSTR, LPVOID, PVOID, VOID+/;
enum {
HSE_VERSION_MAJOR = 2,
diff --git a/libphobos/libdruntime/core/sys/windows/imagehlp.d b/libphobos/libdruntime/core/sys/windows/imagehlp.d
index b77ef76..f9edba1 100644
--- a/libphobos/libdruntime/core/sys/windows/imagehlp.d
+++ b/libphobos/libdruntime/core/sys/windows/imagehlp.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.imagehlp;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
@@ -18,7 +19,7 @@ version (ANSI) {} else version = Unicode;
as well provide it here.
*/
-private import core.sys.windows.winbase, core.sys.windows.windef;
+import core.sys.windows.winbase, core.sys.windows.windef;
// FIXME: check types of constants
diff --git a/libphobos/libdruntime/core/sys/windows/imm.d b/libphobos/libdruntime/core/sys/windows/imm.d
index 5a55d04..3ebab30 100644
--- a/libphobos/libdruntime/core/sys/windows/imm.d
+++ b/libphobos/libdruntime/core/sys/windows/imm.d
@@ -8,13 +8,14 @@
*/
module core.sys.windows.imm;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "imm32");
import core.sys.windows.windef, core.sys.windows.wingdi;
import core.sys.windows.winuser; // for the MFS_xxx enums.
-private import core.sys.windows.w32api;
+import core.sys.windows.w32api;
enum WM_CONVERTREQUESTEX = 0x108;
enum WM_IME_STARTCOMPOSITION = 0x10D;
diff --git a/libphobos/libdruntime/core/sys/windows/intshcut.d b/libphobos/libdruntime/core/sys/windows/intshcut.d
index 4070577..f2f44e1 100644
--- a/libphobos/libdruntime/core/sys/windows/intshcut.d
+++ b/libphobos/libdruntime/core/sys/windows/intshcut.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.intshcut;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.unknwn, core.sys.windows.windef;
+import core.sys.windows.unknwn, core.sys.windows.windef;
enum : SCODE {
E_FLAGS = 0x80041000,
diff --git a/libphobos/libdruntime/core/sys/windows/ipexport.d b/libphobos/libdruntime/core/sys/windows/ipexport.d
index c9fcbd3..b66aa26 100644
--- a/libphobos/libdruntime/core/sys/windows/ipexport.d
+++ b/libphobos/libdruntime/core/sys/windows/ipexport.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.ipexport;
version (Windows):
+@system:
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum size_t MAX_ADAPTER_NAME = 128;
diff --git a/libphobos/libdruntime/core/sys/windows/iphlpapi.d b/libphobos/libdruntime/core/sys/windows/iphlpapi.d
index 6dabd0b..313e40b 100644
--- a/libphobos/libdruntime/core/sys/windows/iphlpapi.d
+++ b/libphobos/libdruntime/core/sys/windows/iphlpapi.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.iphlpapi;
version (Windows):
+@system:
import core.sys.windows.ipexport, core.sys.windows.iprtrmib, core.sys.windows.iptypes;
-private import core.sys.windows.winbase, core.sys.windows.windef;
+import core.sys.windows.winbase, core.sys.windows.windef;
extern (Windows) {
DWORD AddIPAddress(IPAddr, IPMask, DWORD, PULONG, PULONG);
diff --git a/libphobos/libdruntime/core/sys/windows/iprtrmib.d b/libphobos/libdruntime/core/sys/windows/iprtrmib.d
index 4365723..1d23bc1 100644
--- a/libphobos/libdruntime/core/sys/windows/iprtrmib.d
+++ b/libphobos/libdruntime/core/sys/windows/iprtrmib.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.iprtrmib;
version (Windows):
+@system:
import core.sys.windows.ipifcons;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
// FIXME: check types of constants
diff --git a/libphobos/libdruntime/core/sys/windows/iptypes.d b/libphobos/libdruntime/core/sys/windows/iptypes.d
index ada3e9c..f4f9fe8 100644
--- a/libphobos/libdruntime/core/sys/windows/iptypes.d
+++ b/libphobos/libdruntime/core/sys/windows/iptypes.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.iptypes;
version (Windows):
+@system:
import core.sys.windows.windef;
import core.stdc.time;
diff --git a/libphobos/libdruntime/core/sys/windows/isguids.d b/libphobos/libdruntime/core/sys/windows/isguids.d
index b78d352..61e1d1e 100644
--- a/libphobos/libdruntime/core/sys/windows/isguids.d
+++ b/libphobos/libdruntime/core/sys/windows/isguids.d
@@ -10,7 +10,7 @@
module core.sys.windows.isguids;
version (Windows):
-private import core.sys.windows.basetyps;
+import core.sys.windows.basetyps;
extern (C) extern const GUID
CLSID_InternetShortcut,
diff --git a/libphobos/libdruntime/core/sys/windows/lm.d b/libphobos/libdruntime/core/sys/windows/lm.d
index 48a6f55..e12f629 100644
--- a/libphobos/libdruntime/core/sys/windows/lm.d
+++ b/libphobos/libdruntime/core/sys/windows/lm.d
@@ -8,6 +8,8 @@
*/
module core.sys.windows.lm;
version (Windows):
+@system:
+
/* removed - now supporting only Win2k up
version (WindowsVista) {
version = WIN32_WINNT_ONLY;
diff --git a/libphobos/libdruntime/core/sys/windows/lmaccess.d b/libphobos/libdruntime/core/sys/windows/lmaccess.d
index 5846fa1..3e1370d 100644
--- a/libphobos/libdruntime/core/sys/windows/lmaccess.d
+++ b/libphobos/libdruntime/core/sys/windows/lmaccess.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.lmaccess;
version (Windows):
+@system:
pragma(lib, "netapi32");
/**
@@ -16,7 +17,7 @@ pragma(lib, "netapi32");
the Platform SDK docs, so they have been dropped from this file.
*/
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
const wchar[]
GROUP_SPECIALGRP_USERS = "USERS",
diff --git a/libphobos/libdruntime/core/sys/windows/lmalert.d b/libphobos/libdruntime/core/sys/windows/lmalert.d
index 53acff03..675dc89 100644
--- a/libphobos/libdruntime/core/sys/windows/lmalert.d
+++ b/libphobos/libdruntime/core/sys/windows/lmalert.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.lmalert;
version (Windows):
+@system:
pragma(lib, "netapi32");
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
const TCHAR[]
ALERTER_MAILSLOT = `\\.\MAILSLOT\Alerter`,
diff --git a/libphobos/libdruntime/core/sys/windows/lmapibuf.d b/libphobos/libdruntime/core/sys/windows/lmapibuf.d
index 6c2df77..f78271a 100644
--- a/libphobos/libdruntime/core/sys/windows/lmapibuf.d
+++ b/libphobos/libdruntime/core/sys/windows/lmapibuf.d
@@ -10,7 +10,7 @@ module core.sys.windows.lmapibuf;
version (Windows):
pragma(lib, "netapi32");
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
extern (Windows) {
NET_API_STATUS NetApiBufferAllocate(DWORD, PVOID*);
diff --git a/libphobos/libdruntime/core/sys/windows/lmat.d b/libphobos/libdruntime/core/sys/windows/lmat.d
index 64272af..1862adf 100644
--- a/libphobos/libdruntime/core/sys/windows/lmat.d
+++ b/libphobos/libdruntime/core/sys/windows/lmat.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.lmat;
version (Windows):
+@system:
pragma(lib, "netapi32");
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum JOB_RUN_PERIODICALLY = 1;
enum JOB_EXEC_ERROR = 2;
diff --git a/libphobos/libdruntime/core/sys/windows/lmaudit.d b/libphobos/libdruntime/core/sys/windows/lmaudit.d
index 476ab5b..524332a 100644
--- a/libphobos/libdruntime/core/sys/windows/lmaudit.d
+++ b/libphobos/libdruntime/core/sys/windows/lmaudit.d
@@ -9,8 +9,9 @@
// COMMENT: This file may be deprecated.
module core.sys.windows.lmaudit;
version (Windows):
+@system:
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum LOGFLAGS_FORWARD = 0;
enum LOGFLAGS_BACKWARD = 1;
diff --git a/libphobos/libdruntime/core/sys/windows/lmbrowsr.d b/libphobos/libdruntime/core/sys/windows/lmbrowsr.d
index 2bd303f..971d8cd 100644
--- a/libphobos/libdruntime/core/sys/windows/lmbrowsr.d
+++ b/libphobos/libdruntime/core/sys/windows/lmbrowsr.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.lmbrowsr;
version (Windows):
+@system:
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum BROWSER_ROLE_PDC = 1;
enum BROWSER_ROLE_BDC = 2;
diff --git a/libphobos/libdruntime/core/sys/windows/lmchdev.d b/libphobos/libdruntime/core/sys/windows/lmchdev.d
index 2dcf9e3..39d9e78 100644
--- a/libphobos/libdruntime/core/sys/windows/lmchdev.d
+++ b/libphobos/libdruntime/core/sys/windows/lmchdev.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.lmchdev;
version (Windows):
+@system:
// COMMENT: This file might be deprecated.
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum CHARDEVQ_NO_REQUESTS = -1;
enum CHARDEV_CLOSE = 0;
diff --git a/libphobos/libdruntime/core/sys/windows/lmconfig.d b/libphobos/libdruntime/core/sys/windows/lmconfig.d
index 64e943a..6bb2472 100644
--- a/libphobos/libdruntime/core/sys/windows/lmconfig.d
+++ b/libphobos/libdruntime/core/sys/windows/lmconfig.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.lmconfig;
version (Windows):
+@system:
// All functions in this file are deprecated!
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
deprecated {
struct CONFIG_INFO_0 {
diff --git a/libphobos/libdruntime/core/sys/windows/lmcons.d b/libphobos/libdruntime/core/sys/windows/lmcons.d
index c0fcb8f..b115cce 100644
--- a/libphobos/libdruntime/core/sys/windows/lmcons.d
+++ b/libphobos/libdruntime/core/sys/windows/lmcons.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.lmcons;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.windef;
-private import core.sys.windows.lmerr; // for NERR_BASE
+import core.sys.windows.windef;
+import core.sys.windows.lmerr; // for NERR_BASE
const TCHAR[]
MESSAGE_FILENAME = "NETMSG",
diff --git a/libphobos/libdruntime/core/sys/windows/lmerr.d b/libphobos/libdruntime/core/sys/windows/lmerr.d
index 5af4132..77e2378 100644
--- a/libphobos/libdruntime/core/sys/windows/lmerr.d
+++ b/libphobos/libdruntime/core/sys/windows/lmerr.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.lmerr;
version (Windows):
+@system:
import core.sys.windows.winerror;
diff --git a/libphobos/libdruntime/core/sys/windows/lmerrlog.d b/libphobos/libdruntime/core/sys/windows/lmerrlog.d
index 8bc627e..8e15b4d 100644
--- a/libphobos/libdruntime/core/sys/windows/lmerrlog.d
+++ b/libphobos/libdruntime/core/sys/windows/lmerrlog.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.lmerrlog;
version (Windows):
+@system:
// COMMENT: This appears to be only for Win16. All functions are deprecated.
-private import core.sys.windows.lmcons, core.sys.windows.windef;
-private import core.sys.windows.lmaudit; // for LPHLOG
+import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmaudit; // for LPHLOG
enum ERRLOG_BASE=3100;
enum ERRLOG2_BASE=5700;
diff --git a/libphobos/libdruntime/core/sys/windows/lmmsg.d b/libphobos/libdruntime/core/sys/windows/lmmsg.d
index e636df7..2a2d60a 100644
--- a/libphobos/libdruntime/core/sys/windows/lmmsg.d
+++ b/libphobos/libdruntime/core/sys/windows/lmmsg.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.lmmsg;
version (Windows):
+@system:
pragma(lib, "netapi32");
-private import core.sys.windows.lmcons, core.sys.windows.windef, core.sys.windows.w32api;
+import core.sys.windows.lmcons, core.sys.windows.windef, core.sys.windows.w32api;
static assert (_WIN32_WINNT >= 0x501,
"core.sys.windows.lmmsg is available only if version WindowsXP, Windows2003 "
diff --git a/libphobos/libdruntime/core/sys/windows/lmremutl.d b/libphobos/libdruntime/core/sys/windows/lmremutl.d
index 0d1229e..ce7d45a 100644
--- a/libphobos/libdruntime/core/sys/windows/lmremutl.d
+++ b/libphobos/libdruntime/core/sys/windows/lmremutl.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.lmremutl;
version (Windows):
+@system:
pragma(lib, "netapi32");
// D Conversion Note: DESC_CHAR is defined as TCHAR.
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum SUPPORTS_REMOTE_ADMIN_PROTOCOL = 2;
enum SUPPORTS_RPC = 4;
diff --git a/libphobos/libdruntime/core/sys/windows/lmrepl.d b/libphobos/libdruntime/core/sys/windows/lmrepl.d
index 7796728..02345f8 100644
--- a/libphobos/libdruntime/core/sys/windows/lmrepl.d
+++ b/libphobos/libdruntime/core/sys/windows/lmrepl.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.lmrepl;
version (Windows):
+@system:
pragma(lib, "netapi32");
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum REPL_ROLE_EXPORT=1;
enum REPL_ROLE_IMPORT=2;
diff --git a/libphobos/libdruntime/core/sys/windows/lmserver.d b/libphobos/libdruntime/core/sys/windows/lmserver.d
index f27c7ef..83a9a84 100644
--- a/libphobos/libdruntime/core/sys/windows/lmserver.d
+++ b/libphobos/libdruntime/core/sys/windows/lmserver.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.lmserver;
version (Windows):
+@system:
import core.sys.windows.winsvc;
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
struct SERVER_INFO_100 {
DWORD sv100_platform_id;
diff --git a/libphobos/libdruntime/core/sys/windows/lmshare.d b/libphobos/libdruntime/core/sys/windows/lmshare.d
index 2aacc7e..215fb78 100644
--- a/libphobos/libdruntime/core/sys/windows/lmshare.d
+++ b/libphobos/libdruntime/core/sys/windows/lmshare.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.lmshare;
version (Windows):
+@system:
pragma(lib, "netapi32");
import core.sys.windows.lmcons;
-private import core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.windef;
enum SHARE_NETNAME_PARMNUM = 1;
diff --git a/libphobos/libdruntime/core/sys/windows/lmsname.d b/libphobos/libdruntime/core/sys/windows/lmsname.d
index 01dfe03..bdb1a6d 100644
--- a/libphobos/libdruntime/core/sys/windows/lmsname.d
+++ b/libphobos/libdruntime/core/sys/windows/lmsname.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.lmsname;
version (Windows):
+@system:
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
const TCHAR[]
SERVICE_WORKSTATION = "LanmanWorkstation",
diff --git a/libphobos/libdruntime/core/sys/windows/lmstats.d b/libphobos/libdruntime/core/sys/windows/lmstats.d
index 084c330..0c6e622 100644
--- a/libphobos/libdruntime/core/sys/windows/lmstats.d
+++ b/libphobos/libdruntime/core/sys/windows/lmstats.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.lmstats;
version (Windows):
+@system:
pragma(lib, "netapi32");
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum ULONG
STATSOPT_CLR = 1,
diff --git a/libphobos/libdruntime/core/sys/windows/lmsvc.d b/libphobos/libdruntime/core/sys/windows/lmsvc.d
index 68a1592..1743458 100644
--- a/libphobos/libdruntime/core/sys/windows/lmsvc.d
+++ b/libphobos/libdruntime/core/sys/windows/lmsvc.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.lmsvc;
version (Windows):
+@system:
// FIXME: Is this file deprecated? All of the functions are only for Win16.
/**
@@ -16,7 +17,7 @@ version (Windows):
*/
// TODO: 5 macros
-private import core.sys.windows.lmcons, core.sys.windows.lmsname, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.lmsname, core.sys.windows.windef;
const TCHAR[] SERVICE_DOS_ENCRYPTION = "ENCRYPT";
diff --git a/libphobos/libdruntime/core/sys/windows/lmuse.d b/libphobos/libdruntime/core/sys/windows/lmuse.d
index 8ceab47..a9dbcd4 100644
--- a/libphobos/libdruntime/core/sys/windows/lmuse.d
+++ b/libphobos/libdruntime/core/sys/windows/lmuse.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.lmuse;
version (Windows):
+@system:
pragma(lib, "netapi32");
import core.sys.windows.lmuseflg;
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum {
USE_LOCAL_PARMNUM = 1,
diff --git a/libphobos/libdruntime/core/sys/windows/lmwksta.d b/libphobos/libdruntime/core/sys/windows/lmwksta.d
index 33b57e5..f4d85fe 100644
--- a/libphobos/libdruntime/core/sys/windows/lmwksta.d
+++ b/libphobos/libdruntime/core/sys/windows/lmwksta.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.lmwksta;
version (Windows):
+@system:
pragma(lib, "netapi32");
import core.sys.windows.lmuseflg;
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
pragma(lib, "Netapi32");
diff --git a/libphobos/libdruntime/core/sys/windows/lzexpand.d b/libphobos/libdruntime/core/sys/windows/lzexpand.d
index 0ed0855..32ab141 100644
--- a/libphobos/libdruntime/core/sys/windows/lzexpand.d
+++ b/libphobos/libdruntime/core/sys/windows/lzexpand.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.lzexpand;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "lz32");
-private import core.sys.windows.winbase, core.sys.windows.windef;
+import core.sys.windows.winbase, core.sys.windows.windef;
enum : LONG {
LZERROR_BADINHANDLE = -1,
diff --git a/libphobos/libdruntime/core/sys/windows/mapi.d b/libphobos/libdruntime/core/sys/windows/mapi.d
index 2f8f03b..194f63b 100644
--- a/libphobos/libdruntime/core/sys/windows/mapi.d
+++ b/libphobos/libdruntime/core/sys/windows/mapi.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.mapi;
version (Windows):
+@system:
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
// FIXME: check types and grouping of constants
diff --git a/libphobos/libdruntime/core/sys/windows/mciavi.d b/libphobos/libdruntime/core/sys/windows/mciavi.d
index 537bd48..f7367e3 100644
--- a/libphobos/libdruntime/core/sys/windows/mciavi.d
+++ b/libphobos/libdruntime/core/sys/windows/mciavi.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.mciavi;
version (Windows):
+@system:
-private import core.sys.windows.mmsystem;
+import core.sys.windows.mmsystem;
// FIXME: check types and grouping of constants
diff --git a/libphobos/libdruntime/core/sys/windows/mcx.d b/libphobos/libdruntime/core/sys/windows/mcx.d
index 11f6a45..01b28ad 100644
--- a/libphobos/libdruntime/core/sys/windows/mcx.d
+++ b/libphobos/libdruntime/core/sys/windows/mcx.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.mcx;
version (Windows):
+@system:
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum DWORD
DIALOPTION_BILLING = 64,
diff --git a/libphobos/libdruntime/core/sys/windows/mgmtapi.d b/libphobos/libdruntime/core/sys/windows/mgmtapi.d
index 3a11e81..673fba8 100644
--- a/libphobos/libdruntime/core/sys/windows/mgmtapi.d
+++ b/libphobos/libdruntime/core/sys/windows/mgmtapi.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.mgmtapi;
version (Windows):
+@system:
import core.sys.windows.snmp;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum {
SNMP_MGMTAPI_TIMEOUT = 40,
diff --git a/libphobos/libdruntime/core/sys/windows/mmsystem.d b/libphobos/libdruntime/core/sys/windows/mmsystem.d
index ceb4c3d..9359afd 100644
--- a/libphobos/libdruntime/core/sys/windows/mmsystem.d
+++ b/libphobos/libdruntime/core/sys/windows/mmsystem.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.mmsystem;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "winmm");
@@ -16,7 +17,7 @@ pragma(lib, "winmm");
* compile-time constants, so they are implemented as templates.
*/
-private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver;
+import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver;
align(1):
@@ -1039,7 +1040,7 @@ struct MMTIME {
BYTE fps;
BYTE dummy;
BYTE[2] pad;
- };
+ }
_smpte smpte;
struct _midi {
DWORD songptrpos;
diff --git a/libphobos/libdruntime/core/sys/windows/msacm.d b/libphobos/libdruntime/core/sys/windows/msacm.d
index c6bf8af..b5d3052 100644
--- a/libphobos/libdruntime/core/sys/windows/msacm.d
+++ b/libphobos/libdruntime/core/sys/windows/msacm.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.msacm;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.basetsd, core.sys.windows.mmsystem, core.sys.windows.windef;
+import core.sys.windows.basetsd, core.sys.windows.mmsystem, core.sys.windows.windef;
mixin DECLARE_HANDLE!("HACMDRIVERID");
mixin DECLARE_HANDLE!("HACMDRIVER");
diff --git a/libphobos/libdruntime/core/sys/windows/mshtml.d b/libphobos/libdruntime/core/sys/windows/mshtml.d
index 796f1d3..2c4410d 100644
--- a/libphobos/libdruntime/core/sys/windows/mshtml.d
+++ b/libphobos/libdruntime/core/sys/windows/mshtml.d
@@ -8,39 +8,40 @@
*/
module core.sys.windows.mshtml;
version (Windows):
+@system:
-private import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn,
+import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn,
core.sys.windows.windef, core.sys.windows.wtypes;
// These are used in this file, but not defined in MinGW.
-interface IHTMLStyleSheet {};
+interface IHTMLStyleSheet {}
alias IHTMLStyle LPHTMLSTYLE;
alias IHTMLStyleSheet LPHTMLSTYLESHEET;
-interface IHTMLLocation {};
+interface IHTMLLocation {}
alias IHTMLLocation LPHTMLLOCATION;
-interface IHTMLFramesCollection {};
+interface IHTMLFramesCollection {}
alias IHTMLFramesCollection LPHTMLFRAMESCOLLECTION;
-interface IHTMLStyleSheetsCollection {};
+interface IHTMLStyleSheetsCollection {}
alias IHTMLStyleSheetsCollection LPHTMLSTYLESHEETSCOLLECTION;
-interface IHTMLStyle {};
-interface IHTMLFiltersCollection {};
+interface IHTMLStyle {}
+interface IHTMLFiltersCollection {}
alias IHTMLFiltersCollection LPHTMLFILTERSCOLLECTION;
interface IOmHistory : IDispatch {
HRESULT get_length(short* p);
HRESULT back(VARIANT*);
HRESULT forward(VARIANT*);
HRESULT go(VARIANT*);
-};
+}
alias IOmHistory LPOMHISTORY;
-interface IOmNavigator {};
+interface IOmNavigator {}
alias IOmNavigator LPOMNAVIGATOR;
-interface IHTMLImageElementFactory {};
+interface IHTMLImageElementFactory {}
alias IHTMLImageElementFactory LPHTMLIMAGEELEMENTFACTORY;
-interface IHTMLEventObj {};
+interface IHTMLEventObj {}
alias IHTMLEventObj LPHTMLEVENTOBJ;
-interface IHTMLScreen {};
+interface IHTMLScreen {}
alias IHTMLScreen LPHTMLSCREEN;
-interface IHTMLOptionElementFactory {};
+interface IHTMLOptionElementFactory {}
alias IHTMLOptionElementFactory LPHTMLOPTIONELEMENTFACTORY;
interface IHTMLLinkElement : IDispatch {
diff --git a/libphobos/libdruntime/core/sys/windows/mswsock.d b/libphobos/libdruntime/core/sys/windows/mswsock.d
index f7088ee..cd6b63c 100644
--- a/libphobos/libdruntime/core/sys/windows/mswsock.d
+++ b/libphobos/libdruntime/core/sys/windows/mswsock.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.mswsock;
version (Windows):
+@system:
import core.sys.windows.winbase, core.sys.windows.windef;
-private import core.sys.windows.basetyps, core.sys.windows.w32api;
+import core.sys.windows.basetyps, core.sys.windows.w32api;
import core.sys.windows.winsock2;
diff --git a/libphobos/libdruntime/core/sys/windows/nb30.d b/libphobos/libdruntime/core/sys/windows/nb30.d
index d587a9f..0d250cc 100644
--- a/libphobos/libdruntime/core/sys/windows/nb30.d
+++ b/libphobos/libdruntime/core/sys/windows/nb30.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.nb30;
version (Windows):
+@system:
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum size_t
NCBNAMSZ = 16,
diff --git a/libphobos/libdruntime/core/sys/windows/nddeapi.d b/libphobos/libdruntime/core/sys/windows/nddeapi.d
index b50e6cc..d4692c9 100644
--- a/libphobos/libdruntime/core/sys/windows/nddeapi.d
+++ b/libphobos/libdruntime/core/sys/windows/nddeapi.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.nddeapi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
// FIXME: check types and grouping of constants
diff --git a/libphobos/libdruntime/core/sys/windows/nspapi.d b/libphobos/libdruntime/core/sys/windows/nspapi.d
index 0e03acd..a2e7fab 100644
--- a/libphobos/libdruntime/core/sys/windows/nspapi.d
+++ b/libphobos/libdruntime/core/sys/windows/nspapi.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.nspapi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.basetyps, core.sys.windows.windef;
+import core.sys.windows.basetyps, core.sys.windows.windef;
// FIXME: check types of constants
diff --git a/libphobos/libdruntime/core/sys/windows/ntdef.d b/libphobos/libdruntime/core/sys/windows/ntdef.d
index 3dc875e..83d668c 100644
--- a/libphobos/libdruntime/core/sys/windows/ntdef.d
+++ b/libphobos/libdruntime/core/sys/windows/ntdef.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.ntdef;
version (Windows):
+@system:
-private import core.sys.windows.basetsd, core.sys.windows.subauth, core.sys.windows.windef, core.sys.windows.winnt;
+import core.sys.windows.basetsd, core.sys.windows.subauth, core.sys.windows.windef, core.sys.windows.winnt;
enum uint
OBJ_INHERIT = 0x0002,
diff --git a/libphobos/libdruntime/core/sys/windows/ntdll.d b/libphobos/libdruntime/core/sys/windows/ntdll.d
index 72ad54d..e8aa3a7 100644
--- a/libphobos/libdruntime/core/sys/windows/ntdll.d
+++ b/libphobos/libdruntime/core/sys/windows/ntdll.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.ntdll;
version (Windows):
+@system:
-private import core.sys.windows.w32api;
+import core.sys.windows.w32api;
enum SHUTDOWN_ACTION {
diff --git a/libphobos/libdruntime/core/sys/windows/ntldap.d b/libphobos/libdruntime/core/sys/windows/ntldap.d
index 3437658..e7a55dd 100644
--- a/libphobos/libdruntime/core/sys/windows/ntldap.d
+++ b/libphobos/libdruntime/core/sys/windows/ntldap.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.ntldap;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
diff --git a/libphobos/libdruntime/core/sys/windows/ntsecapi.d b/libphobos/libdruntime/core/sys/windows/ntsecapi.d
index b043168..df9c10a 100644
--- a/libphobos/libdruntime/core/sys/windows/ntsecapi.d
+++ b/libphobos/libdruntime/core/sys/windows/ntsecapi.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.ntsecapi;
version (Windows):
+@system:
pragma(lib, "advapi32");
version (ANSI) {} else version = Unicode;
diff --git a/libphobos/libdruntime/core/sys/windows/ntsecpkg.d b/libphobos/libdruntime/core/sys/windows/ntsecpkg.d
index 55a3112..8625b7a 100644
--- a/libphobos/libdruntime/core/sys/windows/ntsecpkg.d
+++ b/libphobos/libdruntime/core/sys/windows/ntsecpkg.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.ntsecpkg;
version (Windows):
+@system:
import core.sys.windows.windef, core.sys.windows.ntsecapi, core.sys.windows.security, core.sys.windows.ntdef, core.sys.windows.sspi;
import core.sys.windows.basetyps : GUID;
diff --git a/libphobos/libdruntime/core/sys/windows/oaidl.d b/libphobos/libdruntime/core/sys/windows/oaidl.d
index c8938ff..51d6be9 100644
--- a/libphobos/libdruntime/core/sys/windows/oaidl.d
+++ b/libphobos/libdruntime/core/sys/windows/oaidl.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.oaidl;
version (Windows):
+@system:
-private import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
+import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
enum DISPID_UNKNOWN = -1;
enum DISPID_VALUE = 0;
diff --git a/libphobos/libdruntime/core/sys/windows/objbase.d b/libphobos/libdruntime/core/sys/windows/objbase.d
index ee3f0d5..961ebcc 100644
--- a/libphobos/libdruntime/core/sys/windows/objbase.d
+++ b/libphobos/libdruntime/core/sys/windows/objbase.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.objbase;
version (Windows):
+@system:
pragma(lib, "ole32");
import core.sys.windows.cguid, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.wtypes;
-private import core.sys.windows.basetyps, core.sys.windows.objfwd, core.sys.windows.rpcdce, core.sys.windows.winbase,
+import core.sys.windows.basetyps, core.sys.windows.objfwd, core.sys.windows.rpcdce, core.sys.windows.winbase,
core.sys.windows.windef;
// DAC: Not needed for D?
diff --git a/libphobos/libdruntime/core/sys/windows/objfwd.d b/libphobos/libdruntime/core/sys/windows/objfwd.d
index 70a2a10..76d4f41 100644
--- a/libphobos/libdruntime/core/sys/windows/objfwd.d
+++ b/libphobos/libdruntime/core/sys/windows/objfwd.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.objfwd;
version (Windows):
+@system:
-private import core.sys.windows.objidl;
+import core.sys.windows.objidl;
/+
// Forward declararions are not necessary in D.
diff --git a/libphobos/libdruntime/core/sys/windows/objidl.d b/libphobos/libdruntime/core/sys/windows/objidl.d
index 7b33677..5368c29 100644
--- a/libphobos/libdruntime/core/sys/windows/objidl.d
+++ b/libphobos/libdruntime/core/sys/windows/objidl.d
@@ -12,15 +12,16 @@
// # do we need the proxies that are defined in this file?
module core.sys.windows.objidl;
version (Windows):
+@system:
import core.sys.windows.unknwn;
import core.sys.windows.objfwd;
-private import core.sys.windows.windef;
-private import core.sys.windows.basetyps;
-private import core.sys.windows.oleidl;
-private import core.sys.windows.wtypes;
-private import core.sys.windows.winbase; // for FILETIME
-private import core.sys.windows.rpcdce;
+import core.sys.windows.windef;
+import core.sys.windows.basetyps;
+import core.sys.windows.oleidl;
+import core.sys.windows.wtypes;
+import core.sys.windows.winbase; // for FILETIME
+import core.sys.windows.rpcdce;
struct STATSTG {
LPOLESTR pwcsName;
diff --git a/libphobos/libdruntime/core/sys/windows/objsafe.d b/libphobos/libdruntime/core/sys/windows/objsafe.d
index 2556984..0bfd19a 100644
--- a/libphobos/libdruntime/core/sys/windows/objsafe.d
+++ b/libphobos/libdruntime/core/sys/windows/objsafe.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.objsafe;
version (Windows):
+@system:
-private import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef;
+import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef;
enum {
INTERFACESAFE_FOR_UNTRUSTED_CALLER = 1,
diff --git a/libphobos/libdruntime/core/sys/windows/ocidl.d b/libphobos/libdruntime/core/sys/windows/ocidl.d
index 4244ba1..4b090b0 100644
--- a/libphobos/libdruntime/core/sys/windows/ocidl.d
+++ b/libphobos/libdruntime/core/sys/windows/ocidl.d
@@ -10,12 +10,13 @@
*/
module core.sys.windows.ocidl;
version (Windows):
+@system:
-private import core.sys.windows.ole2, core.sys.windows.oleidl, core.sys.windows.oaidl, core.sys.windows.objfwd,
+import core.sys.windows.ole2, core.sys.windows.oleidl, core.sys.windows.oaidl, core.sys.windows.objfwd,
core.sys.windows.windef, core.sys.windows.wtypes;
-private import core.sys.windows.objidl; // for CLIPFORMAT
-private import core.sys.windows.wingdi; // for TEXTMETRICW
-private import core.sys.windows.winuser; // for LPMSG
+import core.sys.windows.objidl; // for CLIPFORMAT
+import core.sys.windows.wingdi; // for TEXTMETRICW
+import core.sys.windows.winuser; // for LPMSG
interface IBindHost : IUnknown {}
@@ -25,8 +26,8 @@ interface IServiceProvider : IUnknown{
/*
// TODO:
-//private import core.sys.windows.servprov; // for IServiceProvider
-// private import core.sys.windows.urlmon; // for IBindHost. This is not included in MinGW.
+//import core.sys.windows.servprov; // for IServiceProvider
+// import core.sys.windows.urlmon; // for IBindHost. This is not included in MinGW.
// core.sys.windows.urlmon should contain:
interface IBindHost : IUnknown
diff --git a/libphobos/libdruntime/core/sys/windows/odbcinst.d b/libphobos/libdruntime/core/sys/windows/odbcinst.d
index 8947b39..ee22bc6 100644
--- a/libphobos/libdruntime/core/sys/windows/odbcinst.d
+++ b/libphobos/libdruntime/core/sys/windows/odbcinst.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.odbcinst;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
import core.sys.windows.sql;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
/* FIXME: The Unicode/Ansi functions situation is a mess. How do the xxxA
* versions of these functions fit into the scheme?
diff --git a/libphobos/libdruntime/core/sys/windows/ole.d b/libphobos/libdruntime/core/sys/windows/ole.d
index cb7dffe..1a49ea5 100644
--- a/libphobos/libdruntime/core/sys/windows/ole.d
+++ b/libphobos/libdruntime/core/sys/windows/ole.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.ole;
version (Windows):
+@system:
pragma(lib, "ole32");
-private import core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.uuid;
+import core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.uuid;
alias LPCSTR OLE_LPCSTR;
diff --git a/libphobos/libdruntime/core/sys/windows/ole2.d b/libphobos/libdruntime/core/sys/windows/ole2.d
index 0f216af..575a8eb 100644
--- a/libphobos/libdruntime/core/sys/windows/ole2.d
+++ b/libphobos/libdruntime/core/sys/windows/ole2.d
@@ -8,12 +8,13 @@
*/
module core.sys.windows.ole2;
version (Windows):
+@system:
pragma(lib, "ole32");
public import core.sys.windows.basetyps, core.sys.windows.objbase, core.sys.windows.oleauto, core.sys.windows.olectlid,
core.sys.windows.oleidl, core.sys.windows.unknwn, core.sys.windows.winerror, core.sys.windows.uuid;
-private import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.windef, core.sys.windows.wtypes;
-private import core.sys.windows.winuser; // for LPMSG
+import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.windef, core.sys.windows.wtypes;
+import core.sys.windows.winuser; // for LPMSG
enum E_DRAW = VIEW_E_DRAW;
diff --git a/libphobos/libdruntime/core/sys/windows/oleacc.d b/libphobos/libdruntime/core/sys/windows/oleacc.d
index fb4f770..77ced02 100644
--- a/libphobos/libdruntime/core/sys/windows/oleacc.d
+++ b/libphobos/libdruntime/core/sys/windows/oleacc.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.oleacc;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "oleacc");
-private import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn, core.sys.windows.wtypes,
+import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn, core.sys.windows.wtypes,
core.sys.windows.windef;
enum {
diff --git a/libphobos/libdruntime/core/sys/windows/oleauto.d b/libphobos/libdruntime/core/sys/windows/oleauto.d
index 113456c..20f34af 100644
--- a/libphobos/libdruntime/core/sys/windows/oleauto.d
+++ b/libphobos/libdruntime/core/sys/windows/oleauto.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.oleauto;
version (Windows):
+@system:
pragma(lib, "oleaut32");
import core.sys.windows.oaidl;
-private import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
-private import core.sys.windows.winbase; // for SYSTEMTIME
+import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
+import core.sys.windows.winbase; // for SYSTEMTIME
align(8):
enum STDOLE_MAJORVERNUM = 1;
@@ -215,10 +216,10 @@ struct NUMPARSE {
deprecated { // not actually deprecated, but they aren't converted yet.
// (will need to reinstate CreateTypeLib as well)
- interface ICreateTypeInfo {};
- interface ICreateTypeInfo2 {};
- interface ICreateTypeLib {};
- interface ICreateTypeLib2 {};
+ interface ICreateTypeInfo {}
+ interface ICreateTypeInfo2 {}
+ interface ICreateTypeLib {}
+ interface ICreateTypeLib2 {}
alias ICreateTypeInfo LPCREATETYPEINFO;
alias ICreateTypeInfo2 LPCREATETYPEINFO2;
diff --git a/libphobos/libdruntime/core/sys/windows/olectl.d b/libphobos/libdruntime/core/sys/windows/olectl.d
index 3909c48..e0bc679 100644
--- a/libphobos/libdruntime/core/sys/windows/olectl.d
+++ b/libphobos/libdruntime/core/sys/windows/olectl.d
@@ -8,16 +8,17 @@
*/
module core.sys.windows.olectl;
version (Windows):
+@system:
// In conversion from MinGW, the following was deleted:
//#define FONTSIZE(n) {n##0000, 0}
import core.sys.windows.ocidl, core.sys.windows.olectlid;
-private import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.oleauto, core.sys.windows.unknwn,
+import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.oleauto, core.sys.windows.unknwn,
core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.winuser, core.sys.windows.wtypes;
-private import core.sys.windows.ntdef; // for NTSTATUS
-private import core.sys.windows.objfwd; // for LPSTREAM
-private import core.sys.windows.winerror; // for SCODE
+import core.sys.windows.ntdef; // for NTSTATUS
+import core.sys.windows.objfwd; // for LPSTREAM
+import core.sys.windows.winerror; // for SCODE
private {
diff --git a/libphobos/libdruntime/core/sys/windows/olectlid.d b/libphobos/libdruntime/core/sys/windows/olectlid.d
index 72156a1..fd3ea89 100644
--- a/libphobos/libdruntime/core/sys/windows/olectlid.d
+++ b/libphobos/libdruntime/core/sys/windows/olectlid.d
@@ -9,5 +9,5 @@
module core.sys.windows.olectlid;
version (Windows):
-private import core.sys.windows.basetyps;
+import core.sys.windows.basetyps;
diff --git a/libphobos/libdruntime/core/sys/windows/oledlg.d b/libphobos/libdruntime/core/sys/windows/oledlg.d
index 732d302..e44c029 100644
--- a/libphobos/libdruntime/core/sys/windows/oledlg.d
+++ b/libphobos/libdruntime/core/sys/windows/oledlg.d
@@ -7,12 +7,13 @@
* Source: $(DRUNTIMESRC src/core/sys/windows/_oledlg.d)
*/
module core.sys.windows.oledlg;
+@system:
version (Windows):
version (ANSI) {} else version = Unicode;
import core.sys.windows.commdlg, core.sys.windows.dlgs, core.sys.windows.ole2, core.sys.windows.prsht, core.sys.windows.shellapi;
-private import core.sys.windows.winbase, core.sys.windows.objidl, core.sys.windows.objfwd, core.sys.windows.winnt;
+import core.sys.windows.winbase, core.sys.windows.objidl, core.sys.windows.objfwd, core.sys.windows.winnt;
// FIXME: remove inherited methods from interface definitions
diff --git a/libphobos/libdruntime/core/sys/windows/oleidl.d b/libphobos/libdruntime/core/sys/windows/oleidl.d
index 2c68602..dc0cae8 100644
--- a/libphobos/libdruntime/core/sys/windows/oleidl.d
+++ b/libphobos/libdruntime/core/sys/windows/oleidl.d
@@ -8,15 +8,16 @@
*/
module core.sys.windows.oleidl;
version (Windows):
+@system:
// DAC: This is defined in ocidl !!
// what is it doing in here?
//alias IEnumOleUndoUnits LPENUMOLEUNDOUNITS;
-private import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef,
+import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef,
core.sys.windows.winuser, core.sys.windows.wtypes;
-private import core.sys.windows.objfwd; // for LPMONIKER
-private import core.sys.windows.wingdi; // for LPLOGPALETTE
+import core.sys.windows.objfwd; // for LPMONIKER
+import core.sys.windows.wingdi; // for LPLOGPALETTE
enum MK_ALT = 32;
diff --git a/libphobos/libdruntime/core/sys/windows/pbt.d b/libphobos/libdruntime/core/sys/windows/pbt.d
index e6b7814..aec938e 100644
--- a/libphobos/libdruntime/core/sys/windows/pbt.d
+++ b/libphobos/libdruntime/core/sys/windows/pbt.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.pbt;
version (Windows):
+@system:
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum : WPARAM {
PBT_APMQUERYSUSPEND,
diff --git a/libphobos/libdruntime/core/sys/windows/powrprof.d b/libphobos/libdruntime/core/sys/windows/powrprof.d
index 59a90c5..75ec73e 100644
--- a/libphobos/libdruntime/core/sys/windows/powrprof.d
+++ b/libphobos/libdruntime/core/sys/windows/powrprof.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.powrprof;
version (Windows):
+@system:
pragma(lib, "powrprof");
-private import core.sys.windows.windef;
-private import core.sys.windows.ntdef;
+import core.sys.windows.windef;
+import core.sys.windows.ntdef;
// FIXME: look up Windows version support
diff --git a/libphobos/libdruntime/core/sys/windows/prsht.d b/libphobos/libdruntime/core/sys/windows/prsht.d
index 3dbb314..efea4f2 100644
--- a/libphobos/libdruntime/core/sys/windows/prsht.d
+++ b/libphobos/libdruntime/core/sys/windows/prsht.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.prsht;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "comctl32");
-private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser;
+import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser;
enum MAXPROPPAGES = 100;
diff --git a/libphobos/libdruntime/core/sys/windows/psapi.d b/libphobos/libdruntime/core/sys/windows/psapi.d
index 7088784..7e62d9f 100644
--- a/libphobos/libdruntime/core/sys/windows/psapi.d
+++ b/libphobos/libdruntime/core/sys/windows/psapi.d
@@ -13,12 +13,13 @@
module core.sys.windows.psapi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.w32api;
-private import core.sys.windows.winbase;
-private import core.sys.windows.windef;
+import core.sys.windows.w32api;
+import core.sys.windows.winbase;
+import core.sys.windows.windef;
struct MODULEINFO {
LPVOID lpBaseOfDll;
@@ -83,13 +84,11 @@ alias ENUM_PAGE_FILE_INFORMATION* PENUM_PAGE_FILE_INFORMATION;
/* application-defined callback function used with the EnumPageFiles()
* http://windowssdk.msdn.microsoft.com/library/ms682627.aspx */
-version (Unicode) {
- alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCWSTR)
- PENUM_PAGE_FILE_CALLBACK;
-} else {
- alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCSTR)
- PENUM_PAGE_FILE_CALLBACK;
-}
+alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCWSTR)
+ PENUM_PAGE_FILE_CALLBACKW;
+alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCSTR)
+ PENUM_PAGE_FILE_CALLBACKA;
+
// Grouped by application, not in alphabetical order.
extern (Windows) {
@@ -137,11 +136,12 @@ extern (Windows) {
/* Resources Information */
BOOL GetPerformanceInfo(PPERFORMANCE_INFORMATION, DWORD); /* XP/Server2003/Vista/Longhorn */
- BOOL EnumPageFilesW(PENUM_PAGE_FILE_CALLBACK, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */
- BOOL EnumPageFilesA(PENUM_PAGE_FILE_CALLBACK, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */
+ BOOL EnumPageFilesW(PENUM_PAGE_FILE_CALLBACKW, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */
+ BOOL EnumPageFilesA(PENUM_PAGE_FILE_CALLBACKA, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */
}
version (Unicode) {
+ alias PENUM_PAGE_FILE_CALLBACKW PENUM_PAGE_FILE_CALLBACK;
alias GetModuleBaseNameW GetModuleBaseName;
alias GetModuleFileNameExW GetModuleFileNameEx;
alias GetMappedFileNameW GetMappedFileName;
@@ -150,6 +150,7 @@ version (Unicode) {
alias EnumPageFilesW EnumPageFiles;
alias GetProcessImageFileNameW GetProcessImageFileName;
} else {
+ alias PENUM_PAGE_FILE_CALLBACKA PENUM_PAGE_FILE_CALLBACK;
alias GetModuleBaseNameA GetModuleBaseName;
alias GetModuleFileNameExA GetModuleFileNameEx;
alias GetMappedFileNameA GetMappedFileName;
diff --git a/libphobos/libdruntime/core/sys/windows/rapi.d b/libphobos/libdruntime/core/sys/windows/rapi.d
index b60a14b..6c48f6b 100644
--- a/libphobos/libdruntime/core/sys/windows/rapi.d
+++ b/libphobos/libdruntime/core/sys/windows/rapi.d
@@ -9,13 +9,14 @@
*/
module core.sys.windows.rapi;
version (Windows):
+@system:
/* Comment from MinGW
NOTE: This strictly does not belong in the Win32 API since it's
really part of Platform SDK.
*/
-private import core.sys.windows.winbase, core.sys.windows.windef;
+import core.sys.windows.winbase, core.sys.windows.windef;
extern (Windows):
diff --git a/libphobos/libdruntime/core/sys/windows/ras.d b/libphobos/libdruntime/core/sys/windows/ras.d
index 479aa3b..1004c6b 100644
--- a/libphobos/libdruntime/core/sys/windows/ras.d
+++ b/libphobos/libdruntime/core/sys/windows/ras.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.ras;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "rasapi32");
-private import core.sys.windows.basetyps, core.sys.windows.lmcons, core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.basetyps, core.sys.windows.lmcons, core.sys.windows.w32api, core.sys.windows.windef;
align(4):
diff --git a/libphobos/libdruntime/core/sys/windows/rasdlg.d b/libphobos/libdruntime/core/sys/windows/rasdlg.d
index 77346cb..8304a01 100644
--- a/libphobos/libdruntime/core/sys/windows/rasdlg.d
+++ b/libphobos/libdruntime/core/sys/windows/rasdlg.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.rasdlg;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
import core.sys.windows.ras;
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
enum {
RASPBDEVENT_AddEntry = 1,
diff --git a/libphobos/libdruntime/core/sys/windows/raserror.d b/libphobos/libdruntime/core/sys/windows/raserror.d
index 9004444..43bebac 100644
--- a/libphobos/libdruntime/core/sys/windows/raserror.d
+++ b/libphobos/libdruntime/core/sys/windows/raserror.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.raserror;
version (Windows):
+@system:
enum {
SUCCESS = 0,
diff --git a/libphobos/libdruntime/core/sys/windows/rassapi.d b/libphobos/libdruntime/core/sys/windows/rassapi.d
index b70dc07..0eaa5b2 100644
--- a/libphobos/libdruntime/core/sys/windows/rassapi.d
+++ b/libphobos/libdruntime/core/sys/windows/rassapi.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.rassapi;
version (Windows):
+@system:
-private import core.sys.windows.lmcons, core.sys.windows.windef;
+import core.sys.windows.lmcons, core.sys.windows.windef;
// FIXME: check types of constants
diff --git a/libphobos/libdruntime/core/sys/windows/reason.d b/libphobos/libdruntime/core/sys/windows/reason.d
index 752f28e..b0c4969 100644
--- a/libphobos/libdruntime/core/sys/windows/reason.d
+++ b/libphobos/libdruntime/core/sys/windows/reason.d
@@ -9,8 +9,9 @@
*/
module core.sys.windows.reason;
version (Windows):
+@system:
-private import core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.windef;
static assert (_WIN32_WINNT >= 0x501,
"core.sys.windows.reason is only available on WindowsXP and later");
diff --git a/libphobos/libdruntime/core/sys/windows/regstr.d b/libphobos/libdruntime/core/sys/windows/regstr.d
index 2302964..1fa1c7e 100644
--- a/libphobos/libdruntime/core/sys/windows/regstr.d
+++ b/libphobos/libdruntime/core/sys/windows/regstr.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.regstr;
version (Windows):
+@system:
// TODO: fix possible conflict with shloj. Sort out NEC_98 issue.
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum REGSTR_MAX_VALUE_LENGTH = 256;
diff --git a/libphobos/libdruntime/core/sys/windows/richedit.d b/libphobos/libdruntime/core/sys/windows/richedit.d
index a05c3b8..1abc8f3 100644
--- a/libphobos/libdruntime/core/sys/windows/richedit.d
+++ b/libphobos/libdruntime/core/sys/windows/richedit.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.richedit;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.windef, core.sys.windows.winuser;
-private import core.sys.windows.wingdi; // for LF_FACESIZE
+import core.sys.windows.windef, core.sys.windows.winuser;
+import core.sys.windows.wingdi; // for LF_FACESIZE
align(4):
diff --git a/libphobos/libdruntime/core/sys/windows/richole.d b/libphobos/libdruntime/core/sys/windows/richole.d
index 56a0fd8..a4e64e8 100644
--- a/libphobos/libdruntime/core/sys/windows/richole.d
+++ b/libphobos/libdruntime/core/sys/windows/richole.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.richole;
version (Windows):
+@system:
-private import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.ole2, core.sys.windows.unknwn,
+import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.ole2, core.sys.windows.unknwn,
core.sys.windows.windef;
-private import core.sys.windows.richedit; // for CHARRANGE
+import core.sys.windows.richedit; // for CHARRANGE
//align(4):
@@ -83,7 +84,7 @@ interface IRichEditOle : IUnknown {
HRESULT ContextSensitiveHelp(BOOL);
HRESULT GetClipboardData(CHARRANGE*, DWORD, LPDATAOBJECT*);
HRESULT ImportDataObject(LPDATAOBJECT, CLIPFORMAT, HGLOBAL);
-};
+}
alias IRichEditOle LPRICHEDITOLE;
interface IRichEditOleCallback : IUnknown {
@@ -97,5 +98,5 @@ interface IRichEditOleCallback : IUnknown {
HRESULT GetClipboardData(CHARRANGE*, DWORD, LPDATAOBJECT*);
HRESULT GetDragDropEffect(BOOL, DWORD, PDWORD);
HRESULT GetContextMenu(WORD, LPOLEOBJECT, CHARRANGE*, HMENU*);
-};
+}
alias IRichEditOleCallback LPRICHEDITOLECALLBACK;
diff --git a/libphobos/libdruntime/core/sys/windows/rpc.d b/libphobos/libdruntime/core/sys/windows/rpc.d
index 6097184..5922123 100644
--- a/libphobos/libdruntime/core/sys/windows/rpc.d
+++ b/libphobos/libdruntime/core/sys/windows/rpc.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.rpc;
version (Windows):
+@system:
/* Moved to rpcdecp (duplicate definition).
typedef void *I_RPC_HANDLE;
diff --git a/libphobos/libdruntime/core/sys/windows/rpcdce.d b/libphobos/libdruntime/core/sys/windows/rpcdce.d
index d29bd9d..cdffbcf 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcdce.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcdce.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.rpcdce;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "Rpcrt4");
@@ -16,7 +17,7 @@ pragma(lib, "Rpcrt4");
// replaced aliases for version (Unicode)
public import core.sys.windows.rpcdcep;
-private import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.windef;
// FIXME: clean up Windows version support
diff --git a/libphobos/libdruntime/core/sys/windows/rpcdce2.d b/libphobos/libdruntime/core/sys/windows/rpcdce2.d
index 7993459..10ec910 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcdce2.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcdce2.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.rpcdce2;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
import core.sys.windows.rpcdce;
-private import core.sys.windows.basetyps;
+import core.sys.windows.basetyps;
// FIXME: deal with RPC_UNICODE_SUPPORTED
// FIXME: check types of constants
diff --git a/libphobos/libdruntime/core/sys/windows/rpcdcep.d b/libphobos/libdruntime/core/sys/windows/rpcdcep.d
index 2d29276..fe22bf8 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcdcep.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcdcep.d
@@ -8,12 +8,13 @@
*/
module core.sys.windows.rpcdcep;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.basetyps;
-private import core.sys.windows.w32api;
-private import core.sys.windows.windef;
+import core.sys.windows.basetyps;
+import core.sys.windows.w32api;
+import core.sys.windows.windef;
mixin DECLARE_HANDLE!("I_RPC_HANDLE");
alias long RPC_STATUS;
diff --git a/libphobos/libdruntime/core/sys/windows/rpcndr.d b/libphobos/libdruntime/core/sys/windows/rpcndr.d
index d75f100..6720b94 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcndr.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcndr.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.rpcndr;
version (Windows):
+@system:
pragma(lib, "rpcrt4");
/* Translation notes:
@@ -19,9 +20,9 @@ pragma(lib, "rpcrt4");
enum __RPCNDR_H_VERSION__= 450;
import core.sys.windows.rpcnsip;
-private import core.sys.windows.rpc, core.sys.windows.rpcdce, core.sys.windows.unknwn, core.sys.windows.windef;
-private import core.sys.windows.objidl; // for IRpcChannelBuffer, IRpcStubBuffer
-private import core.sys.windows.basetyps;
+import core.sys.windows.rpc, core.sys.windows.rpcdce, core.sys.windows.unknwn, core.sys.windows.windef;
+import core.sys.windows.objidl; // for IRpcChannelBuffer, IRpcStubBuffer
+import core.sys.windows.basetyps;
extern (Windows):
diff --git a/libphobos/libdruntime/core/sys/windows/rpcnsi.d b/libphobos/libdruntime/core/sys/windows/rpcnsi.d
index f4e8538..2ecae63 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcnsi.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcnsi.d
@@ -10,13 +10,14 @@
*/
module core.sys.windows.rpcnsi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "rpcns4");
-private import core.sys.windows.basetyps, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi, core.sys.windows.rpcdce,
+import core.sys.windows.basetyps, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi, core.sys.windows.rpcdce,
core.sys.windows.w32api;
-private import core.sys.windows.windef; // for HANDLE
+import core.sys.windows.windef; // for HANDLE
mixin DECLARE_HANDLE!("RPC_NS_HANDLE");
diff --git a/libphobos/libdruntime/core/sys/windows/rpcnsip.d b/libphobos/libdruntime/core/sys/windows/rpcnsip.d
index fcf4389..1c0f050 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcnsip.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcnsip.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.rpcnsip;
version (Windows):
+@system:
-private import core.sys.windows.rpcdce, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi;
+import core.sys.windows.rpcdce, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi;
struct RPC_IMPORT_CONTEXT_P {
RPC_NS_HANDLE LookupContext;
diff --git a/libphobos/libdruntime/core/sys/windows/rpcnterr.d b/libphobos/libdruntime/core/sys/windows/rpcnterr.d
index 8b1e583..dcd63ab 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcnterr.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcnterr.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.rpcnterr;
version (Windows):
+@system:
import core.sys.windows.winerror;
diff --git a/libphobos/libdruntime/core/sys/windows/schannel.d b/libphobos/libdruntime/core/sys/windows/schannel.d
index c762238..1d2fbda 100644
--- a/libphobos/libdruntime/core/sys/windows/schannel.d
+++ b/libphobos/libdruntime/core/sys/windows/schannel.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.schannel;
version (Windows):
+@system:
import core.sys.windows.wincrypt;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum DWORD SCHANNEL_CRED_VERSION = 4;
enum SCHANNEL_SHUTDOWN = 1;
diff --git a/libphobos/libdruntime/core/sys/windows/sdkddkver.d b/libphobos/libdruntime/core/sys/windows/sdkddkver.d
new file mode 100644
index 0000000..3af3c86
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/windows/sdkddkver.d
@@ -0,0 +1,118 @@
+/**
+ * Windows API header module
+ *
+ * Translated from Windows SDK API
+ *
+ * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Source: $(DRUNTIMESRC src/core/sys/windows/sdkddkver.d)
+ */
+module core.sys.windows.sdkddkver;
+
+version (Windows):
+@system:
+
+enum _WIN32_WINNT_NT4 = 0x0400;
+enum _WIN32_WINNT_WIN2K = 0x0500;
+enum _WIN32_WINNT_WINXP = 0x0501;
+enum _WIN32_WINNT_WS03 = 0x0502;
+enum _WIN32_WINNT_WIN6 = 0x0600;
+enum _WIN32_WINNT_VISTA = 0x0600;
+enum _WIN32_WINNT_WS08 = 0x0600;
+enum _WIN32_WINNT_LONGHORN = 0x0600;
+enum _WIN32_WINNT_WIN7 = 0x0601;
+enum _WIN32_WINNT_WIN8 = 0x0602;
+enum _WIN32_WINNT_WINBLUE = 0x0603;
+enum _WIN32_WINNT_WIN10 = 0x0A00;
+
+enum _WIN32_IE_IE20 = 0x0200;
+enum _WIN32_IE_IE30 = 0x0300;
+enum _WIN32_IE_IE302 = 0x0302;
+enum _WIN32_IE_IE40 = 0x0400;
+enum _WIN32_IE_IE401 = 0x0401;
+enum _WIN32_IE_IE50 = 0x0500;
+enum _WIN32_IE_IE501 = 0x0501;
+enum _WIN32_IE_IE55 = 0x0550;
+enum _WIN32_IE_IE60 = 0x0600;
+enum _WIN32_IE_IE60SP1 = 0x0601;
+enum _WIN32_IE_IE60SP2 = 0x0603;
+enum _WIN32_IE_IE70 = 0x0700;
+enum _WIN32_IE_IE80 = 0x0800;
+enum _WIN32_IE_IE90 = 0x0900;
+enum _WIN32_IE_IE100 = 0x0A00;
+
+enum _WIN32_IE_NT4 = _WIN32_IE_IE20;
+enum _WIN32_IE_NT4SP1 = _WIN32_IE_IE20;
+enum _WIN32_IE_NT4SP2 = _WIN32_IE_IE20;
+enum _WIN32_IE_NT4SP3 = _WIN32_IE_IE302;
+enum _WIN32_IE_NT4SP4 = _WIN32_IE_IE401;
+enum _WIN32_IE_NT4SP5 = _WIN32_IE_IE401;
+enum _WIN32_IE_NT4SP6 = _WIN32_IE_IE50;
+enum _WIN32_IE_WIN98 = _WIN32_IE_IE401;
+enum _WIN32_IE_WIN98SE = _WIN32_IE_IE50;
+enum _WIN32_IE_WINME = _WIN32_IE_IE55;
+enum _WIN32_IE_WIN2K = _WIN32_IE_IE501;
+enum _WIN32_IE_WIN2KSP1 = _WIN32_IE_IE501;
+enum _WIN32_IE_WIN2KSP2 = _WIN32_IE_IE501;
+enum _WIN32_IE_WIN2KSP3 = _WIN32_IE_IE501;
+enum _WIN32_IE_WIN2KSP4 = _WIN32_IE_IE501;
+enum _WIN32_IE_XP = _WIN32_IE_IE60;
+enum _WIN32_IE_XPSP1 = _WIN32_IE_IE60SP1;
+enum _WIN32_IE_XPSP2 = _WIN32_IE_IE60SP2;
+enum _WIN32_IE_WS03 = 0x0602;
+enum _WIN32_IE_WS03SP1 = _WIN32_IE_IE60SP2;
+enum _WIN32_IE_WIN6 = _WIN32_IE_IE70;
+enum _WIN32_IE_LONGHORN = _WIN32_IE_IE70;
+enum _WIN32_IE_WIN7 = _WIN32_IE_IE80;
+enum _WIN32_IE_WIN8 = _WIN32_IE_IE100;
+enum _WIN32_IE_WINBLUE = _WIN32_IE_IE100;
+
+
+enum NTDDI_WIN2K = 0x05000000;
+enum NTDDI_WIN2KSP1 = 0x05000100;
+enum NTDDI_WIN2KSP2 = 0x05000200;
+enum NTDDI_WIN2KSP3 = 0x05000300;
+enum NTDDI_WIN2KSP4 = 0x05000400;
+
+enum NTDDI_WINXP = 0x05010000;
+enum NTDDI_WINXPSP1 = 0x05010100;
+enum NTDDI_WINXPSP2 = 0x05010200;
+enum NTDDI_WINXPSP3 = 0x05010300;
+enum NTDDI_WINXPSP4 = 0x05010400;
+
+enum NTDDI_WS03 = 0x05020000;
+enum NTDDI_WS03SP1 = 0x05020100;
+enum NTDDI_WS03SP2 = 0x05020200;
+enum NTDDI_WS03SP3 = 0x05020300;
+enum NTDDI_WS03SP4 = 0x05020400;
+
+enum NTDDI_WIN6 = 0x06000000;
+enum NTDDI_WIN6SP1 = 0x06000100;
+enum NTDDI_WIN6SP2 = 0x06000200;
+enum NTDDI_WIN6SP3 = 0x06000300;
+enum NTDDI_WIN6SP4 = 0x06000400;
+
+enum NTDDI_VISTA = NTDDI_WIN6;
+enum NTDDI_VISTASP1 = NTDDI_WIN6SP1;
+enum NTDDI_VISTASP2 = NTDDI_WIN6SP2;
+enum NTDDI_VISTASP3 = NTDDI_WIN6SP3;
+enum NTDDI_VISTASP4 = NTDDI_WIN6SP4;
+
+enum NTDDI_LONGHORN = NTDDI_VISTA;
+
+enum NTDDI_WS08 = NTDDI_WIN6SP1;
+enum NTDDI_WS08SP2 = NTDDI_WIN6SP2;
+enum NTDDI_WS08SP3 = NTDDI_WIN6SP3;
+enum NTDDI_WS08SP4 = NTDDI_WIN6SP4;
+
+enum NTDDI_WIN7 = 0x06010000;
+enum NTDDI_WIN8 = 0x06020000;
+enum NTDDI_WINBLUE = 0x06030000;
+
+enum OSVERSION_MASK = 0xFFFF0000;
+enum SPVERSION_MASK = 0x0000FF00;
+enum SUBVERSION_MASK = 0x000000FF;
+
+enum _WIN32_WINNT = 0x0603;
+
+enum NTDDI_VERSION = 0x06030000;
+enum WINVER = _WIN32_WINNT;
diff --git a/libphobos/libdruntime/core/sys/windows/secext.d b/libphobos/libdruntime/core/sys/windows/secext.d
index 486025d..dd4ec85 100644
--- a/libphobos/libdruntime/core/sys/windows/secext.d
+++ b/libphobos/libdruntime/core/sys/windows/secext.d
@@ -9,11 +9,12 @@
// Don't include this file directly, use core.sys.windows.security instead.
module core.sys.windows.secext;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "secur32");
-private import core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.windef;
static assert (_WIN32_WINNT >= 0x501,
"SecExt is only available on WindowsXP and later");
diff --git a/libphobos/libdruntime/core/sys/windows/security.d b/libphobos/libdruntime/core/sys/windows/security.d
index a5f5785..2dc7c19 100644
--- a/libphobos/libdruntime/core/sys/windows/security.d
+++ b/libphobos/libdruntime/core/sys/windows/security.d
@@ -3,44 +3,118 @@
*
* Translated from MinGW Windows headers
*
- * Authors: Ellery Newcomer
+ * Authors: Ellery Newcomer, John Colvin
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC src/core/sys/windows/_security.d)
*/
module core.sys.windows.security;
version (Windows):
+@system:
-enum :SECURITY_STATUS{
- SEC_E_OK = 0,
- SEC_E_CERT_EXPIRED = (-2146893016),
- SEC_E_INCOMPLETE_MESSAGE = (-2146893032),
- SEC_E_INSUFFICIENT_MEMORY = (-2146893056),
- SEC_E_INTERNAL_ERROR = (-2146893052),
- SEC_E_INVALID_HANDLE = (-2146893055),
- SEC_E_INVALID_TOKEN = (-2146893048),
- SEC_E_LOGON_DENIED = (-2146893044),
- SEC_E_NO_AUTHENTICATING_AUTHORITY = (-2146893039),
- SEC_E_NO_CREDENTIALS = (-2146893042),
- SEC_E_TARGET_UNKNOWN = (-2146893053),
- SEC_E_UNSUPPORTED_FUNCTION = (-2146893054),
- SEC_E_UNTRUSTED_ROOT = (-2146893019),
- SEC_E_WRONG_PRINCIPAL = (-2146893022),
- SEC_E_SECPKG_NOT_FOUND = (-2146893051),
- SEC_E_QOP_NOT_SUPPORTED = (-2146893046),
- SEC_E_UNKNOWN_CREDENTIALS = (-2146893043),
- SEC_E_NOT_OWNER = (-2146893050),
+enum : SECURITY_STATUS
+{
+ SEC_E_OK = 0x00000000,
+ SEC_E_INSUFFICIENT_MEMORY = 0x80090300,
+ SEC_E_INVALID_HANDLE = 0x80090301,
+ SEC_E_UNSUPPORTED_FUNCTION = 0x80090302,
+ SEC_E_TARGET_UNKNOWN = 0x80090303,
+ SEC_E_INTERNAL_ERROR = 0x80090304,
+ SEC_E_SECPKG_NOT_FOUND = 0x80090305,
+ SEC_E_NOT_OWNER = 0x80090306,
+ SEC_E_CANNOT_INSTALL = 0x80090307,
+ SEC_E_INVALID_TOKEN = 0x80090308,
+ SEC_E_CANNOT_PACK = 0x80090309,
+ SEC_E_QOP_NOT_SUPPORTED = 0x8009030A,
+ SEC_E_NO_IMPERSONATION = 0x8009030B,
+ SEC_E_LOGON_DENIED = 0x8009030C,
+ SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D,
+ SEC_E_NO_CREDENTIALS = 0x8009030E,
+ SEC_E_MESSAGE_ALTERED = 0x8009030F,
+ SEC_E_OUT_OF_SEQUENCE = 0x80090310,
+ SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311,
+ SEC_E_BAD_PKGID = 0x80090316,
+ SEC_E_CONTEXT_EXPIRED = 0x80090317,
+ SEC_E_INCOMPLETE_MESSAGE = 0x80090318,
+ SEC_E_INCOMPLETE_CREDENTIALS = 0x80090320,
+ SEC_E_BUFFER_TOO_SMALL = 0x80090321,
+ SEC_E_WRONG_PRINCIPAL = 0x80090322,
+ SEC_E_TIME_SKEW = 0x80090324,
+ SEC_E_UNTRUSTED_ROOT = 0x80090325,
+ SEC_E_ILLEGAL_MESSAGE = 0x80090326,
+ SEC_E_CERT_UNKNOWN = 0x80090327,
+ SEC_E_CERT_EXPIRED = 0x80090328,
+ SEC_E_ENCRYPT_FAILURE = 0x80090329,
+ SEC_E_DECRYPT_FAILURE = 0x80090330,
+ SEC_E_ALGORITHM_MISMATCH = 0x80090331,
+ SEC_E_SECURITY_QOS_FAILED = 0x80090332,
+ SEC_E_UNFINISHED_CONTEXT_DELETED = 0x80090333,
+ SEC_E_NO_TGT_REPLY = 0x80090334,
+ SEC_E_NO_IP_ADDRESSES = 0x80090335,
+ SEC_E_WRONG_CREDENTIAL_HANDLE = 0x80090336,
+ SEC_E_CRYPTO_SYSTEM_INVALID = 0x80090337,
+ SEC_E_MAX_REFERRALS_EXCEEDED = 0x80090338,
+ SEC_E_MUST_BE_KDC = 0x80090339,
+ SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = 0x8009033A,
+ SEC_E_TOO_MANY_PRINCIPALS = 0x8009033B,
+ SEC_E_NO_PA_DATA = 0x8009033C,
+ SEC_E_PKINIT_NAME_MISMATCH = 0x8009033D,
+ SEC_E_SMARTCARD_LOGON_REQUIRED = 0x8009033E,
+ SEC_E_SHUTDOWN_IN_PROGRESS = 0x8009033F,
+ SEC_E_KDC_INVALID_REQUEST = 0x80090340,
+ SEC_E_KDC_UNABLE_TO_REFER = 0x80090341,
+ SEC_E_KDC_UNKNOWN_ETYPE = 0x80090342,
+ SEC_E_UNSUPPORTED_PREAUTH = 0x80090343,
+ SEC_E_DELEGATION_REQUIRED = 0x80090345,
+ SEC_E_BAD_BINDINGS = 0x80090346,
+ SEC_E_MULTIPLE_ACCOUNTS = 0x80090347,
+ SEC_E_NO_KERB_KEY = 0x80090348,
+ SEC_E_CERT_WRONG_USAGE = 0x80090349,
+ SEC_E_DOWNGRADE_DETECTED = 0x80090350,
+ SEC_E_SMARTCARD_CERT_REVOKED = 0x80090351,
+ SEC_E_ISSUING_CA_UNTRUSTED = 0x80090352,
+ SEC_E_REVOCATION_OFFLINE_C = 0x80090353,
+ SEC_E_PKINIT_CLIENT_FAILURE = 0x80090354,
+ SEC_E_SMARTCARD_CERT_EXPIRED = 0x80090355,
+ SEC_E_NO_S4U_PROT_SUPPORT = 0x80090356,
+ SEC_E_CROSSREALM_DELEGATION_FAILURE = 0x80090357,
+ SEC_E_REVOCATION_OFFLINE_KDC = 0x80090358,
+ SEC_E_ISSUING_CA_UNTRUSTED_KDC = 0x80090359,
+ SEC_E_KDC_CERT_EXPIRED = 0x8009035A,
+ SEC_E_KDC_CERT_REVOKED = 0x8009035B,
+ SEC_E_INVALID_PARAMETER = 0x8009035D,
+ SEC_E_DELEGATION_POLICY = 0x8009035E,
+ SEC_E_POLICY_NLTM_ONLY = 0x8009035F,
+ SEC_E_NO_CONTEXT = 0x80090361,
+ SEC_E_PKU2U_CERT_FAILURE = 0x80090362,
+ SEC_E_MUTUAL_AUTH_FAILED = 0x80090363,
+ SEC_E_ONLY_HTTPS_ALLOWED = 0x80090365,
+ SEC_E_APPLICATION_PROTOCOL_MISMATCH = 0x80090367,
+ SEC_E_INVALID_UPN_NAME = 0x80090369,
+ SEC_E_EXT_BUFFER_TOO_SMALL = 0x8009036A,
+ SEC_E_INSUFFICIENT_BUFFERS = 0x8009036B,
+ SEC_E_NO_SPM = SEC_E_INTERNAL_ERROR,
+ SEC_E_NOT_SUPPORTED = SEC_E_UNSUPPORTED_FUNCTION
}
-enum :SECURITY_STATUS {
- SEC_I_RENEGOTIATE = 590625,
- SEC_I_COMPLETE_AND_CONTINUE = 590612,
- SEC_I_COMPLETE_NEEDED = 590611,
- SEC_I_CONTINUE_NEEDED = 590610,
- SEC_I_INCOMPLETE_CREDENTIALS = 590624,
+enum : SECURITY_STATUS
+{
+ SEC_I_CONTINUE_NEEDED = 0x00090312,
+ SEC_I_COMPLETE_NEEDED = 0x00090313,
+ SEC_I_COMPLETE_AND_CONTINUE = 0x00090314,
+ SEC_I_LOCAL_LOGON = 0x00090315,
+ SEC_I_GENERIC_EXTENSION_RECEIVED = 0x00090316,
+ SEC_I_CONTEXT_EXPIRED = 0x00090317,
+ SEC_I_INCOMPLETE_CREDENTIALS = 0x00090320,
+ SEC_I_RENEGOTIATE = 0x00090321,
+ SEC_I_NO_LSA_CONTEXT = 0x00090323,
+ SEC_I_SIGNATURE_NEEDED = 0x0009035C,
+ SEC_I_NO_RENEGOTIATION = 0x00090360,
+ SEC_I_MESSAGE_FRAGMENT = 0x00090364,
+ SEC_I_CONTINUE_NEEDED_MESSAGE_OK = 0x00090366,
+ SEC_I_ASYNC_CALL_PENDING = 0x00090368,
}
/* always a char */
-alias char SEC_CHAR;
-alias wchar SEC_WCHAR;
-
-alias int SECURITY_STATUS;
+alias SEC_CHAR = char;
+alias SEC_WCHAR = wchar;
+alias SECURITY_STATUS = int;
diff --git a/libphobos/libdruntime/core/sys/windows/servprov.d b/libphobos/libdruntime/core/sys/windows/servprov.d
index 91a0a11..1c061dd 100644
--- a/libphobos/libdruntime/core/sys/windows/servprov.d
+++ b/libphobos/libdruntime/core/sys/windows/servprov.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.servprov;
version (Windows):
+@system:
-private import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
+import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
interface IServiceProvider : IUnknown {
HRESULT QueryService(REFGUID, REFIID, void**);
diff --git a/libphobos/libdruntime/core/sys/windows/setupapi.d b/libphobos/libdruntime/core/sys/windows/setupapi.d
index 8df96b1..432ff35 100644
--- a/libphobos/libdruntime/core/sys/windows/setupapi.d
+++ b/libphobos/libdruntime/core/sys/windows/setupapi.d
@@ -9,13 +9,14 @@
*/
module core.sys.windows.setupapi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "setupapi");
-private import core.sys.windows.basetyps, core.sys.windows.commctrl, core.sys.windows.prsht, core.sys.windows.w32api,
+import core.sys.windows.basetyps, core.sys.windows.commctrl, core.sys.windows.prsht, core.sys.windows.w32api,
core.sys.windows.winreg, core.sys.windows.windef;
-private import core.sys.windows.winbase; // for SYSTEMTIME
+import core.sys.windows.winbase; // for SYSTEMTIME
/*static if (_WIN32_WINNT < _WIN32_WINDOWS) {
enum UINT _SETUPAPI_VER = _WIN32_WINNT; // SetupAPI version follows Windows NT version
diff --git a/libphobos/libdruntime/core/sys/windows/shellapi.d b/libphobos/libdruntime/core/sys/windows/shellapi.d
index 26c6f78..2b7f145 100644
--- a/libphobos/libdruntime/core/sys/windows/shellapi.d
+++ b/libphobos/libdruntime/core/sys/windows/shellapi.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.shellapi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "shell32");
-private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.basetyps;
+import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.basetyps;
enum : UINT {
ABE_LEFT,
diff --git a/libphobos/libdruntime/core/sys/windows/shldisp.d b/libphobos/libdruntime/core/sys/windows/shldisp.d
index 876d4d7..70cf884 100644
--- a/libphobos/libdruntime/core/sys/windows/shldisp.d
+++ b/libphobos/libdruntime/core/sys/windows/shldisp.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.shldisp;
version (Windows):
+@system:
-private import core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
+import core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;
// options for IAutoComplete2
enum DWORD ACO_AUTOSUGGEST = 0x01;
diff --git a/libphobos/libdruntime/core/sys/windows/shlguid.d b/libphobos/libdruntime/core/sys/windows/shlguid.d
index e2bbf02..15e6138 100644
--- a/libphobos/libdruntime/core/sys/windows/shlguid.d
+++ b/libphobos/libdruntime/core/sys/windows/shlguid.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.shlguid;
version (Windows):
+@system:
-private import core.sys.windows.basetyps, core.sys.windows.w32api;
+import core.sys.windows.basetyps, core.sys.windows.w32api;
// FIXME: clean up Windows version support
diff --git a/libphobos/libdruntime/core/sys/windows/shlobj.d b/libphobos/libdruntime/core/sys/windows/shlobj.d
index 19b4426..5f921b3 100644
--- a/libphobos/libdruntime/core/sys/windows/shlobj.d
+++ b/libphobos/libdruntime/core/sys/windows/shlobj.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.shlobj;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "shell32");
@@ -17,10 +18,10 @@ pragma(lib, "shell32");
// SHGetFolderPath in shfolder.dll on W9x, NT4, also in shell32.dll on W2K
import core.sys.windows.commctrl, core.sys.windows.ole2, core.sys.windows.shlguid, core.sys.windows.shellapi;
-private import core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.w32api, core.sys.windows.winbase,
+import core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.w32api, core.sys.windows.winbase,
core.sys.windows.winnt, core.sys.windows.winuser, core.sys.windows.wtypes, core.sys.windows.objfwd, core.sys.windows.objidl;
-private import core.sys.windows.winnetwk; // for NETRESOURCE
-private import core.sys.windows.oaidl : VARIANT;
+import core.sys.windows.winnetwk; // for NETRESOURCE
+import core.sys.windows.oaidl : VARIANT;
// FIXME: clean up Windows version support
@@ -691,7 +692,7 @@ alias IContextMenu LPCONTEXTMENU;
interface IContextMenu2 : IContextMenu {
HRESULT HandleMenuMsg(UINT, WPARAM, LPARAM);
-};
+}
alias IContextMenu2 LPCONTEXTMENU2;
static if (_WIN32_IE >= 0x500) {
@@ -770,7 +771,7 @@ alias IShellPropSheetExt LPSHELLPROPSHEETEXT;
interface IExtractIconA : IUnknown {
HRESULT GetIconLocation(UINT, LPSTR, UINT, int*, PUINT);
HRESULT Extract(LPCSTR, UINT, HICON*, HICON*, UINT);
-};
+}
alias IExtractIconA LPEXTRACTICONA;
interface IExtractIconW : IUnknown {
@@ -855,16 +856,6 @@ interface IEnumExtraSearch: IUnknown {
alias IEnumExtraSearch LPENUMEXTRASEARCH;
interface IShellFolder2 : IShellFolder {
- HRESULT ParseDisplayName(HWND, LPBC, LPOLESTR, PULONG, LPITEMIDLIST*, PULONG);
- HRESULT EnumObjects(HWND, DWORD, LPENUMIDLIST*);
- HRESULT BindToObject(LPCITEMIDLIST, LPBC, REFIID, PVOID*);
- HRESULT BindToStorage(LPCITEMIDLIST, LPBC, REFIID, PVOID*);
- HRESULT CompareIDs(LPARAM, LPCITEMIDLIST, LPCITEMIDLIST);
- HRESULT CreateViewObject(HWND, REFIID, PVOID*);
- HRESULT GetAttributesOf(UINT, LPCITEMIDLIST*, PULONG);
- HRESULT GetUIObjectOf(HWND, UINT, LPCITEMIDLIST*, REFIID, PUINT, PVOID*);
- HRESULT GetDisplayNameOf(LPCITEMIDLIST, DWORD, LPSTRRET);
- HRESULT SetNameOf(HWND, LPCITEMIDLIST, LPCOLESTR, DWORD, LPITEMIDLIST*);
HRESULT GetDefaultSearchGUID(GUID*);
HRESULT EnumSearches(IEnumExtraSearch*);
HRESULT GetDefaultColumn(DWORD, ULONG*, ULONG*);
diff --git a/libphobos/libdruntime/core/sys/windows/shlwapi.d b/libphobos/libdruntime/core/sys/windows/shlwapi.d
index 64e9796..8cb21ef 100644
--- a/libphobos/libdruntime/core/sys/windows/shlwapi.d
+++ b/libphobos/libdruntime/core/sys/windows/shlwapi.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.shlwapi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "shlwapi");
@@ -27,7 +28,7 @@ wnsprintf functions are not included.
*/
import core.sys.windows.objbase, core.sys.windows.shlobj;
-private import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef,
+import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef,
core.sys.windows.winbase, core.sys.windows.winreg;
enum DLLVER_PLATFORM_WINDOWS = 0x00000001;
diff --git a/libphobos/libdruntime/core/sys/windows/snmp.d b/libphobos/libdruntime/core/sys/windows/snmp.d
index 4f55018..ea64e0d 100644
--- a/libphobos/libdruntime/core/sys/windows/snmp.d
+++ b/libphobos/libdruntime/core/sys/windows/snmp.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.snmp;
version (Windows):
+@system:
-private import core.sys.windows.basetsd /+: HANDLE+/;
-private import core.sys.windows.windef /+: BOOL, BYTE, DWORD, INT, LONG, UINT, ULONG+/;
-private import core.sys.windows.winnt /+: LPSTR, LPVOID, ULARGE_INTEGER, VOID+/;
+import core.sys.windows.basetsd /+: HANDLE+/;
+import core.sys.windows.windef /+: BOOL, BYTE, DWORD, INT, LONG, UINT, ULONG+/;
+import core.sys.windows.winnt /+: LPSTR, LPVOID, ULARGE_INTEGER, VOID+/;
// These are not documented on MSDN
enum {
diff --git a/libphobos/libdruntime/core/sys/windows/sql.d b/libphobos/libdruntime/core/sys/windows/sql.d
index 4eb2cfb..177a48d 100644
--- a/libphobos/libdruntime/core/sys/windows/sql.d
+++ b/libphobos/libdruntime/core/sys/windows/sql.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.sql;
version (Windows):
+@system:
public import core.sys.windows.sqltypes;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum ODBCVER = 0x0351;
diff --git a/libphobos/libdruntime/core/sys/windows/sqlext.d b/libphobos/libdruntime/core/sys/windows/sqlext.d
index 842f721..3acfc5a 100644
--- a/libphobos/libdruntime/core/sys/windows/sqlext.d
+++ b/libphobos/libdruntime/core/sys/windows/sqlext.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.sqlext;
version (Windows):
+@system:
/* Conversion notes:
The MinGW file was a horrible mess. All of the #defines were sorted alphabetically,
@@ -17,7 +18,7 @@ version (Windows):
*/
public import core.sys.windows.sql;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum SQL_SPEC_MAJOR = 3;
enum SQL_SPEC_MINOR = 51;
diff --git a/libphobos/libdruntime/core/sys/windows/sqltypes.d b/libphobos/libdruntime/core/sys/windows/sqltypes.d
index 288b20e..aaffeb2 100644
--- a/libphobos/libdruntime/core/sys/windows/sqltypes.d
+++ b/libphobos/libdruntime/core/sys/windows/sqltypes.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.sqltypes;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
@@ -15,8 +16,8 @@ version (ANSI) {} else version = Unicode;
It's assumed that ODBC >= 0x0300.
*/
-private import core.sys.windows.windef;
-private import core.sys.windows.basetyps; // for GUID
+import core.sys.windows.windef;
+import core.sys.windows.basetyps; // for GUID
alias byte SCHAR, SQLSCHAR;
alias int SDWORD, SLONG, SQLINTEGER;
diff --git a/libphobos/libdruntime/core/sys/windows/sqlucode.d b/libphobos/libdruntime/core/sys/windows/sqlucode.d
index 6a5a48c..21f47f6 100644
--- a/libphobos/libdruntime/core/sys/windows/sqlucode.d
+++ b/libphobos/libdruntime/core/sys/windows/sqlucode.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.sqlucode;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.sqlext;
+import core.sys.windows.sqlext;
enum SQL_WCHAR = -8;
enum SQL_WVARCHAR = -9;
diff --git a/libphobos/libdruntime/core/sys/windows/sspi.d b/libphobos/libdruntime/core/sys/windows/sspi.d
index 9f72368..cf41298 100644
--- a/libphobos/libdruntime/core/sys/windows/sspi.d
+++ b/libphobos/libdruntime/core/sys/windows/sspi.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.sspi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d
index d354ffe..2922e54 100644
--- a/libphobos/libdruntime/core/sys/windows/stacktrace.d
+++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d
@@ -11,9 +11,9 @@
module core.sys.windows.stacktrace;
version (Windows):
+@system:
import core.demangle;
-import core.runtime;
import core.stdc.stdlib;
import core.stdc.string;
import core.sys.windows.dbghelp;
@@ -217,11 +217,6 @@ private:
// do ... while so that we don't skip the first stackframe
do
{
- if ( stackframe.AddrPC.Offset == stackframe.AddrReturn.Offset )
- {
- debug(PRINTF) printf("Endless callstack\n");
- break;
- }
if (frameNum >= skip)
{
result ~= stackframe.AddrPC.Offset;
@@ -255,26 +250,23 @@ private:
char[][] trace;
foreach (pc; addresses)
{
- if ( pc != 0 )
+ char[] res;
+ if (dbghelp.SymGetSymFromAddr64(hProcess, pc, null, symbol) &&
+ *symbol.Name.ptr)
{
- char[] res;
- if (dbghelp.SymGetSymFromAddr64(hProcess, pc, null, symbol) &&
- *symbol.Name.ptr)
- {
- DWORD disp;
- IMAGEHLP_LINEA64 line=void;
- line.SizeOfStruct = IMAGEHLP_LINEA64.sizeof;
-
- if (dbghelp.SymGetLineFromAddr64(hProcess, pc, &disp, &line))
- res = formatStackFrame(cast(void*)pc, symbol.Name.ptr,
- line.FileName, line.LineNumber);
- else
- res = formatStackFrame(cast(void*)pc, symbol.Name.ptr);
- }
+ DWORD disp;
+ IMAGEHLP_LINEA64 line=void;
+ line.SizeOfStruct = IMAGEHLP_LINEA64.sizeof;
+
+ if (dbghelp.SymGetLineFromAddr64(hProcess, pc, &disp, &line))
+ res = formatStackFrame(cast(void*)pc, symbol.Name.ptr,
+ line.FileName, line.LineNumber);
else
- res = formatStackFrame(cast(void*)pc);
- trace ~= res;
+ res = formatStackFrame(cast(void*)pc, symbol.Name.ptr);
}
+ else
+ res = formatStackFrame(cast(void*)pc);
+ trace ~= res;
}
return trace;
}
@@ -307,7 +299,7 @@ private:
}
static char[] formatStackFrame(void* pc, char* symName,
- in char* fileName, uint lineNum)
+ const scope char* fileName, uint lineNum)
{
import core.stdc.stdio : snprintf;
char[11] buf=void;
diff --git a/libphobos/libdruntime/core/sys/windows/stat.d b/libphobos/libdruntime/core/sys/windows/stat.d
index 03d219b..c9ee6ce 100644
--- a/libphobos/libdruntime/core/sys/windows/stat.d
+++ b/libphobos/libdruntime/core/sys/windows/stat.d
@@ -6,6 +6,7 @@ module core.sys.windows.stat;
version (Windows):
extern (C) nothrow @nogc:
+@system:
// Posix version is in core.sys.posix.sys.stat
diff --git a/libphobos/libdruntime/core/sys/windows/stdc/malloc.d b/libphobos/libdruntime/core/sys/windows/stdc/malloc.d
new file mode 100644
index 0000000..f52ba37
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/windows/stdc/malloc.d
@@ -0,0 +1,26 @@
+/**
+ * D header file for Windows malloc.h.
+ *
+ * Translated from MinGW Windows headers
+ *
+ * Authors: Iain Buclaw
+ * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Source: $(DRUNTIMESRC src/core/sys/windows/stdc/_malloc.d)
+ */
+module core.sys.windows.stdc.malloc;
+version (CRuntime_Microsoft):
+extern (C):
+@system:
+nothrow:
+@nogc:
+
+export void* _recalloc(void*, size_t, size_t);
+
+export void _aligned_free(void*);
+export void* _aligned_malloc(size_t, size_t);
+
+export void* _aligned_offset_malloc(size_t, size_t, size_t);
+export void* _aligned_realloc(void*, size_t, size_t);
+export void* _aligned_recalloc(void*, size_t, size_t, size_t);
+export void* _aligned_offset_realloc(void*, size_t, size_t, size_t);
+export void* _aligned_offset_recalloc(void*, size_t, size_t, size_t, size_t);
diff --git a/libphobos/libdruntime/core/sys/windows/stdc/time.d b/libphobos/libdruntime/core/sys/windows/stdc/time.d
new file mode 100644
index 0000000..97eb4bf
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/windows/stdc/time.d
@@ -0,0 +1,59 @@
+/**
+ * D header file for C99.
+ *
+ * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_time.h.html, _time.h)
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2009.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly,
+ * Alex Rønne Petersen
+ * Source: $(DRUNTIMESRC core/stdc/_time.d)
+ * Standards: ISO/IEC 9899:1999 (E)
+ */
+
+module core.sys.windows.stdc.time;
+
+version (Windows):
+
+import core.stdc.config;
+
+extern (C):
+@trusted: // There are only a few functions here that use unsafe C strings.
+nothrow:
+@nogc:
+
+///
+struct tm
+{
+ int tm_sec; /// seconds after the minute - [0, 60]
+ int tm_min; /// minutes after the hour - [0, 59]
+ int tm_hour; /// hours since midnight - [0, 23]
+ int tm_mday; /// day of the month - [1, 31]
+ int tm_mon; /// months since January - [0, 11]
+ int tm_year; /// years since 1900
+ int tm_wday; /// days since Sunday - [0, 6]
+ int tm_yday; /// days since January 1 - [0, 365]
+ int tm_isdst; /// Daylight Saving Time flag
+}
+
+///
+alias c_long time_t;
+///
+alias c_long clock_t;
+
+enum clock_t CLOCKS_PER_SEC = 1000;
+clock_t clock();
+
+///
+void tzset(); // non-standard
+///
+void _tzset(); // non-standard
+///
+@system char* _strdate(return scope char* s); // non-standard
+///
+@system char* _strtime(return scope char* s); // non-standard
+
+///
+extern __gshared const(char)*[2] tzname; // non-standard
diff --git a/libphobos/libdruntime/core/sys/windows/subauth.d b/libphobos/libdruntime/core/sys/windows/subauth.d
index 9d39a90..42d2fa7 100644
--- a/libphobos/libdruntime/core/sys/windows/subauth.d
+++ b/libphobos/libdruntime/core/sys/windows/subauth.d
@@ -8,8 +8,9 @@
*/
module core.sys.windows.subauth;
version (Windows):
+@system:
-private import core.sys.windows.ntdef, core.sys.windows.windef;
+import core.sys.windows.ntdef, core.sys.windows.windef;
/+
alias LONG NTSTATUS;
diff --git a/libphobos/libdruntime/core/sys/windows/threadaux.d b/libphobos/libdruntime/core/sys/windows/threadaux.d
index e3bdd40..34fda65 100644
--- a/libphobos/libdruntime/core/sys/windows/threadaux.d
+++ b/libphobos/libdruntime/core/sys/windows/threadaux.d
@@ -14,6 +14,7 @@
*/
module core.sys.windows.threadaux;
version (Windows):
+@system:
import core.sys.windows.basetsd/+ : HANDLE+/;
import core.sys.windows.winbase/+ : CloseHandle, GetCurrentThreadId, GetCurrentProcessId,
@@ -171,7 +172,7 @@ struct thread_aux
version (GNU_InlineAsm)
{
void** teb;
- asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" teb; }
+ asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" (teb); }
return teb;
}
else
@@ -189,7 +190,7 @@ struct thread_aux
version (GNU_InlineAsm)
{
void** teb;
- asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" teb; }
+ asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" (teb); }
return teb;
}
else
diff --git a/libphobos/libdruntime/core/sys/windows/tlhelp32.d b/libphobos/libdruntime/core/sys/windows/tlhelp32.d
index 3a3959f..308c5a4 100644
--- a/libphobos/libdruntime/core/sys/windows/tlhelp32.d
+++ b/libphobos/libdruntime/core/sys/windows/tlhelp32.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.tlhelp32;
version (Windows):
+@system:
pragma(lib, "kernel32");
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
enum : uint {
HF32_DEFAULT = 1,
diff --git a/libphobos/libdruntime/core/sys/windows/tmschema.d b/libphobos/libdruntime/core/sys/windows/tmschema.d
index ad62d0e..ea7863a 100644
--- a/libphobos/libdruntime/core/sys/windows/tmschema.d
+++ b/libphobos/libdruntime/core/sys/windows/tmschema.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.tmschema;
version (Windows):
+@system:
/* BUTTON parts */
enum {
diff --git a/libphobos/libdruntime/core/sys/windows/unknwn.d b/libphobos/libdruntime/core/sys/windows/unknwn.d
index 8bcbc3c..1c3e453 100644
--- a/libphobos/libdruntime/core/sys/windows/unknwn.d
+++ b/libphobos/libdruntime/core/sys/windows/unknwn.d
@@ -8,9 +8,10 @@
*/
module core.sys.windows.unknwn;
version (Windows):
+@system:
import core.sys.windows.objfwd, core.sys.windows.windef, core.sys.windows.wtypes;
-private import core.sys.windows.basetyps;
+import core.sys.windows.basetyps;
extern (Windows) {
void* MIDL_user_allocate(size_t);
diff --git a/libphobos/libdruntime/core/sys/windows/uuid.d b/libphobos/libdruntime/core/sys/windows/uuid.d
index d3b979d..7e8d4b9 100644
--- a/libphobos/libdruntime/core/sys/windows/uuid.d
+++ b/libphobos/libdruntime/core/sys/windows/uuid.d
@@ -1,5 +1,6 @@
module core.sys.windows.uuid;
version (Windows):
+@system:
import core.sys.windows.basetyps;
diff --git a/libphobos/libdruntime/core/sys/windows/vfw.d b/libphobos/libdruntime/core/sys/windows/vfw.d
index 4d168b3..3ffff20 100644
--- a/libphobos/libdruntime/core/sys/windows/vfw.d
+++ b/libphobos/libdruntime/core/sys/windows/vfw.d
@@ -9,6 +9,7 @@
module core.sys.windows.vfw;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "vfw32");
diff --git a/libphobos/libdruntime/core/sys/windows/w32api.d b/libphobos/libdruntime/core/sys/windows/w32api.d
index 33807c9..a392d59 100644
--- a/libphobos/libdruntime/core/sys/windows/w32api.d
+++ b/libphobos/libdruntime/core/sys/windows/w32api.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.w32api;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
@@ -24,7 +25,7 @@ enum __W32API_MINOR_VERSION = 17;
* removed in order to simplify the bindings.
*/
version (Windows10) {
- enum uint _WIN32_WINNT = 0x604;
+ enum uint _WIN32_WINNT = 0xA00;
} else version (Windows8_1) { // also Windows2012R2
enum uint _WIN32_WINNT = 0x603;
} else version (Windows8) { // also Windows2012
@@ -45,7 +46,9 @@ enum __W32API_MINOR_VERSION = 17;
enum uint _WIN32_WINNT = 0x501;
}
-version (IE10) {
+version (IE11) {
+ enum uint _WIN32_IE = 0xA00;
+} else version (IE10) {
enum uint _WIN32_IE = 0xA00;
} else version (IE9) {
enum uint _WIN32_IE = 0x900;
@@ -61,6 +64,8 @@ version (IE10) {
enum uint _WIN32_IE = 0x600;
} else version (IE56) {
enum uint _WIN32_IE = 0x560;
+} else version (IE55) {
+ enum uint _WIN32_IE = 0x550;
} else version (IE501) {
enum uint _WIN32_IE = 0x501;
} else version (IE5) {
@@ -71,6 +76,8 @@ version (IE10) {
enum uint _WIN32_IE = 0x400;
} else version (IE3) {
enum uint _WIN32_IE = 0x300;
+} else static if (_WIN32_WINNT >= 0x500) {
+ enum uint _WIN32_IE = 0x600;
} else static if (_WIN32_WINNT >= 0x410) {
enum uint _WIN32_IE = 0x400;
} else {
diff --git a/libphobos/libdruntime/core/sys/windows/winbase.d b/libphobos/libdruntime/core/sys/windows/winbase.d
index 280c468..a9844de 100644
--- a/libphobos/libdruntime/core/sys/windows/winbase.d
+++ b/libphobos/libdruntime/core/sys/windows/winbase.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.winbase;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "kernel32");
@@ -33,7 +34,7 @@ int wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
*/
import core.sys.windows.windef, core.sys.windows.winver;
-private import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winnt;
+import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winnt;
// FIXME:
//alias void va_list;
@@ -1285,9 +1286,17 @@ struct WIN32_STREAM_ID {
}
alias WIN32_STREAM_ID* LPWIN32_STREAM_ID;
-enum FINDEX_INFO_LEVELS {
- FindExInfoStandard,
- FindExInfoMaxInfoLevel
+static if (_WIN32_WINNT >= 0x601) {
+ enum FINDEX_INFO_LEVELS {
+ FindExInfoStandard,
+ FindExInfoBasic,
+ FindExInfoMaxInfoLevel,
+ }
+} else {
+ enum FINDEX_INFO_LEVELS {
+ FindExInfoStandard,
+ FindExInfoMaxInfoLevel,
+ }
}
enum FINDEX_SEARCH_OPS {
@@ -1581,6 +1590,14 @@ static if (_WIN32_WINNT >= 0x410) {
alias DWORD EXECUTION_STATE;
}
+// CreateSymbolicLink
+static if (_WIN32_WINNT >= 0x600) {
+ enum {
+ SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1,
+ SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2
+ }
+}
+
// Callbacks
extern (Windows) {
alias DWORD function(LPVOID) LPTHREAD_START_ROUTINE;
@@ -2242,6 +2259,7 @@ WINBASEAPI BOOL WINAPI SetEvent(HANDLE);
BOOL IsValidAcl(PACL);
BOOL IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
BOOL IsValidSid(PSID);
+ BOOL CreateWellKnownSid(WELL_KNOWN_SID_TYPE, PSID, PSID, PDWORD);
BOOL LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED);
BOOL LogonUserA(LPSTR, LPSTR, LPSTR, DWORD, DWORD, PHANDLE);
BOOL LogonUserW(LPWSTR, LPWSTR, LPWSTR, DWORD, DWORD, PHANDLE);
@@ -2471,6 +2489,11 @@ WINBASEAPI BOOL WINAPI SetEvent(HANDLE);
static if (_WIN32_WINNT >= 0x510) {
VOID RestoreLastError(DWORD);
}
+
+ static if (_WIN32_WINNT >= 0x600) {
+ BOOL CreateSymbolicLinkA(LPCSTR, LPCSTR, DWORD);
+ BOOL CreateSymbolicLinkW(LPCWSTR, LPCWSTR, DWORD);
+ }
}
// For compatibility with old core.sys.windows.windows:
@@ -2656,6 +2679,10 @@ version (Unicode) {
alias GetDllDirectoryW GetDllDirectory;
}
+ static if (_WIN32_WINNT >= 0x600) {
+ alias CreateSymbolicLinkW CreateSymbolicLink;
+ }
+
} else {
//alias STARTUPINFOA STARTUPINFO;
alias WIN32_FIND_DATAA WIN32_FIND_DATA;
@@ -2830,6 +2857,10 @@ version (Unicode) {
alias SetDllDirectoryA SetDllDirectory;
alias SetFirmwareEnvironmentVariableA SetFirmwareEnvironmentVariable;
}
+
+ static if (_WIN32_WINNT >= 0x600) {
+ alias CreateSymbolicLinkA CreateSymbolicLink;
+ }
}
alias STARTUPINFO* LPSTARTUPINFO;
diff --git a/libphobos/libdruntime/core/sys/windows/winber.d b/libphobos/libdruntime/core/sys/windows/winber.d
index 9ff3231..2718903 100644
--- a/libphobos/libdruntime/core/sys/windows/winber.d
+++ b/libphobos/libdruntime/core/sys/windows/winber.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.winber;
version (Windows):
+@system:
/* Comment from MinGW
winber.h - Header file for the Windows LDAP Basic Encoding Rules API
diff --git a/libphobos/libdruntime/core/sys/windows/wincon.d b/libphobos/libdruntime/core/sys/windows/wincon.d
index 6b06c14..67bd17e 100644
--- a/libphobos/libdruntime/core/sys/windows/wincon.d
+++ b/libphobos/libdruntime/core/sys/windows/wincon.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.wincon;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "kernel32");
-private import core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.windef;
// FIXME: clean up Windows version support
diff --git a/libphobos/libdruntime/core/sys/windows/wincrypt.d b/libphobos/libdruntime/core/sys/windows/wincrypt.d
index 0651ea8..9495105 100644
--- a/libphobos/libdruntime/core/sys/windows/wincrypt.d
+++ b/libphobos/libdruntime/core/sys/windows/wincrypt.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.wincrypt;
version (Windows):
+@system:
pragma(lib, "advapi32");
version (ANSI) {} else version = Unicode;
-private import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
/* FIXME:
* Types of some constants
diff --git a/libphobos/libdruntime/core/sys/windows/windef.d b/libphobos/libdruntime/core/sys/windows/windef.d
index 25cf044..f79b593 100644
--- a/libphobos/libdruntime/core/sys/windows/windef.d
+++ b/libphobos/libdruntime/core/sys/windows/windef.d
@@ -9,9 +9,10 @@
*/
module core.sys.windows.windef;
version (Windows):
+@system:
public import core.sys.windows.winnt;
-private import core.sys.windows.w32api;
+import core.sys.windows.w32api;
enum size_t MAX_PATH = 260;
diff --git a/libphobos/libdruntime/core/sys/windows/windows.d b/libphobos/libdruntime/core/sys/windows/windows.d
index 85dc5f4..8b8c8ab 100644
--- a/libphobos/libdruntime/core/sys/windows/windows.d
+++ b/libphobos/libdruntime/core/sys/windows/windows.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.windows;
version (Windows):
+@system:
/*
windows.h - main header file for the Win32 API
diff --git a/libphobos/libdruntime/core/sys/windows/winerror.d b/libphobos/libdruntime/core/sys/windows/winerror.d
index 71a2f98..ab987a3e 100644
--- a/libphobos/libdruntime/core/sys/windows/winerror.d
+++ b/libphobos/libdruntime/core/sys/windows/winerror.d
@@ -8,12 +8,13 @@
*/
module core.sys.windows.winerror;
version (Windows):
+@system:
/* Comments from the Mingw header:
* WAIT_TIMEOUT is also defined in winbase.h
*/
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
alias int SCODE; // was in core.sys.windows.wtypes.
diff --git a/libphobos/libdruntime/core/sys/windows/wingdi.d b/libphobos/libdruntime/core/sys/windows/wingdi.d
index e495b2b..4fc125c 100644
--- a/libphobos/libdruntime/core/sys/windows/wingdi.d
+++ b/libphobos/libdruntime/core/sys/windows/wingdi.d
@@ -8,13 +8,14 @@
*/
module core.sys.windows.wingdi;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "gdi32");
// FIXME: clean up Windows version support
-private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver;
+import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver;
// BITMAPINFOHEADER.biCompression
enum : DWORD {
@@ -2057,13 +2058,13 @@ struct RGBQUAD {
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
-};
+}
alias RGBQUAD* LPRGBQUAD;
struct BITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD[1] bmiColors;
-};
+}
alias BITMAPINFO* PBITMAPINFO, LPBITMAPINFO;
alias int FXPT16DOT16;
diff --git a/libphobos/libdruntime/core/sys/windows/winhttp.d b/libphobos/libdruntime/core/sys/windows/winhttp.d
index a7a343f..e919635 100644
--- a/libphobos/libdruntime/core/sys/windows/winhttp.d
+++ b/libphobos/libdruntime/core/sys/windows/winhttp.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.winhttp;
version (Windows):
+@system:
pragma(lib, "winhttp");
// FIXME: Grouping of constants. Windows SDK doesn't make this entirely clear
// FIXME: Verify WINHTTP_STATUS_CALLBACK function declaration works correctly
diff --git a/libphobos/libdruntime/core/sys/windows/wininet.d b/libphobos/libdruntime/core/sys/windows/wininet.d
index 231c31a..64b95c4 100644
--- a/libphobos/libdruntime/core/sys/windows/wininet.d
+++ b/libphobos/libdruntime/core/sys/windows/wininet.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.wininet;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "wininet");
@@ -17,6 +18,11 @@ pragma(lib, "wininet");
import core.sys.windows.winbase, core.sys.windows.windef;
+// From Winineti.h
+enum {
+ INTERNET_FLAG_BGUPDATE = 0x00000008,
+}
+
enum {
INTERNET_INVALID_PORT_NUMBER = 0,
INTERNET_DEFAULT_FTP_PORT = 21,
@@ -46,8 +52,18 @@ enum : DWORD {
}
enum {
- INTERNET_REQFLAG_FROM_CACHE = 1,
- INTERNET_REQFLAG_ASYNC = 2
+ INTERNET_REQFLAG_FROM_CACHE = 0x00000001,
+ INTERNET_REQFLAG_ASYNC = 0x00000002,
+ INTERNET_REQFLAG_VIA_PROXY = 0x00000004,
+ INTERNET_REQFLAG_NO_HEADERS = 0x00000008,
+ INTERNET_REQFLAG_PASSIVE = 0x00000010,
+ INTERNET_REQFLAG_CACHE_WRITE_DISABLED = 0x00000040,
+ INTERNET_REQFLAG_NET_TIMEOUT = 0x00000080,
+}
+
+enum {
+ INTERNET_FLAG_IDN_DIRECT = 0x00000001,
+ INTERNET_FLAG_IDN_PROXY = 0x00000002
}
enum DWORD
@@ -59,13 +75,16 @@ enum DWORD
INTERNET_FLAG_NO_CACHE_WRITE = 0x04000000,
INTERNET_FLAG_DONT_CACHE = INTERNET_FLAG_NO_CACHE_WRITE,
INTERNET_FLAG_MAKE_PERSISTENT = 0x02000000,
- INTERNET_FLAG_OFFLINE = 0x01000000,
+ INTERNET_FLAG_FROM_CACHE = 0x01000000,
+ INTERNET_FLAG_OFFLINE = INTERNET_FLAG_FROM_CACHE,
INTERNET_FLAG_SECURE = 0x00800000,
INTERNET_FLAG_KEEP_CONNECTION = 0x00400000,
INTERNET_FLAG_NO_AUTO_REDIRECT = 0x00200000,
INTERNET_FLAG_READ_PREFETCH = 0x00100000,
INTERNET_FLAG_NO_COOKIES = 0x00080000,
INTERNET_FLAG_NO_AUTH = 0x00040000,
+ INTERNET_FLAG_RESTRICTED_ZONE = 0x00020000,
+ INTERNET_FLAG_CACHE_IF_NET_FAIL = 0x00010000,
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP = 0x00008000,
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS = 0x00004000,
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000,
@@ -74,14 +93,55 @@ enum DWORD
INTERNET_FLAG_HYPERLINK = 0x00000400,
INTERNET_FLAG_NO_UI = 0x00000200,
INTERNET_FLAG_PRAGMA_NOCACHE = 0x00000100,
- INTERNET_FLAG_MUST_CACHE_REQUEST = 0x00000010,
+ INTERNET_FLAG_CACHE_ASYNC = 0x00000080,
+ INTERNET_FLAG_FORMS_SUBMIT = 0x00000040,
+ INTERNET_FLAG_FWD_BACK = 0x00000020,
+ INTERNET_FLAG_NEED_FILE = 0x00000010,
+ INTERNET_FLAG_MUST_CACHE_REQUEST = INTERNET_FLAG_NEED_FILE,
INTERNET_FLAG_TRANSFER_ASCII = FTP_TRANSFER_TYPE_ASCII,
INTERNET_FLAG_TRANSFER_BINARY = FTP_TRANSFER_TYPE_BINARY,
- SECURITY_INTERNET_MASK = 0x0000F000,
+ SECURITY_INTERNET_MASK = INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
+ INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS |
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP,
+
SECURITY_SET_MASK = SECURITY_INTERNET_MASK,
- INTERNET_FLAGS_MASK = 0xFFFCFE13,
+ INTERNET_FLAGS_MASK = INTERNET_FLAG_RELOAD
+ | INTERNET_FLAG_RAW_DATA
+ | INTERNET_FLAG_EXISTING_CONNECT
+ | INTERNET_FLAG_ASYNC
+ | INTERNET_FLAG_PASSIVE
+ | INTERNET_FLAG_NO_CACHE_WRITE
+ | INTERNET_FLAG_MAKE_PERSISTENT
+ | INTERNET_FLAG_FROM_CACHE
+ | INTERNET_FLAG_SECURE
+ | INTERNET_FLAG_KEEP_CONNECTION
+ | INTERNET_FLAG_NO_AUTO_REDIRECT
+ | INTERNET_FLAG_READ_PREFETCH
+ | INTERNET_FLAG_NO_COOKIES
+ | INTERNET_FLAG_NO_AUTH
+ | INTERNET_FLAG_CACHE_IF_NET_FAIL
+ | SECURITY_INTERNET_MASK
+ | INTERNET_FLAG_RESYNCHRONIZE
+ | INTERNET_FLAG_HYPERLINK
+ | INTERNET_FLAG_NO_UI
+ | INTERNET_FLAG_PRAGMA_NOCACHE
+ | INTERNET_FLAG_CACHE_ASYNC
+ | INTERNET_FLAG_FORMS_SUBMIT
+ | INTERNET_FLAG_NEED_FILE
+ | INTERNET_FLAG_RESTRICTED_ZONE
+ | INTERNET_FLAG_TRANSFER_BINARY
+ | INTERNET_FLAG_TRANSFER_ASCII
+ | INTERNET_FLAG_FWD_BACK
+ | INTERNET_FLAG_BGUPDATE,
+
+ INTERNET_ERROR_MASK_INSERT_CDROM = 0x1,
+ INTERNET_ERROR_MASK_COMBINED_SEC_CERT = 0x2,
+ INTERNET_ERROR_MASK_NEED_MSN_SSPI_PKG = 0X4,
+ INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY = 0x8,
+
INTERNET_OPTIONS_MASK = ~INTERNET_FLAGS_MASK;
enum INTERNET_NO_CALLBACK = 0;
@@ -122,9 +182,8 @@ enum {
INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT = INTERNET_OPTION_RECEIVE_TIMEOUT,
INTERNET_OPTION_DATA_SEND_TIMEOUT,
INTERNET_OPTION_DATA_RECEIVE_TIMEOUT,
- INTERNET_OPTION_HANDLE_TYPE,
- INTERNET_OPTION_CONTEXT_VALUE,
- INTERNET_OPTION_LISTEN_TIMEOUT,
+ INTERNET_OPTION_HANDLE_TYPE = 9,
+ INTERNET_OPTION_LISTEN_TIMEOUT = 11,
INTERNET_OPTION_READ_BUFFER_SIZE,
INTERNET_OPTION_WRITE_BUFFER_SIZE, // = 13
INTERNET_OPTION_ASYNC_ID = 15,
@@ -152,9 +211,73 @@ enum {
INTERNET_OPTION_END_BROWSER_SESSION,
INTERNET_OPTION_PROXY_USERNAME,
INTERNET_OPTION_PROXY_PASSWORD, // = 44
- INTERNET_FIRST_OPTION = INTERNET_OPTION_CALLBACK,
- // why?
- INTERNET_LAST_OPTION = INTERNET_OPTION_USER_AGENT
+ INTERNET_OPTION_CONTEXT_VALUE = 45,
+ INTERNET_OPTION_CONNECT_LIMIT = 46,
+ INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT= 47,
+ INTERNET_OPTION_POLICY = 48,
+ INTERNET_OPTION_DISCONNECTED_TIMEOUT = 49,
+ INTERNET_OPTION_CONNECTED_STATE = 50,
+ INTERNET_OPTION_IDLE_STATE = 51,
+ INTERNET_OPTION_OFFLINE_SEMANTICS = 52,
+ INTERNET_OPTION_SECONDARY_CACHE_KEY = 53,
+ INTERNET_OPTION_CALLBACK_FILTER = 54,
+ INTERNET_OPTION_CONNECT_TIME = 55,
+ INTERNET_OPTION_SEND_THROUGHPUT = 56,
+ INTERNET_OPTION_RECEIVE_THROUGHPUT = 57,
+ INTERNET_OPTION_REQUEST_PRIORITY = 58,
+ INTERNET_OPTION_HTTP_VERSION = 59,
+ INTERNET_OPTION_RESET_URLCACHE_SESSION = 60,
+ INTERNET_OPTION_ERROR_MASK = 62,
+ INTERNET_OPTION_FROM_CACHE_TIMEOUT = 63,
+ INTERNET_OPTION_BYPASS_EDITED_ENTRY = 64,
+ INTERNET_OPTION_HTTP_DECODING = 65,
+ INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO = 67,
+ INTERNET_OPTION_CODEPAGE = 68,
+ INTERNET_OPTION_CACHE_TIMESTAMPS = 69,
+ INTERNET_OPTION_DISABLE_AUTODIAL = 70,
+ INTERNET_OPTION_MAX_CONNS_PER_SERVER = 73,
+ INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER= 74,
+ INTERNET_OPTION_PER_CONNECTION_OPTION = 75,
+ INTERNET_OPTION_DIGEST_AUTH_UNLOAD = 76,
+ INTERNET_OPTION_IGNORE_OFFLINE = 77,
+ INTERNET_OPTION_IDENTITY = 78,
+ INTERNET_OPTION_REMOVE_IDENTITY = 79,
+ INTERNET_OPTION_ALTER_IDENTITY = 80,
+ INTERNET_OPTION_SUPPRESS_BEHAVIOR = 81,
+ INTERNET_OPTION_AUTODIAL_MODE = 82,
+ INTERNET_OPTION_AUTODIAL_CONNECTION = 83,
+ INTERNET_OPTION_CLIENT_CERT_CONTEXT = 84,
+ INTERNET_OPTION_AUTH_FLAGS = 85,
+ INTERNET_OPTION_COOKIES_3RD_PARTY = 86,
+ INTERNET_OPTION_DISABLE_PASSPORT_AUTH = 87,
+ INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY = 88,
+ INTERNET_OPTION_EXEMPT_CONNECTION_LIMIT = 89,
+ INTERNET_OPTION_ENABLE_PASSPORT_AUTH = 90,
+ INTERNET_OPTION_HIBERNATE_INACTIVE_WORKER_THREADS = 91,
+ INTERNET_OPTION_ACTIVATE_WORKER_THREADS = 92,
+ INTERNET_OPTION_RESTORE_WORKER_THREAD_DEFAULTS = 93,
+ INTERNET_OPTION_SOCKET_SEND_BUFFER_LENGTH = 94,
+ INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 95,
+ INTERNET_OPTION_DATAFILE_EXT = 96,
+ INTERNET_OPTION_CODEPAGE_PATH = 100,
+ INTERNET_OPTION_CODEPAGE_EXTRA = 101,
+ INTERNET_OPTION_IDN = 102,
+ INTERNET_OPTION_MAX_CONNS_PER_PROXY = 103,
+ INTERNET_OPTION_SUPPRESS_SERVER_AUTH = 104,
+ INTERNET_OPTION_SERVER_CERT_CHAIN_CONTEXT = 105,
+ INTERNET_OPTION_ENABLE_REDIRECT_CACHE_READ = 122,
+ INTERNET_OPTION_COMPRESSED_CONTENT_LENGTH = 147,
+ INTERNET_OPTION_ENABLE_HTTP_PROTOCOL = 148,
+ INTERNET_OPTION_HTTP_PROTOCOL_USED = 149,
+ INTERNET_OPTION_ENCODE_EXTRA = 155,
+ INTERNET_OPTION_HSTS = 157,
+ INTERNET_OPTION_ENTERPRISE_CONTEXT = 159,
+ INTERNET_OPTION_CONNECTION_FILTER = 162,
+ INTERNET_OPTION_REFERER_TOKEN_BINDING_HOSTNAME = 163,
+ INTERNET_OPTION_TOKEN_BINDING_PUBLIC_KEY = 181,
+ INTERNET_OPTION_COOKIES_SAME_SITE_LEVEL = 187,
+ INTERNET_FIRST_OPTION = INTERNET_OPTION_CALLBACK,
+ INTERNET_LAST_OPTION = INTERNET_OPTION_COOKIES_SAME_SITE_LEVEL,
}
enum INTERNET_PRIORITY_FOREGROUND = 1000;
@@ -641,8 +764,11 @@ enum INTERNET_SCHEME {
INTERNET_SCHEME_NEWS,
INTERNET_SCHEME_MAILTO,
INTERNET_SCHEME_SOCKS,
+ INTERNET_SCHEME_JAVASCRIPT,
+ INTERNET_SCHEME_VBSCRIPT,
+ INTERNET_SCHEME_RES,
INTERNET_SCHEME_FIRST = INTERNET_SCHEME_FTP,
- INTERNET_SCHEME_LAST = INTERNET_SCHEME_SOCKS
+ INTERNET_SCHEME_LAST = INTERNET_SCHEME_RES
}
alias INTERNET_SCHEME* LPINTERNET_SCHEME;
@@ -652,6 +778,14 @@ struct INTERNET_ASYNC_RESULT {
}
alias INTERNET_ASYNC_RESULT* LPINTERNET_ASYNC_RESULT;
+struct INTERNET_DIAGNOSTIC_SOCKET_INFO {
+ DWORD_PTR Socket;
+ DWORD SourcePort;
+ DWORD DestPort;
+ DWORD Flags;
+}
+alias INTERNET_DIAGNOSTIC_SOCKET_INFO* LPINTERNET_DIAGNOSTIC_SOCKET_INFO;
+
struct INTERNET_PREFETCH_STATUS {
DWORD dwStatus;
DWORD dwSize;
@@ -665,6 +799,74 @@ struct INTERNET_PROXY_INFO {
}
alias INTERNET_PROXY_INFO* LPINTERNET_PROXY_INFO;
+struct INTERNET_PER_CONN_OPTIONA {
+ DWORD dwOption;
+ union {
+ DWORD dwValue;
+ LPSTR pszValue;
+ FILETIME ftValue;
+ }
+}
+alias INTERNET_PER_CONN_OPTIONA* LPINTERNET_PER_CONN_OPTIONA;
+
+struct INTERNET_PER_CONN_OPTIONW {
+ DWORD dwOption;
+ union {
+ DWORD dwValue;
+ LPWSTR pszValue;
+ FILETIME ftValue;
+ }
+}
+alias INTERNET_PER_CONN_OPTIONW* LPINTERNET_PER_CONN_OPTIONW;
+
+struct INTERNET_PER_CONN_OPTION_LISTA {
+ DWORD dwSize;
+ LPSTR pszConnection;
+ DWORD dwOptionCount;
+ DWORD dwOptionError;
+ LPINTERNET_PER_CONN_OPTIONA pOptions;
+}
+alias INTERNET_PER_CONN_OPTION_LISTA* LPINTERNET_PER_CONN_OPTION_LISTA;
+
+struct INTERNET_PER_CONN_OPTION_LISTW {
+ DWORD dwSize;
+ LPWSTR pszConnection;
+ DWORD dwOptionCount;
+ DWORD dwOptionError;
+ LPINTERNET_PER_CONN_OPTIONW pOptions;
+}
+alias INTERNET_PER_CONN_OPTION_LISTW* LPINTERNET_PER_CONN_OPTION_LISTW;
+
+enum {
+ INTERNET_PER_CONN_FLAGS = 1,
+ INTERNET_PER_CONN_PROXY_SERVER = 2,
+ INTERNET_PER_CONN_PROXY_BYPASS = 3,
+ INTERNET_PER_CONN_AUTOCONFIG_URL = 4,
+ INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5,
+ INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL = 6,
+ INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS = 7,
+ INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME = 8,
+ INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL = 9,
+ INTERNET_PER_CONN_FLAGS_UI = 10,
+}
+
+enum {
+ PROXY_TYPE_DIRECT = 0x00000001,
+ PROXY_TYPE_PROXY = 0x00000002,
+ PROXY_TYPE_AUTO_PROXY_URL = 0x00000004,
+ PROXY_TYPE_AUTO_DETECT = 0x00000008,
+}
+
+enum {
+ AUTO_PROXY_FLAG_USER_SET = 0x00000001,
+ AUTO_PROXY_FLAG_ALWAYS_DETECT = 0x00000002,
+ AUTO_PROXY_FLAG_DETECTION_RUN = 0x00000004,
+ AUTO_PROXY_FLAG_MIGRATED = 0x00000008,
+ AUTO_PROXY_FLAG_DONT_CACHE_PROXY_RESULT = 0x00000010,
+ AUTO_PROXY_FLAG_CACHE_INIT_RUN = 0x00000020,
+ AUTO_PROXY_FLAG_DETECTION_SUSPECT = 0x00000040,
+}
+
struct INTERNET_VERSION_INFO {
DWORD dwMajorVersion;
DWORD dwMinorVersion;
@@ -1129,6 +1331,10 @@ extern (Windows) {
}
version (Unicode) {
+ alias INTERNET_PER_CONN_OPTIONW INTERNET_PER_CONN_OPTION;
+ alias LPINTERNET_PER_CONN_OPTIONW LPINTERNET_PER_CONN_OPTION;
+ alias INTERNET_PER_CONN_OPTION_LISTW INTERNET_PER_CONN_OPTION_LIST;
+ alias LPINTERNET_PER_CONN_OPTION_LISTW LPINTERNET_PER_CONN_OPTION_LIST;
alias URL_COMPONENTSW URL_COMPONENTS;
alias LPURL_COMPONENTSW LPURL_COMPONENTS;
alias GOPHER_FIND_DATAW GOPHER_FIND_DATA;
@@ -1187,6 +1393,10 @@ version (Unicode) {
alias GetUrlCacheGroupAttributeW GetUrlCacheGroupAttribute;
alias SetUrlCacheGroupAttributeW SetUrlCacheGroupAttribute;
} else {
+ alias INTERNET_PER_CONN_OPTIONA INTERNET_PER_CONN_OPTION;
+ alias LPINTERNET_PER_CONN_OPTIONA LPINTERNET_PER_CONN_OPTION;
+ alias INTERNET_PER_CONN_OPTION_LISTA INTERNET_PER_CONN_OPTION_LIST;
+ alias LPINTERNET_PER_CONN_OPTION_LISTA LPINTERNET_PER_CONN_OPTION_LIST;
alias URL_COMPONENTSA URL_COMPONENTS;
alias LPURL_COMPONENTSA LPURL_COMPONENTS;
alias GOPHER_FIND_DATAA GOPHER_FIND_DATA;
diff --git a/libphobos/libdruntime/core/sys/windows/winioctl.d b/libphobos/libdruntime/core/sys/windows/winioctl.d
index cd41a3f..84d498e 100644
--- a/libphobos/libdruntime/core/sys/windows/winioctl.d
+++ b/libphobos/libdruntime/core/sys/windows/winioctl.d
@@ -9,10 +9,11 @@
*/
module core.sys.windows.winioctl;
version (Windows):
+@system:
// FIXME: check types of some constants
-private import core.sys.windows.basetyps, core.sys.windows.windef;
+import core.sys.windows.basetyps, core.sys.windows.windef;
enum size_t
HIST_NO_OF_BUCKETS = 24,
diff --git a/libphobos/libdruntime/core/sys/windows/winldap.d b/libphobos/libdruntime/core/sys/windows/winldap.d
index 8a861ae..78578dd 100644
--- a/libphobos/libdruntime/core/sys/windows/winldap.d
+++ b/libphobos/libdruntime/core/sys/windows/winldap.d
@@ -9,6 +9,7 @@
*/
module core.sys.windows.winldap;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
@@ -30,7 +31,7 @@ version (ANSI) {} else version = Unicode;
*/
import core.sys.windows.schannel, core.sys.windows.winber;
-private import core.sys.windows.wincrypt, core.sys.windows.windef;
+import core.sys.windows.wincrypt, core.sys.windows.windef;
//align(4):
@@ -460,7 +461,7 @@ struct LDAPVLVInfo {
* Under Microsoft WinLDAP the function ldap_error is only stub.
* This macro uses LDAP structure to get error string and pass it to the user.
*/
-private extern (C) int printf(in char* format, ...);
+private extern (C) int printf(const scope char* format, ...);
int ldap_perror(LDAP* handle, char* message) {
return printf("%s: %s\n", message, handle.ld_error);
}
@@ -491,111 +492,111 @@ extern (C) {
ULONG ldap_controls_freeW(LDAPControlW**);
ULONG ldap_free_controlsA(LDAPControlA**);
ULONG ldap_free_controlsW(LDAPControlW**);
- ULONG ldap_sasl_bindA(LDAP*, PCHAR, PCHAR, BERVAL*, PLDAPControlA*,
+ ULONG ldap_sasl_bindA(LDAP*, PCSTR, PCSTR, BERVAL*, PLDAPControlA*,
PLDAPControlA*, int*);
- ULONG ldap_sasl_bindW(LDAP*, PWCHAR, PWCHAR, BERVAL*, PLDAPControlW*,
+ ULONG ldap_sasl_bindW(LDAP*, PCWSTR, PCWSTR, BERVAL*, PLDAPControlW*,
PLDAPControlW*, int*);
- ULONG ldap_sasl_bind_sA(LDAP*, PCHAR, PCHAR, BERVAL*, PLDAPControlA*,
+ ULONG ldap_sasl_bind_sA(LDAP*, PCSTR, PCSTR, BERVAL*, PLDAPControlA*,
PLDAPControlA*, PBERVAL*);
- ULONG ldap_sasl_bind_sW(LDAP*, PWCHAR, PWCHAR, BERVAL*, PLDAPControlW*,
+ ULONG ldap_sasl_bind_sW(LDAP*, PCWSTR, PCWSTR, BERVAL*, PLDAPControlW*,
PLDAPControlW*, PBERVAL*);
- ULONG ldap_simple_bindA(LDAP*, PCHAR, PCHAR);
- ULONG ldap_simple_bindW(LDAP*, PWCHAR, PWCHAR);
- ULONG ldap_simple_bind_sA(LDAP*, PCHAR, PCHAR);
- ULONG ldap_simple_bind_sW(LDAP*, PWCHAR, PWCHAR);
+ ULONG ldap_simple_bindA(LDAP*, PSTR, PSTR);
+ ULONG ldap_simple_bindW(LDAP*, PWSTR, PWSTR);
+ ULONG ldap_simple_bind_sA(LDAP*, PSTR, PSTR);
+ ULONG ldap_simple_bind_sW(LDAP*, PWSTR, PWSTR);
ULONG ldap_unbind(LDAP*);
ULONG ldap_unbind_s(LDAP*);
- ULONG ldap_search_extA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG,
+ ULONG ldap_search_extA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG,
+ PLDAPControlA*, PLDAPControlA*, ULONG, ULONG, ULONG*);
+ ULONG ldap_search_extW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG,
PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, ULONG*);
- ULONG ldap_search_extW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG,
- PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, ULONG*);
- ULONG ldap_search_ext_sA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG,
- PLDAPControlA*, PLDAPControlA*, LDAP_TIMEVAL*, ULONG, LDAPMessage**);
- ULONG ldap_search_ext_sW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG,
- PLDAPControlW*, PLDAPControlW*, LDAP_TIMEVAL*, ULONG, LDAPMessage**);
- ULONG ldap_searchA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG);
- ULONG ldap_searchW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG);
- ULONG ldap_search_sA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG,
- LDAPMessage**);
- ULONG ldap_search_sW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG,
- LDAPMessage**);
- ULONG ldap_search_stA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG,
- LDAP_TIMEVAL*, LDAPMessage**);
- ULONG ldap_search_stW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG,
- LDAP_TIMEVAL*, LDAPMessage**);
- ULONG ldap_compare_extA(LDAP*, PCHAR, PCHAR, PCHAR, BerValue*,
+ ULONG ldap_search_ext_sA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG,
+ PLDAPControlA*, PLDAPControlA*, LDAP_TIMEVAL*, ULONG, PLDAPMessage*);
+ ULONG ldap_search_ext_sW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG,
+ PLDAPControlW*, PLDAPControlW*, LDAP_TIMEVAL*, ULONG, PLDAPMessage*);
+ ULONG ldap_searchA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG);
+ ULONG ldap_searchW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG);
+ ULONG ldap_search_sA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG,
+ PLDAPMessage*);
+ ULONG ldap_search_sW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG,
+ PLDAPMessage*);
+ ULONG ldap_search_stA(LDAP*, PCSTR, ULONG, PCSTR, PZPSTR, ULONG,
+ LDAP_TIMEVAL*, PLDAPMessage*);
+ ULONG ldap_search_stW(LDAP*, PCWSTR, ULONG, PCWSTR, PZPWSTR, ULONG,
+ LDAP_TIMEVAL*, PLDAPMessage*);
+ ULONG ldap_compare_extA(LDAP*, PCSTR, PCSTR, PCSTR, BerValue*,
PLDAPControlA*, PLDAPControlA*, ULONG*);
- ULONG ldap_compare_extW(LDAP*, PWCHAR, PWCHAR, PWCHAR, BerValue*,
+ ULONG ldap_compare_extW(LDAP*, PCWSTR, PCWSTR, PCWSTR, BerValue*,
PLDAPControlW*, PLDAPControlW*, ULONG*);
- ULONG ldap_compare_ext_sA(LDAP*, PCHAR, PCHAR, PCHAR, BerValue*,
+ ULONG ldap_compare_ext_sA(LDAP*, PCSTR, PCSTR, PCSTR, BerValue*,
PLDAPControlA*, PLDAPControlA*);
- ULONG ldap_compare_ext_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR, BerValue*,
+ ULONG ldap_compare_ext_sW(LDAP*, PCWSTR, PCWSTR, PCWSTR, BerValue*,
PLDAPControlW*, PLDAPControlW*);
- ULONG ldap_compareA(LDAP*, PCHAR, PCHAR, PCHAR);
- ULONG ldap_compareW(LDAP*, PWCHAR, PWCHAR, PWCHAR);
- ULONG ldap_compare_sA(LDAP*, PCHAR, PCHAR, PCHAR);
- ULONG ldap_compare_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR);
- ULONG ldap_modify_extA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*,
+ ULONG ldap_compareA(LDAP*, PCSTR, PCSTR, PCSTR);
+ ULONG ldap_compareW(LDAP*, PCWSTR, PCWSTR, PCWSTR);
+ ULONG ldap_compare_sA(LDAP*, PCSTR, PCSTR, PCSTR);
+ ULONG ldap_compare_sW(LDAP*, PCWSTR, PCWSTR, PCWSTR);
+ ULONG ldap_modify_extA(LDAP*, PCSTR, LDAPModA**, PLDAPControlA*,
PLDAPControlA*, ULONG*);
- ULONG ldap_modify_extW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*,
+ ULONG ldap_modify_extW(LDAP*, PCWSTR, LDAPModW**, PLDAPControlW*,
PLDAPControlW*, ULONG*);
- ULONG ldap_modify_ext_sA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*,
+ ULONG ldap_modify_ext_sA(LDAP*, PCSTR, LDAPModA**, PLDAPControlA*,
PLDAPControlA*);
- ULONG ldap_modify_ext_sW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*,
+ ULONG ldap_modify_ext_sW(LDAP*, PCWSTR, LDAPModW**, PLDAPControlW*,
PLDAPControlW*);
- ULONG ldap_modifyA(LDAP*, PCHAR, LDAPModA*[]);
- ULONG ldap_modifyW(LDAP*, PWCHAR, LDAPModW*[]);
- ULONG ldap_modify_sA(LDAP*, PCHAR, LDAPModA*[]);
- ULONG ldap_modify_sW(LDAP*, PWCHAR, LDAPModW*[]);
- ULONG ldap_rename_extA(LDAP*, PCHAR, PCHAR, PCHAR, INT, PLDAPControlA*,
+ ULONG ldap_modifyA(LDAP*, PSTR, LDAPModA**);
+ ULONG ldap_modifyW(LDAP*, PWSTR, LDAPModW**);
+ ULONG ldap_modify_sA(LDAP*, PSTR, LDAPModA**);
+ ULONG ldap_modify_sW(LDAP*, PWSTR, LDAPModW**);
+ ULONG ldap_rename_extA(LDAP*, PCSTR, PCSTR, PCSTR, INT, PLDAPControlA*,
PLDAPControlA*, ULONG*);
- ULONG ldap_rename_extW(LDAP*, PWCHAR, PWCHAR, PWCHAR, INT, PLDAPControlW*,
+ ULONG ldap_rename_extW(LDAP*, PCWSTR, PCWSTR, PCWSTR, INT, PLDAPControlW*,
PLDAPControlW*, ULONG*);
- ULONG ldap_rename_ext_sA(LDAP*, PCHAR, PCHAR, PCHAR, INT,
+ ULONG ldap_rename_ext_sA(LDAP*, PCSTR, PCSTR, PCSTR, INT,
PLDAPControlA*, PLDAPControlA*);
- ULONG ldap_rename_ext_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR, INT,
+ ULONG ldap_rename_ext_sW(LDAP*, PCWSTR, PCWSTR, PCWSTR, INT,
PLDAPControlW*, PLDAPControlW*);
- ULONG ldap_add_extA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*,
+ ULONG ldap_add_extA(LDAP*, PCSTR, LDAPModA**, PLDAPControlA*,
PLDAPControlA*, ULONG*);
- ULONG ldap_add_extW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*,
+ ULONG ldap_add_extW(LDAP*, PCWSTR, LDAPModW**, PLDAPControlW*,
PLDAPControlW*, ULONG*);
- ULONG ldap_add_ext_sA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*,
+ ULONG ldap_add_ext_sA(LDAP*, PCSTR, LDAPModA**, PLDAPControlA*,
PLDAPControlA*);
- ULONG ldap_add_ext_sW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*,
+ ULONG ldap_add_ext_sW(LDAP*, PCWSTR, LDAPModW**, PLDAPControlW*,
PLDAPControlW*);
- ULONG ldap_addA(LDAP*, PCHAR, LDAPModA*[]);
- ULONG ldap_addW(LDAP*, PWCHAR, LDAPModW*[]);
- ULONG ldap_add_sA(LDAP*, PCHAR, LDAPModA*[]);
- ULONG ldap_add_sW(LDAP*, PWCHAR, LDAPModW*[]);
- ULONG ldap_delete_extA(LDAP*, PCHAR, PLDAPControlA*, PLDAPControlA*,
+ ULONG ldap_addA(LDAP*, PSTR, LDAPModA**);
+ ULONG ldap_addW(LDAP*, PWSTR, LDAPModW**);
+ ULONG ldap_add_sA(LDAP*, PSTR, LDAPModA**);
+ ULONG ldap_add_sW(LDAP*, PWSTR, LDAPModW**);
+ ULONG ldap_delete_extA(LDAP*, PCSTR, PLDAPControlA*, PLDAPControlA*,
ULONG*);
- ULONG ldap_delete_extW(LDAP*, PWCHAR, PLDAPControlW*, PLDAPControlW*,
+ ULONG ldap_delete_extW(LDAP*, PCWSTR, PLDAPControlW*, PLDAPControlW*,
ULONG*);
- ULONG ldap_delete_ext_sA(LDAP*, PCHAR, PLDAPControlA*, PLDAPControlA*);
- ULONG ldap_delete_ext_sW(LDAP*, PWCHAR, PLDAPControlW*, PLDAPControlW*);
- ULONG ldap_deleteA(LDAP*, PCHAR);
- ULONG ldap_deleteW(LDAP*, PWCHAR);
- ULONG ldap_delete_sA(LDAP*, PCHAR);
- ULONG ldap_delete_sW(LDAP*, PWCHAR);
- ULONG ldap_extended_operationA(LDAP*, PCHAR, BerValue*, PLDAPControlA*,
+ ULONG ldap_delete_ext_sA(LDAP*, PCSTR, PLDAPControlA*, PLDAPControlA*);
+ ULONG ldap_delete_ext_sW(LDAP*, PCWSTR, PLDAPControlW*, PLDAPControlW*);
+ ULONG ldap_deleteA(LDAP*, PCSTR);
+ ULONG ldap_deleteW(LDAP*, PCWSTR);
+ ULONG ldap_delete_sA(LDAP*, PCSTR);
+ ULONG ldap_delete_sW(LDAP*, PCWSTR);
+ ULONG ldap_extended_operationA(LDAP*, PCSTR, BerValue*, PLDAPControlA*,
PLDAPControlA*, ULONG*);
- ULONG ldap_extended_operationW(LDAP*, PWCHAR, BerValue*, PLDAPControlW*,
+ ULONG ldap_extended_operationW(LDAP*, PCWSTR, BerValue*, PLDAPControlW*,
PLDAPControlW*, ULONG*);
- ULONG ldap_extended_operation_sA(LDAP*, PCHAR, BerValue*, PLDAPControlA*,
+ ULONG ldap_extended_operation_sA(LDAP*, PSTR, BerValue*, PLDAPControlA*,
PLDAPControlA*, PCHAR*, BerValue**);
- ULONG ldap_extended_operation_sW(LDAP*, PWCHAR, BerValue*, PLDAPControlW*,
+ ULONG ldap_extended_operation_sW(LDAP*, PWSTR, BerValue*, PLDAPControlW*,
PLDAPControlW*, PWCHAR*, BerValue**);
ULONG ldap_close_extended_op(LDAP*, ULONG);
ULONG ldap_abandon(LDAP*, ULONG);
ULONG ldap_result(LDAP*, ULONG, ULONG, LDAP_TIMEVAL*, LDAPMessage**);
ULONG ldap_msgfree(LDAPMessage*);
- ULONG ldap_parse_resultA(LDAP*, LDAPMessage*, ULONG*, PCHAR*, PCHAR*,
- PCHAR**, PLDAPControlA**, BOOLEAN);
- ULONG ldap_parse_resultW(LDAP*, LDAPMessage*, ULONG*, PWCHAR*, PWCHAR*,
- PWCHAR**, PLDAPControlW**, BOOLEAN);
- ULONG ldap_parse_extended_resultA(LDAP, LDAPMessage*, PCHAR*, BerValue**,
+ ULONG ldap_parse_resultA(LDAP*, LDAPMessage*, ULONG*, PSTR*, PSTR*,
+ PZPSTR*, PLDAPControlA**, BOOLEAN);
+ ULONG ldap_parse_resultW(LDAP*, LDAPMessage*, ULONG*, PWSTR*, PWSTR*,
+ PZPWSTR*, PLDAPControlW**, BOOLEAN);
+ ULONG ldap_parse_extended_resultA(LDAP, LDAPMessage*, PSTR*, BerValue**,
BOOLEAN);
- ULONG ldap_parse_extended_resultW(LDAP, LDAPMessage*, PWCHAR*, BerValue**,
+ ULONG ldap_parse_extended_resultW(LDAP, LDAPMessage*, PWSTR*, BerValue**,
BOOLEAN);
PCHAR ldap_err2stringA(ULONG);
PWCHAR ldap_err2stringW(ULONG);
@@ -614,10 +615,10 @@ extern (C) {
PWCHAR ldap_next_attributeW(LDAP*, LDAPMessage*, BerElement*);
VOID ldap_memfreeA(PCHAR);
VOID ldap_memfreeW(PWCHAR);
- PCHAR* ldap_get_valuesA(LDAP*, LDAPMessage*, PCHAR);
- PWCHAR* ldap_get_valuesW(LDAP*, LDAPMessage*, PWCHAR);
- BerValue** ldap_get_values_lenA(LDAP*, LDAPMessage*, PCHAR);
- BerValue** ldap_get_values_lenW(LDAP*, LDAPMessage*, PWCHAR);
+ PCHAR* ldap_get_valuesA(LDAP*, LDAPMessage*, PCSTR);
+ PWCHAR* ldap_get_valuesW(LDAP*, LDAPMessage*, PCWSTR);
+ BerValue** ldap_get_values_lenA(LDAP*, LDAPMessage*, PCSTR);
+ BerValue** ldap_get_values_lenW(LDAP*, LDAPMessage*, PCWSTR);
ULONG ldap_count_valuesA(PCHAR*);
ULONG ldap_count_valuesW(PWCHAR*);
ULONG ldap_count_values_len(BerValue**);
@@ -626,16 +627,16 @@ extern (C) {
ULONG ldap_value_free_len(BerValue**);
PCHAR ldap_get_dnA(LDAP*, LDAPMessage*);
PWCHAR ldap_get_dnW(LDAP*, LDAPMessage*);
- PCHAR ldap_explode_dnA(PCHAR, ULONG);
- PWCHAR ldap_explode_dnW(PWCHAR, ULONG);
- PCHAR ldap_dn2ufnA(PCHAR);
- PWCHAR ldap_dn2ufnW(PWCHAR);
- ULONG ldap_ufn2dnA(PCHAR, PCHAR*);
- ULONG ldap_ufn2dnW(PWCHAR, PWCHAR*);
+ PCHAR ldap_explode_dnA(PCSTR, ULONG);
+ PWCHAR ldap_explode_dnW(PCWSTR, ULONG);
+ PCHAR ldap_dn2ufnA(PCSTR);
+ PWCHAR ldap_dn2ufnW(PCWSTR);
+ ULONG ldap_ufn2dnA(PCSTR, PSTR*);
+ ULONG ldap_ufn2dnW(PCWSTR, PWSTR*);
ULONG ldap_parse_referenceA(LDAP*, LDAPMessage*, PCHAR**);
ULONG ldap_parse_referenceW(LDAP*, LDAPMessage*, PWCHAR**);
- ULONG ldap_check_filterA(LDAP*, PCHAR);
- ULONG ldap_check_filterW(LDAP*, PWCHAR);
+ ULONG ldap_check_filterA(LDAP*, PSTR);
+ ULONG ldap_check_filterW(LDAP*, PWSTR);
ULONG ldap_create_page_controlA(PLDAP, ULONG, BerValue*, UCHAR,
PLDAPControlA*);
ULONG ldap_create_page_controlW(PLDAP, ULONG, BerValue*, UCHAR,
@@ -644,8 +645,8 @@ extern (C) {
PLDAPControlA*);
ULONG ldap_create_sort_controlW(PLDAP, PLDAPSortKeyW*, UCHAR,
PLDAPControlW*);
- INT ldap_create_vlv_controlA(LDAP*, LDAPVLVInfo*, UCHAR, LDAPControlA**);
- INT ldap_create_vlv_controlW(LDAP*, LDAPVLVInfo*, UCHAR, LDAPControlW**);
+ INT ldap_create_vlv_controlA(LDAP*, LDAPVLVInfo*, UCHAR, PLDAPControlA*);
+ INT ldap_create_vlv_controlW(LDAP*, LDAPVLVInfo*, UCHAR, PLDAPControlW*);
ULONG ldap_encode_sort_controlA(PLDAP, PLDAPSortKeyA*, PLDAPControlA,
BOOLEAN);
ULONG ldap_encode_sort_controlW(PLDAP, PLDAPSortKeyW*, PLDAPControlW,
@@ -660,31 +661,31 @@ extern (C) {
ULONG ldap_parse_page_controlW(PLDAP, PLDAPControlW*, ULONG*, BerValue**);
ULONG ldap_parse_sort_controlA(PLDAP, PLDAPControlA*, ULONG*, PCHAR*);
ULONG ldap_parse_sort_controlW(PLDAP, PLDAPControlW*, ULONG*, PWCHAR*);
- INT ldap_parse_vlv_controlA(LDAP*, LDAPControlA**, uint*, uint*,
- BerValue**, int*);
- INT ldap_parse_vlv_controlW(LDAP*, LDAPControlW**, uint*, uint*,
- BerValue**, int*);
- PLDAPSearch ldap_search_init_pageA(PLDAP, PCHAR, ULONG, PCHAR, PCHAR[],
+ INT ldap_parse_vlv_controlA(PLDAP, PLDAPControlA*, PULONG, PULONG,
+ BerValue**, PINT);
+ INT ldap_parse_vlv_controlW(PLDAP, PLDAPControlW*, PULONG, PULONG,
+ BerValue**, PINT);
+ PLDAPSearch ldap_search_init_pageA(PLDAP, PCSTR, ULONG, PCSTR, PZPSTR,
ULONG, PLDAPControlA*, PLDAPControlA*, ULONG, ULONG, PLDAPSortKeyA*);
- PLDAPSearch ldap_search_init_pageW(PLDAP, PWCHAR, ULONG, PWCHAR, PWCHAR[],
+ PLDAPSearch ldap_search_init_pageW(PLDAP, PCWSTR, ULONG, PCWSTR, PZPWSTR,
ULONG, PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, PLDAPSortKeyW*);
ULONG ldap_search_abandon_page(PLDAP, PLDAPSearch);
LDAP ldap_conn_from_msg(LDAP*, LDAPMessage*);
INT LdapUnicodeToUTF8(LPCWSTR, int, LPSTR, int);
INT LdapUTF8ToUnicode(LPCSTR, int, LPWSTR, int);
- deprecated {
- ULONG ldap_bindA(LDAP*, PCHAR, PCHAR, ULONG);
- ULONG ldap_bindW(LDAP*, PWCHAR, PWCHAR, ULONG);
- ULONG ldap_bind_sA(LDAP*, PCHAR, PCHAR, ULONG);
- ULONG ldap_bind_sW(LDAP*, PWCHAR, PWCHAR, ULONG);
- ULONG ldap_modrdnA(LDAP*, PCHAR, PCHAR);
- ULONG ldap_modrdnW(LDAP*, PWCHAR, PWCHAR);
- ULONG ldap_modrdn_sA(LDAP*, PCHAR, PCHAR);
- ULONG ldap_modrdn_sW(LDAP*, PWCHAR, PWCHAR);
- ULONG ldap_modrdn2A(LDAP*, PCHAR, PCHAR, INT);
- ULONG ldap_modrdn2W(LDAP*, PWCHAR, PWCHAR, INT);
- ULONG ldap_modrdn2_sA(LDAP*, PCHAR, PCHAR, INT);
- ULONG ldap_modrdn2_sW(LDAP*, PWCHAR, PWCHAR, INT);
+ ULONG ldap_bindA(LDAP*, PSTR, PCHAR, ULONG);
+ ULONG ldap_bindW(LDAP*, PWSTR, PWCHAR, ULONG);
+ ULONG ldap_bind_sA(LDAP*, PSTR, PCHAR, ULONG);
+ ULONG ldap_bind_sW(LDAP*, PWSTR, PWCHAR, ULONG);
+ deprecated ("For LDAP 3 or later, use the ldap_rename_ext or ldap_rename_ext_s functions") {
+ ULONG ldap_modrdnA(LDAP*, PCSTR, PCSTR);
+ ULONG ldap_modrdnW(LDAP*, PCWSTR, PCWSTR);
+ ULONG ldap_modrdn_sA(LDAP*, PCSTR, PCSTR);
+ ULONG ldap_modrdn_sW(LDAP*, PCWSTR, PCWSTR);
+ ULONG ldap_modrdn2A(LDAP*, PCSTR, PCSTR, INT);
+ ULONG ldap_modrdn2W(LDAP*, PCWSTR, PCWSTR, INT);
+ ULONG ldap_modrdn2_sA(LDAP*, PCSTR, PCSTR, INT);
+ ULONG ldap_modrdn2_sW(LDAP*, PCWSTR, PCWSTR, INT);
}
}
diff --git a/libphobos/libdruntime/core/sys/windows/winnetwk.d b/libphobos/libdruntime/core/sys/windows/winnetwk.d
index 1f952b6..7601279 100644
--- a/libphobos/libdruntime/core/sys/windows/winnetwk.d
+++ b/libphobos/libdruntime/core/sys/windows/winnetwk.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.winnetwk;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "mpr");
-private import core.sys.windows.winbase, core.sys.windows.winerror, core.sys.windows.winnt;
+import core.sys.windows.winbase, core.sys.windows.winerror, core.sys.windows.winnt;
enum : DWORD {
WNNC_NET_MSNET = 0x00010000,
diff --git a/libphobos/libdruntime/core/sys/windows/winnls.d b/libphobos/libdruntime/core/sys/windows/winnls.d
index 5f1c150..6483f4b 100644
--- a/libphobos/libdruntime/core/sys/windows/winnls.d
+++ b/libphobos/libdruntime/core/sys/windows/winnls.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.winnls;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "kernel32");
-private import core.sys.windows.basetsd, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
+import core.sys.windows.basetsd, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
alias DWORD LCTYPE, CALTYPE, CALID, LGRPID, GEOID, GEOTYPE, GEOCLASS;
diff --git a/libphobos/libdruntime/core/sys/windows/winnt.d b/libphobos/libdruntime/core/sys/windows/winnt.d
index f378a17..2d9a281 100644
--- a/libphobos/libdruntime/core/sys/windows/winnt.d
+++ b/libphobos/libdruntime/core/sys/windows/winnt.d
@@ -8,11 +8,12 @@
*/
module core.sys.windows.winnt;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
public import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winerror;
-private import core.sys.windows.w32api;
+import core.sys.windows.w32api;
/* Translation Notes:
The following macros are unneeded for D:
@@ -2246,8 +2247,8 @@ enum LEGACY_SAVE_AREA_LENGTH = XMM_SAVE_AREA32.sizeof;
M128A Xmm13;
M128A Xmm14;
M128A Xmm15;
- };
- };
+ }
+ }
M128A[26] VectorRegister;
DWORD64 VectorControl;
DWORD64 DebugControl;
@@ -2397,6 +2398,7 @@ struct TOKEN_OWNER {
PSID Owner;
}
alias TOKEN_OWNER* PTOKEN_OWNER;
+enum SECURITY_MAX_SID_SIZE = 68;
struct TOKEN_PRIMARY_GROUP {
PSID PrimaryGroup;
@@ -2436,6 +2438,10 @@ struct TOKEN_USER {
}
alias TOKEN_USER* PTOKEN_USER;
+struct TOKEN_MANDATORY_LABEL {
+ SID_AND_ATTRIBUTES Label;
+}
+alias PTOKEN_MANDATORY_LABEL = TOKEN_MANDATORY_LABEL*;
alias DWORD SECURITY_INFORMATION;
alias SECURITY_INFORMATION* PSECURITY_INFORMATION;
alias WORD SECURITY_DESCRIPTOR_CONTROL;
@@ -2451,6 +2457,18 @@ struct SECURITY_DESCRIPTOR {
PACL Dacl;
}
alias SECURITY_DESCRIPTOR* PSECURITY_DESCRIPTOR, PISECURITY_DESCRIPTOR;
+enum TOKEN_ELEVATION_TYPE {
+ TokenElevationTypeDefault = 1,
+ TokenElevationTypeFull,
+ TokenElevationTypeLimited
+}
+
+alias PTOKEN_ELEVATION_TYPE = TOKEN_ELEVATION_TYPE*;
+
+struct TOKEN_ELEVATION {
+ DWORD TokenIsElevated;
+}
+alias PTOKEN_ELEVATION = TOKEN_ELEVATION*;
enum TOKEN_INFORMATION_CLASS {
TokenUser = 1,
@@ -2469,7 +2487,32 @@ enum TOKEN_INFORMATION_CLASS {
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
- TokenOrigin
+ TokenOrigin,
+ TokenElevationType,
+ TokenLinkedToken,
+ TokenElevation,
+ TokenHasRestrictions,
+ TokenAccessInformation,
+ TokenVirtualizationAllowed,
+ TokenVirtualizationEnabled,
+ TokenIntegrityLevel,
+ TokenUIAccess,
+ TokenMandatoryPolicy,
+ TokenLogonSid,
+ TokenIsAppContainer,
+ TokenCapabilities,
+ TokenAppContainerSid,
+ TokenAppContainerNumber,
+ TokenUserClaimAttributes,
+ TokenDeviceClaimAttributes,
+ TokenRestrictedUserClaimAttributes,
+ TokenRestrictedDeviceClaimAttributes,
+ TokenDeviceGroups,
+ TokenRestrictedDeviceGroups,
+ TokenSecurityAttributes,
+ TokenIsRestricted,
+ TokenProcessTrustLevel,
+ MaxTokenInfoClass // MaxTokenInfoClass should always be the last enum
}
enum SID_NAME_USE {
@@ -2485,6 +2528,103 @@ enum SID_NAME_USE {
}
alias SID_NAME_USE* PSID_NAME_USE;
+enum WELL_KNOWN_SID_TYPE {
+ WinNullSid = 0,
+ WinWorldSid = 1,
+ WinLocalSid = 2,
+ WinCreatorOwnerSid = 3,
+ WinCreatorGroupSid = 4,
+ WinCreatorOwnerServerSid = 5,
+ WinCreatorGroupServerSid = 6,
+ WinNtAuthoritySid = 7,
+ WinDialupSid = 8,
+ WinNetworkSid = 9,
+ WinBatchSid = 10,
+ WinInteractiveSid = 11,
+ WinServiceSid = 12,
+ WinAnonymousSid = 13,
+ WinProxySid = 14,
+ WinEnterpriseControllersSid = 15,
+ WinSelfSid = 16,
+ WinAuthenticatedUserSid = 17,
+ WinRestrictedCodeSid = 18,
+ WinTerminalServerSid = 19,
+ WinRemoteLogonIdSid = 20,
+ WinLogonIdsSid = 21,
+ WinLocalSystemSid = 22,
+ WinLocalServiceSid = 23,
+ WinNetworkServiceSid = 24,
+ WinBuiltinDomainSid = 25,
+ WinBuiltinAdministratorsSid = 26,
+ WinBuiltinUsersSid = 27,
+ WinBuiltinGuestsSid = 28,
+ WinBuiltinPowerUsersSid = 29,
+ WinBuiltinAccountOperatorsSid = 30,
+ WinBuiltinSystemOperatorsSid = 31,
+ WinBuiltinPrintOperatorsSid = 32,
+ WinBuiltinBackupOperatorsSid = 33,
+ WinBuiltinReplicatorSid = 34,
+ WinBuiltinPreWindows2000CompatibleAccessSid = 35,
+ WinBuiltinRemoteDesktopUsersSid = 36,
+ WinBuiltinNetworkConfigurationOperatorsSid = 37,
+ WinAccountAdministratorSid = 38,
+ WinAccountGuestSid = 39,
+ WinAccountKrbtgtSid = 40,
+ WinAccountDomainAdminsSid = 41,
+ WinAccountDomainUsersSid = 42,
+ WinAccountDomainGuestsSid = 43,
+ WinAccountComputersSid = 44,
+ WinAccountControllersSid = 45,
+ WinAccountCertAdminsSid = 46,
+ WinAccountSchemaAdminsSid = 47,
+ WinAccountEnterpriseAdminsSid = 48,
+ WinAccountPolicyAdminsSid = 49,
+ WinAccountRasAndIasServersSid = 50,
+ WinNTLMAuthenticationSid = 51,
+ WinDigestAuthenticationSid = 52,
+ WinSChannelAuthenticationSid = 53,
+ WinThisOrganizationSid = 54,
+ WinOtherOrganizationSid = 55,
+ WinBuiltinIncomingForestTrustBuildersSid = 56,
+ WinBuiltinPerfMonitoringUsersSid = 57,
+ WinBuiltinPerfLoggingUsersSid = 58,
+ WinBuiltinAuthorizationAccessSid = 59,
+ WinBuiltinTerminalServerLicenseServersSid = 60,
+ WinBuiltinDCOMUsersSid = 61,
+ WinBuiltinIUsersSid = 62,
+ WinIUserSid = 63,
+ WinBuiltinCryptoOperatorsSid = 64,
+ WinUntrustedLabelSid = 65,
+ WinLowLabelSid = 66,
+ WinMediumLabelSid = 67,
+ WinHighLabelSid = 68,
+ WinSystemLabelSid = 69,
+ WinWriteRestrictedCodeSid = 70,
+ WinCreatorOwnerRightsSid = 71,
+ WinCacheablePrincipalsGroupSid = 72,
+ WinNonCacheablePrincipalsGroupSid = 73,
+ WinEnterpriseReadonlyControllersSid = 74,
+ WinAccountReadonlyControllersSid = 75,
+ WinBuiltinEventLogReadersGroup = 76,
+ WinNewEnterpriseReadonlyControllersSid = 77,
+ WinBuiltinCertSvcDComAccessGroup = 78,
+ WinMediumPlusLabelSid = 79,
+ WinLocalLogonSid = 80,
+ WinConsoleLogonSid = 81,
+ WinThisOrganizationCertificateSid = 82,
+ WinApplicationPackageAuthoritySid = 83,
+ WinBuiltinAnyPackageSid = 84,
+ WinCapabilityInternetClientSid = 85,
+ WinCapabilityInternetClientServerSid = 86,
+ WinCapabilityPrivateNetworkClientServerSid = 87,
+ WinCapabilityPicturesLibrarySid = 88,
+ WinCapabilityVideosLibrarySid = 89,
+ WinCapabilityMusicLibrarySid = 90,
+ WinCapabilityDocumentsLibrarySid = 91,
+ WinCapabilitySharedUserCertificatesSid = 92,
+ WinCapabilityEnterpriseAuthenticationSid = 93,
+ WinCapabilityRemovableStorageSid = 94
+}
struct QUOTA_LIMITS {
SIZE_T PagedPoolLimit;
SIZE_T NonPagedPoolLimit;
@@ -3734,6 +3874,7 @@ enum DWORD
ES_SYSTEM_REQUIRED = 0x00000001,
ES_DISPLAY_REQUIRED = 0x00000002,
ES_USER_PRESENT = 0x00000004,
+ ES_AWAYMODE_REQUIRED = 0x00000040,
ES_CONTINUOUS = 0x80000000;
enum LATENCY_TIME {
diff --git a/libphobos/libdruntime/core/sys/windows/winperf.d b/libphobos/libdruntime/core/sys/windows/winperf.d
index 24a6c2c..367c2b0 100644
--- a/libphobos/libdruntime/core/sys/windows/winperf.d
+++ b/libphobos/libdruntime/core/sys/windows/winperf.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.winperf;
version (Windows):
+@system:
import core.sys.windows.windef;
import core.sys.windows.winbase; // for SYSTEMTIME
diff --git a/libphobos/libdruntime/core/sys/windows/winreg.d b/libphobos/libdruntime/core/sys/windows/winreg.d
index 2f80e8f..078bdf7 100644
--- a/libphobos/libdruntime/core/sys/windows/winreg.d
+++ b/libphobos/libdruntime/core/sys/windows/winreg.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.winreg;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "advapi32");
-private import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
enum : HKEY { // for some reason, DMD errors if I don't give all the values explicitly
HKEY_CLASSES_ROOT = cast(HKEY) 0x80000000,
@@ -97,58 +98,58 @@ static if (_WIN32_WINNT >= 0x600) {
}
extern (Windows) nothrow @nogc {
- LONG RegCloseKey(in HKEY);
+ LONG RegCloseKey(const scope HKEY);
LONG RegConnectRegistryA(LPCSTR, HKEY, PHKEY);
LONG RegConnectRegistryW(LPCWSTR, HKEY, PHKEY);
- LONG RegCreateKeyExA(in HKEY, LPCSTR, DWORD, LPSTR, DWORD, REGSAM,
+ LONG RegCreateKeyExA(const scope HKEY, LPCSTR, DWORD, LPSTR, DWORD, REGSAM,
LPSECURITY_ATTRIBUTES, PHKEY, PDWORD);
- LONG RegCreateKeyExW(in HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM,
+ LONG RegCreateKeyExW(const scope HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM,
LPSECURITY_ATTRIBUTES, PHKEY, PDWORD);
- LONG RegDeleteKeyA(in HKEY, LPCSTR);
- LONG RegDeleteKeyW(in HKEY, LPCWSTR);
- LONG RegDeleteValueA(in HKEY, LPCSTR);
- LONG RegDeleteValueW(in HKEY, LPCWSTR);
- LONG RegEnumKeyExA(in HKEY, DWORD, LPSTR, PDWORD, PDWORD, LPSTR, PDWORD,
+ LONG RegDeleteKeyA(const scope HKEY, LPCSTR);
+ LONG RegDeleteKeyW(const scope HKEY, LPCWSTR);
+ LONG RegDeleteValueA(const scope HKEY, LPCSTR);
+ LONG RegDeleteValueW(const scope HKEY, LPCWSTR);
+ LONG RegEnumKeyExA(const scope HKEY, DWORD, LPSTR, PDWORD, PDWORD, LPSTR, PDWORD,
PFILETIME);
- LONG RegEnumKeyExW(in HKEY, DWORD, LPWSTR, PDWORD, PDWORD, LPWSTR, PDWORD,
+ LONG RegEnumKeyExW(const scope HKEY, DWORD, LPWSTR, PDWORD, PDWORD, LPWSTR, PDWORD,
PFILETIME);
- LONG RegEnumValueA(in HKEY, DWORD, LPSTR, PDWORD, PDWORD, PDWORD, LPBYTE,
+ LONG RegEnumValueA(const scope HKEY, DWORD, LPSTR, PDWORD, PDWORD, PDWORD, LPBYTE,
PDWORD);
- LONG RegEnumValueW(in HKEY, DWORD, LPWSTR, PDWORD, PDWORD, PDWORD, LPBYTE,
+ LONG RegEnumValueW(const scope HKEY, DWORD, LPWSTR, PDWORD, PDWORD, PDWORD, LPBYTE,
PDWORD);
- LONG RegFlushKey(in HKEY);
- LONG RegLoadKeyA(in HKEY, LPCSTR, LPCSTR);
- LONG RegLoadKeyW(in HKEY, LPCWSTR, LPCWSTR);
- LONG RegOpenKeyExA(in HKEY, LPCSTR, DWORD, REGSAM, PHKEY);
- LONG RegOpenKeyExW(in HKEY, LPCWSTR, DWORD, REGSAM, PHKEY);
- LONG RegQueryInfoKeyA(in HKEY, LPSTR, PDWORD, PDWORD, PDWORD, PDWORD,
+ LONG RegFlushKey(const scope HKEY);
+ LONG RegLoadKeyA(const scope HKEY, LPCSTR, LPCSTR);
+ LONG RegLoadKeyW(const scope HKEY, LPCWSTR, LPCWSTR);
+ LONG RegOpenKeyExA(const scope HKEY, LPCSTR, DWORD, REGSAM, PHKEY);
+ LONG RegOpenKeyExW(const scope HKEY, LPCWSTR, DWORD, REGSAM, PHKEY);
+ LONG RegQueryInfoKeyA(const scope HKEY, LPSTR, PDWORD, PDWORD, PDWORD, PDWORD,
PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PFILETIME);
- LONG RegQueryInfoKeyW(in HKEY, LPWSTR, PDWORD, PDWORD, PDWORD, PDWORD,
+ LONG RegQueryInfoKeyW(const scope HKEY, LPWSTR, PDWORD, PDWORD, PDWORD, PDWORD,
PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PFILETIME);
- LONG RegQueryMultipleValuesA(in HKEY, PVALENTA, DWORD, LPSTR, LPDWORD);
- LONG RegQueryMultipleValuesW(in HKEY, PVALENTW, DWORD, LPWSTR, LPDWORD);
- LONG RegQueryValueExA(in HKEY, LPCSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD);
- LONG RegQueryValueExW(in HKEY, LPCWSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD);
- LONG RegReplaceKeyA(in HKEY, LPCSTR, LPCSTR, LPCSTR);
- LONG RegReplaceKeyW(in HKEY, LPCWSTR, LPCWSTR, LPCWSTR);
- LONG RegSaveKeyA(in HKEY, LPCSTR, LPSECURITY_ATTRIBUTES);
- LONG RegSaveKeyW(in HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES);
- LONG RegSetKeySecurity(in HKEY, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR);
- LONG RegSetValueExA(in HKEY, LPCSTR, DWORD, DWORD, const(BYTE)*, DWORD);
- LONG RegSetValueExW(in HKEY, LPCWSTR, DWORD, DWORD, const(BYTE)*, DWORD);
- LONG RegUnLoadKeyA(in HKEY, LPCSTR);
- LONG RegUnLoadKeyW(in HKEY, LPCWSTR);
- LONG RegNotifyChangeKeyValue(in HKEY, BOOL, DWORD, HANDLE, BOOL);
+ LONG RegQueryMultipleValuesA(const scope HKEY, PVALENTA, DWORD, LPSTR, LPDWORD);
+ LONG RegQueryMultipleValuesW(const scope HKEY, PVALENTW, DWORD, LPWSTR, LPDWORD);
+ LONG RegQueryValueExA(const scope HKEY, LPCSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD);
+ LONG RegQueryValueExW(const scope HKEY, LPCWSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD);
+ LONG RegReplaceKeyA(const scope HKEY, LPCSTR, LPCSTR, LPCSTR);
+ LONG RegReplaceKeyW(const scope HKEY, LPCWSTR, LPCWSTR, LPCWSTR);
+ LONG RegSaveKeyA(const scope HKEY, LPCSTR, LPSECURITY_ATTRIBUTES);
+ LONG RegSaveKeyW(const scope HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES);
+ LONG RegSetKeySecurity(const scope HKEY, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR);
+ LONG RegSetValueExA(const scope HKEY, LPCSTR, DWORD, DWORD, const(BYTE)*, DWORD);
+ LONG RegSetValueExW(const scope HKEY, LPCWSTR, DWORD, DWORD, const(BYTE)*, DWORD);
+ LONG RegUnLoadKeyA(const scope HKEY, LPCSTR);
+ LONG RegUnLoadKeyW(const scope HKEY, LPCWSTR);
+ LONG RegNotifyChangeKeyValue(const scope HKEY, BOOL, DWORD, HANDLE, BOOL);
BOOL AbortSystemShutdownA(LPCSTR);
BOOL AbortSystemShutdownW(LPCWSTR);
BOOL InitiateSystemShutdownA(LPSTR, LPSTR, DWORD, BOOL, BOOL);
BOOL InitiateSystemShutdownW(LPWSTR, LPWSTR, DWORD, BOOL, BOOL);
- LONG RegGetKeySecurity(in HKEY, SECURITY_INFORMATION,
+ LONG RegGetKeySecurity(const scope HKEY, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR, PDWORD);
- LONG RegRestoreKeyA(in HKEY, LPCSTR, DWORD);
- LONG RegRestoreKeyW(in HKEY, LPCWSTR, DWORD);
- LONG RegSetKeySecurity(in HKEY, SECURITY_INFORMATION,
+ LONG RegRestoreKeyA(const scope HKEY, LPCSTR, DWORD);
+ LONG RegRestoreKeyW(const scope HKEY, LPCWSTR, DWORD);
+ LONG RegSetKeySecurity(const scope HKEY, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR);
static if (_WIN32_WINNT >= 0x500) {
@@ -158,28 +159,28 @@ extern (Windows) nothrow @nogc {
}
static if (_WIN32_WINNT >= 0x501) {
- LONG RegSaveKeyExA(in HKEY, LPCSTR, LPSECURITY_ATTRIBUTES, DWORD);
- LONG RegSaveKeyExW(in HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES, DWORD);
+ LONG RegSaveKeyExA(const scope HKEY, LPCSTR, LPSECURITY_ATTRIBUTES, DWORD);
+ LONG RegSaveKeyExW(const scope HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES, DWORD);
}
static if (_WIN32_WINNT >= 0x600) {
- LONG RegGetValueA(in HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue,
+ LONG RegGetValueA(const scope HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue,
DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
- LONG RegGetValueW(in HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue,
+ LONG RegGetValueW(const scope HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue,
DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
}
//deprecated {
- LONG RegCreateKeyA(in HKEY, LPCSTR, PHKEY);
- LONG RegCreateKeyW(in HKEY, LPCWSTR, PHKEY);
- LONG RegEnumKeyA(in HKEY, DWORD, LPSTR, DWORD);
- LONG RegEnumKeyW(in HKEY, DWORD, LPWSTR, DWORD);
- LONG RegOpenKeyA(in HKEY, LPCSTR, PHKEY);
- LONG RegOpenKeyW(in HKEY, LPCWSTR, PHKEY);
- LONG RegQueryValueA(in HKEY, LPCSTR, LPSTR, PLONG);
- LONG RegQueryValueW(in HKEY, LPCWSTR, LPWSTR, PLONG);
- LONG RegSetValueA(in HKEY, LPCSTR, DWORD, LPCSTR, DWORD);
- LONG RegSetValueW(in HKEY, LPCWSTR, DWORD, LPCWSTR, DWORD);
+ LONG RegCreateKeyA(const scope HKEY, LPCSTR, PHKEY);
+ LONG RegCreateKeyW(const scope HKEY, LPCWSTR, PHKEY);
+ LONG RegEnumKeyA(const scope HKEY, DWORD, LPSTR, DWORD);
+ LONG RegEnumKeyW(const scope HKEY, DWORD, LPWSTR, DWORD);
+ LONG RegOpenKeyA(const scope HKEY, LPCSTR, PHKEY);
+ LONG RegOpenKeyW(const scope HKEY, LPCWSTR, PHKEY);
+ LONG RegQueryValueA(const scope HKEY, LPCSTR, LPSTR, PLONG);
+ LONG RegQueryValueW(const scope HKEY, LPCWSTR, LPWSTR, PLONG);
+ LONG RegSetValueA(const scope HKEY, LPCSTR, DWORD, LPCSTR, DWORD);
+ LONG RegSetValueW(const scope HKEY, LPCWSTR, DWORD, LPCWSTR, DWORD);
//}
}
diff --git a/libphobos/libdruntime/core/sys/windows/winsock2.d b/libphobos/libdruntime/core/sys/windows/winsock2.d
index 04e9881..55a45be 100644
--- a/libphobos/libdruntime/core/sys/windows/winsock2.d
+++ b/libphobos/libdruntime/core/sys/windows/winsock2.d
@@ -6,6 +6,7 @@
module core.sys.windows.winsock2;
version (Windows):
+@system:
pragma(lib, "ws2_32");
diff --git a/libphobos/libdruntime/core/sys/windows/winspool.d b/libphobos/libdruntime/core/sys/windows/winspool.d
index 8cc50dd..db5b23f 100644
--- a/libphobos/libdruntime/core/sys/windows/winspool.d
+++ b/libphobos/libdruntime/core/sys/windows/winspool.d
@@ -8,12 +8,13 @@
*/
module core.sys.windows.winspool;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "winspool");
-private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.wingdi;
-private import core.sys.windows.winbase; // for SYSTEMTIME
+import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.wingdi;
+import core.sys.windows.winbase; // for SYSTEMTIME
// FIXME: clean up Windows version support
diff --git a/libphobos/libdruntime/core/sys/windows/winsvc.d b/libphobos/libdruntime/core/sys/windows/winsvc.d
index 3114807..44c4563 100644
--- a/libphobos/libdruntime/core/sys/windows/winsvc.d
+++ b/libphobos/libdruntime/core/sys/windows/winsvc.d
@@ -9,11 +9,12 @@
*/
module core.sys.windows.winsvc;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "advapi32");
-private import core.sys.windows.w32api, core.sys.windows.windef;
+import core.sys.windows.w32api, core.sys.windows.windef;
// FIXME: check Windows version support
diff --git a/libphobos/libdruntime/core/sys/windows/winuser.d b/libphobos/libdruntime/core/sys/windows/winuser.d
index 11f0a28..07e5efa 100644
--- a/libphobos/libdruntime/core/sys/windows/winuser.d
+++ b/libphobos/libdruntime/core/sys/windows/winuser.d
@@ -8,6 +8,7 @@
*/
module core.sys.windows.winuser;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "user32");
@@ -22,8 +23,8 @@ pragma(lib, "user32");
//#define GetWindowTask(hWnd) ((HANDLE)GetWindowThreadProcessId(hWnd, NULL))
//#define DefHookProc(c, p, lp, h) CallNextHookEx((HHOOK)*h, c, p, lp)
-private import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.wingdi;
-private import core.sys.windows.windef; // for HMONITOR
+import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.wingdi;
+import core.sys.windows.windef; // for HMONITOR
// FIXME: clean up Windows version support
@@ -3545,7 +3546,7 @@ void POINTSTOPOINT()(out POINT p, LONG ps) {
p.y = HIWORD(ps);
}
-POINTS POINTTOPOINTS()(in POINT p) {
+POINTS POINTTOPOINTS()(const POINT p) {
return MAKELONG(p.x, p.y);
}
diff --git a/libphobos/libdruntime/core/sys/windows/winver.d b/libphobos/libdruntime/core/sys/windows/winver.d
index e33ff4b..afe53d8 100644
--- a/libphobos/libdruntime/core/sys/windows/winver.d
+++ b/libphobos/libdruntime/core/sys/windows/winver.d
@@ -9,11 +9,15 @@
*/
module core.sys.windows.winver;
version (Windows):
+@system:
+import core.sys.windows.w32api;
+import core.sys.windows.winbase;
+import core.sys.windows.sdkddkver;
version (ANSI) {} else version = Unicode;
pragma(lib, "version");
-private import core.sys.windows.windef;
+import core.sys.windows.windef;
// FIXME: type weirdness
enum {
@@ -172,3 +176,89 @@ version (Unicode) {
alias VerLanguageNameA VerLanguageName;
alias VerQueryValueA VerQueryValue;
}
+
+alias VERSIONHELPERAPI = BOOL;
+VERSIONHELPERAPI IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
+{
+ OSVERSIONINFOEXW osvi;
+ const DWORDLONG dwlConditionMask = VerSetConditionMask(
+ VerSetConditionMask(
+ VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL),
+ VER_MINORVERSION,
+ VER_GREATER_EQUAL),
+ VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL
+ );
+ osvi.dwMajorVersion = wMajorVersion;
+ osvi.dwMinorVersion = wMinorVersion;
+ osvi.wServicePackMajor = wServicePackMajor;
+
+ return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
+}
+
+VERSIONHELPERAPI IsWindowsXPOrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
+}
+
+VERSIONHELPERAPI IsWindowsXPSP1OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1);
+}
+
+VERSIONHELPERAPI IsWindowsXPSP2OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2);
+}
+
+VERSIONHELPERAPI IsWindowsXPSP3OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3);
+}
+
+VERSIONHELPERAPI IsWindowsVistaOrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
+}
+
+VERSIONHELPERAPI IsWindowsVistaSP1OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1);
+}
+
+VERSIONHELPERAPI IsWindowsVistaSP2OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
+}
+
+VERSIONHELPERAPI IsWindows7OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
+}
+
+VERSIONHELPERAPI IsWindows7SP1OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
+}
+
+VERSIONHELPERAPI IsWindows8OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
+}
+
+VERSIONHELPERAPI IsWindows8Point1OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
+}
+
+VERSIONHELPERAPI IsWindows10OrGreater()
+{
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN10), LOBYTE(_WIN32_WINNT_WIN10), 0);
+}
+
+VERSIONHELPERAPI IsWindowsServer()
+{
+ OSVERSIONINFOEXW osvi = { OSVERSIONINFOEXW.sizeof, 0, 0, 0, 0, [0], 0, 0, 0, VER_NT_WORKSTATION };
+ const DWORDLONG dwlConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL );
+
+ return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
+}
diff --git a/libphobos/libdruntime/core/sys/windows/wtsapi32.d b/libphobos/libdruntime/core/sys/windows/wtsapi32.d
index 538dc62..643c049 100644
--- a/libphobos/libdruntime/core/sys/windows/wtsapi32.d
+++ b/libphobos/libdruntime/core/sys/windows/wtsapi32.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.wtsapi32;
version (Windows):
+@system:
version (ANSI) {} else version = Unicode;
pragma(lib, "wtsapi32");
-private import core.sys.windows.w32api;
+import core.sys.windows.w32api;
import core.sys.windows.windef;
enum {
diff --git a/libphobos/libdruntime/core/sys/windows/wtypes.d b/libphobos/libdruntime/core/sys/windows/wtypes.d
index b7a83cb..8af42cf 100644
--- a/libphobos/libdruntime/core/sys/windows/wtypes.d
+++ b/libphobos/libdruntime/core/sys/windows/wtypes.d
@@ -8,10 +8,11 @@
*/
module core.sys.windows.wtypes;
version (Windows):
+@system:
import core.sys.windows.rpc, core.sys.windows.rpcndr;
-private import core.sys.windows.windef;
-private import core.sys.windows.uuid; // for GUID_NULL
+import core.sys.windows.windef;
+import core.sys.windows.uuid; // for GUID_NULL
alias GUID_NULL IID_NULL, CLSID_NULL;
@@ -187,7 +188,7 @@ enum VARENUM {
VT_ILLEGAL = 0xffff,
VT_ILLEGALMASKED = 0xfff,
VT_TYPEMASK = 0xfff
-};
+}
struct BYTE_SIZEDARR {
uint clSize;
diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d
deleted file mode 100644
index 7506a8b..0000000
--- a/libphobos/libdruntime/core/thread.d
+++ /dev/null
@@ -1,5732 +0,0 @@
-/**
- * The thread module provides support for thread creation and management.
- *
- * Copyright: Copyright Sean Kelly 2005 - 2012.
- * License: Distributed under the
- * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
- * (See accompanying file LICENSE)
- * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
- * Source: $(DRUNTIMESRC core/_thread.d)
- */
-
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
-module core.thread;
-
-
-public import core.time; // for Duration
-import core.exception : onOutOfMemoryError;
-
-version (OSX)
- version = Darwin;
-else version (iOS)
- version = Darwin;
-else version (TVOS)
- version = Darwin;
-else version (WatchOS)
- version = Darwin;
-
-private
-{
- // interface to rt.tlsgc
- import core.internal.traits : externDFunc;
-
- alias rt_tlsgc_init = externDFunc!("rt.tlsgc.init", void* function() nothrow @nogc);
- alias rt_tlsgc_destroy = externDFunc!("rt.tlsgc.destroy", void function(void*) nothrow @nogc);
-
- alias ScanDg = void delegate(void* pstart, void* pend) nothrow;
- alias rt_tlsgc_scan =
- externDFunc!("rt.tlsgc.scan", void function(void*, scope ScanDg) nothrow);
-
- alias rt_tlsgc_processGCMarks =
- externDFunc!("rt.tlsgc.processGCMarks", void function(void*, scope IsMarkedDg) nothrow);
-}
-
-version (Solaris)
-{
- import core.sys.solaris.sys.priocntl;
- import core.sys.solaris.sys.types;
-}
-
-version (GNU)
-{
- import gcc.builtins;
- import gcc.config;
- version (GNU_StackGrowsDown)
- version = StackGrowsDown;
-}
-else
-{
- // this should be true for most architectures
- version = StackGrowsDown;
-}
-
-/**
- * Returns the process ID of the calling process, which is guaranteed to be
- * unique on the system. This call is always successful.
- *
- * Example:
- * ---
- * writefln("Current process id: %s", getpid());
- * ---
- */
-version (Posix)
-{
- alias getpid = core.sys.posix.unistd.getpid;
-}
-else version (Windows)
-{
- alias getpid = core.sys.windows.windows.GetCurrentProcessId;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Thread and Fiber Exceptions
-///////////////////////////////////////////////////////////////////////////////
-
-
-/**
- * Base class for thread exceptions.
- */
-class ThreadException : Exception
-{
- @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
- {
- super(msg, file, line, next);
- }
-
- @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)
- {
- super(msg, file, line, next);
- }
-}
-
-
-/**
-* Base class for thread errors to be used for function inside GC when allocations are unavailable.
-*/
-class ThreadError : Error
-{
- @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
- {
- super(msg, file, line, next);
- }
-
- @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)
- {
- super(msg, file, line, next);
- }
-}
-
-private
-{
- import core.atomic, core.memory, core.sync.mutex;
-
- // Handling unaligned mutexes are not supported on all platforms, so we must
- // ensure that the address of all shared data are appropriately aligned.
- import core.internal.traits : classInstanceAlignment;
-
- enum mutexAlign = classInstanceAlignment!Mutex;
- enum mutexClassInstanceSize = __traits(classInstanceSize, Mutex);
-
- //
- // exposed by compiler runtime
- //
- extern (C) void rt_moduleTlsCtor();
- extern (C) void rt_moduleTlsDtor();
-
- /**
- * Hook for whatever EH implementation is used to save/restore some data
- * per stack.
- *
- * Params:
- * newContext = The return value of the prior call to this function
- * where the stack was last swapped out, or null when a fiber stack
- * is switched in for the first time.
- */
- extern(C) void* _d_eh_swapContext(void* newContext) nothrow @nogc;
-
- version (DigitalMars)
- {
- version (Windows)
- alias swapContext = _d_eh_swapContext;
- else
- {
- extern(C) void* _d_eh_swapContextDwarf(void* newContext) nothrow @nogc;
-
- void* swapContext(void* newContext) nothrow @nogc
- {
- /* Detect at runtime which scheme is being used.
- * Eventually, determine it statically.
- */
- static int which = 0;
- final switch (which)
- {
- case 0:
- {
- assert(newContext == null);
- auto p = _d_eh_swapContext(newContext);
- auto pdwarf = _d_eh_swapContextDwarf(newContext);
- if (p)
- {
- which = 1;
- return p;
- }
- else if (pdwarf)
- {
- which = 2;
- return pdwarf;
- }
- return null;
- }
- case 1:
- return _d_eh_swapContext(newContext);
- case 2:
- return _d_eh_swapContextDwarf(newContext);
- }
- }
- }
- }
- else
- alias swapContext = _d_eh_swapContext;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Thread Entry Point and Signal Handlers
-///////////////////////////////////////////////////////////////////////////////
-
-
-version (Windows)
-{
- private
- {
- import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below
- import core.stdc.stdlib; // for malloc, atexit
- import core.sys.windows.windows;
- import core.sys.windows.threadaux; // for OpenThreadHandle
-
- extern (Windows) alias btex_fptr = uint function(void*);
- extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*) nothrow;
-
- //
- // Entry point for Windows threads
- //
- extern (Windows) uint thread_entryPoint( void* arg ) nothrow
- {
- Thread obj = cast(Thread) arg;
- assert( obj );
-
- assert( obj.m_curr is &obj.m_main );
- obj.m_main.bstack = getStackBottom();
- obj.m_main.tstack = obj.m_main.bstack;
- obj.m_tlsgcdata = rt_tlsgc_init();
-
- Thread.setThis(obj);
- Thread.add(obj);
- scope (exit)
- {
- Thread.remove(obj);
- }
- Thread.add(&obj.m_main);
-
- // NOTE: No GC allocations may occur until the stack pointers have
- // been set and Thread.getThis returns a valid reference to
- // this thread object (this latter condition is not strictly
- // necessary on Windows but it should be followed for the
- // sake of consistency).
-
- // TODO: Consider putting an auto exception object here (using
- // alloca) forOutOfMemoryError plus something to track
- // whether an exception is in-flight?
-
- void append( Throwable t )
- {
- if ( obj.m_unhandled is null )
- obj.m_unhandled = t;
- else
- {
- Throwable last = obj.m_unhandled;
- while ( last.next !is null )
- last = last.next;
- last.next = t;
- }
- }
-
- version (D_InlineAsm_X86)
- {
- asm nothrow @nogc { fninit; }
- }
-
- try
- {
- rt_moduleTlsCtor();
- try
- {
- obj.run();
- }
- catch ( Throwable t )
- {
- append( t );
- }
- rt_moduleTlsDtor();
- }
- catch ( Throwable t )
- {
- append( t );
- }
- return 0;
- }
-
-
- HANDLE GetCurrentThreadHandle() nothrow @nogc
- {
- const uint DUPLICATE_SAME_ACCESS = 0x00000002;
-
- HANDLE curr = GetCurrentThread(),
- proc = GetCurrentProcess(),
- hndl;
-
- DuplicateHandle( proc, curr, proc, &hndl, 0, TRUE, DUPLICATE_SAME_ACCESS );
- return hndl;
- }
- }
-}
-else version (Posix)
-{
- private
- {
- import core.stdc.errno;
- import core.sys.posix.semaphore;
- import core.sys.posix.stdlib; // for malloc, valloc, free, atexit
- import core.sys.posix.pthread;
- import core.sys.posix.signal;
- import core.sys.posix.time;
-
- version (Darwin)
- {
- import core.sys.darwin.mach.thread_act;
- import core.sys.darwin.pthread : pthread_mach_thread_np;
- }
-
- //
- // Entry point for POSIX threads
- //
- extern (C) void* thread_entryPoint( void* arg ) nothrow
- {
- version (Shared)
- {
- import rt.sections;
- Thread obj = cast(Thread)(cast(void**)arg)[0];
- auto loadedLibraries = (cast(void**)arg)[1];
- .free(arg);
- }
- else
- {
- Thread obj = cast(Thread)arg;
- }
- assert( obj );
-
- // loadedLibraries need to be inherited from parent thread
- // before initilizing GC for TLS (rt_tlsgc_init)
- version (Shared) inheritLoadedLibraries(loadedLibraries);
-
- assert( obj.m_curr is &obj.m_main );
- obj.m_main.bstack = getStackBottom();
- obj.m_main.tstack = obj.m_main.bstack;
- obj.m_tlsgcdata = rt_tlsgc_init();
-
- atomicStore!(MemoryOrder.raw)(obj.m_isRunning, true);
- Thread.setThis(obj); // allocates lazy TLS (see Issue 11981)
- Thread.add(obj); // can only receive signals from here on
- scope (exit)
- {
- Thread.remove(obj);
- atomicStore!(MemoryOrder.raw)(obj.m_isRunning, false);
- }
- Thread.add(&obj.m_main);
-
- static extern (C) void thread_cleanupHandler( void* arg ) nothrow @nogc
- {
- Thread obj = cast(Thread) arg;
- assert( obj );
-
- // NOTE: If the thread terminated abnormally, just set it as
- // not running and let thread_suspendAll remove it from
- // the thread list. This is safer and is consistent
- // with the Windows thread code.
- atomicStore!(MemoryOrder.raw)(obj.m_isRunning,false);
- }
-
- // NOTE: Using void to skip the initialization here relies on
- // knowledge of how pthread_cleanup is implemented. It may
- // not be appropriate for all platforms. However, it does
- // avoid the need to link the pthread module. If any
- // implementation actually requires default initialization
- // then pthread_cleanup should be restructured to maintain
- // the current lack of a link dependency.
- static if ( __traits( compiles, pthread_cleanup ) )
- {
- pthread_cleanup cleanup = void;
- cleanup.push( &thread_cleanupHandler, cast(void*) obj );
- }
- else static if ( __traits( compiles, pthread_cleanup_push ) )
- {
- pthread_cleanup_push( &thread_cleanupHandler, cast(void*) obj );
- }
- else
- {
- static assert( false, "Platform not supported." );
- }
-
- // NOTE: No GC allocations may occur until the stack pointers have
- // been set and Thread.getThis returns a valid reference to
- // this thread object (this latter condition is not strictly
- // necessary on Windows but it should be followed for the
- // sake of consistency).
-
- // TODO: Consider putting an auto exception object here (using
- // alloca) forOutOfMemoryError plus something to track
- // whether an exception is in-flight?
-
- void append( Throwable t )
- {
- if ( obj.m_unhandled is null )
- obj.m_unhandled = t;
- else
- {
- Throwable last = obj.m_unhandled;
- while ( last.next !is null )
- last = last.next;
- last.next = t;
- }
- }
-
- try
- {
- rt_moduleTlsCtor();
- try
- {
- obj.run();
- }
- catch ( Throwable t )
- {
- append( t );
- }
- rt_moduleTlsDtor();
- version (Shared) cleanupLoadedLibraries();
- }
- catch ( Throwable t )
- {
- append( t );
- }
-
- // NOTE: Normal cleanup is handled by scope(exit).
-
- static if ( __traits( compiles, pthread_cleanup ) )
- {
- cleanup.pop( 0 );
- }
- else static if ( __traits( compiles, pthread_cleanup_push ) )
- {
- pthread_cleanup_pop( 0 );
- }
-
- return null;
- }
-
-
- //
- // Used to track the number of suspended threads
- //
- __gshared sem_t suspendCount;
-
-
- extern (C) void thread_suspendHandler( int sig ) nothrow
- in
- {
- assert( sig == suspendSignalNumber );
- }
- body
- {
- void op(void* sp) nothrow
- {
- // NOTE: Since registers are being pushed and popped from the
- // stack, any other stack data used by this function should
- // be gone before the stack cleanup code is called below.
- Thread obj = Thread.getThis();
- assert(obj !is null);
-
- if ( !obj.m_lock )
- {
- obj.m_curr.tstack = getStackTop();
- }
-
- sigset_t sigres = void;
- int status;
-
- status = sigfillset( &sigres );
- assert( status == 0 );
-
- status = sigdelset( &sigres, resumeSignalNumber );
- assert( status == 0 );
-
- version (FreeBSD) obj.m_suspendagain = false;
- status = sem_post( &suspendCount );
- assert( status == 0 );
-
- sigsuspend( &sigres );
-
- if ( !obj.m_lock )
- {
- obj.m_curr.tstack = obj.m_curr.bstack;
- }
- }
-
- // avoid deadlocks on FreeBSD, see Issue 13416
- version (FreeBSD)
- {
- auto obj = Thread.getThis();
- if (THR_IN_CRITICAL(obj.m_addr))
- {
- obj.m_suspendagain = true;
- if (sem_post(&suspendCount)) assert(0);
- return;
- }
- }
-
- callWithStackShell(&op);
- }
-
-
- extern (C) void thread_resumeHandler( int sig ) nothrow
- in
- {
- assert( sig == resumeSignalNumber );
- }
- body
- {
-
- }
-
- // HACK libthr internal (thr_private.h) macro, used to
- // avoid deadlocks in signal handler, see Issue 13416
- version (FreeBSD) bool THR_IN_CRITICAL(pthread_t p) nothrow @nogc
- {
- import core.sys.posix.config : c_long;
- import core.sys.posix.sys.types : lwpid_t;
-
- // If the begin of pthread would be changed in libthr (unlikely)
- // we'll run into undefined behavior, compare with thr_private.h.
- static struct pthread
- {
- c_long tid;
- static struct umutex { lwpid_t owner; uint flags; uint[2] ceilings; uint[4] spare; }
- umutex lock;
- uint cycle;
- int locklevel;
- int critical_count;
- // ...
- }
- auto priv = cast(pthread*)p;
- return priv.locklevel > 0 || priv.critical_count > 0;
- }
- }
-}
-else
-{
- // NOTE: This is the only place threading versions are checked. If a new
- // version is added, the module code will need to be searched for
- // places where version-specific code may be required. This can be
- // easily accomlished by searching for 'Windows' or 'Posix'.
- static assert( false, "Unknown threading implementation." );
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Thread
-///////////////////////////////////////////////////////////////////////////////
-
-
-/**
- * This class encapsulates all threading functionality for the D
- * programming language. As thread manipulation is a required facility
- * for garbage collection, all user threads should derive from this
- * class, and instances of this class should never be explicitly deleted.
- * A new thread may be created using either derivation or composition, as
- * in the following example.
- */
-class Thread
-{
- ///////////////////////////////////////////////////////////////////////////
- // Initialization
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * Initializes a thread object which is associated with a static
- * D function.
- *
- * Params:
- * fn = The thread function.
- * sz = The stack size for this thread.
- *
- * In:
- * fn must not be null.
- */
- this( void function() fn, size_t sz = 0 ) @safe pure nothrow @nogc
- in
- {
- assert( fn );
- }
- body
- {
- this(sz);
- () @trusted { m_fn = fn; }();
- m_call = Call.FN;
- m_curr = &m_main;
- }
-
-
- /**
- * Initializes a thread object which is associated with a dynamic
- * D function.
- *
- * Params:
- * dg = The thread function.
- * sz = The stack size for this thread.
- *
- * In:
- * dg must not be null.
- */
- this( void delegate() dg, size_t sz = 0 ) @safe pure nothrow @nogc
- in
- {
- assert( dg );
- }
- body
- {
- this(sz);
- () @trusted { m_dg = dg; }();
- m_call = Call.DG;
- m_curr = &m_main;
- }
-
-
- /**
- * Cleans up any remaining resources used by this object.
- */
- ~this() nothrow @nogc
- {
- if ( m_addr == m_addr.init )
- {
- return;
- }
-
- version (Windows)
- {
- m_addr = m_addr.init;
- CloseHandle( m_hndl );
- m_hndl = m_hndl.init;
- }
- else version (Posix)
- {
- pthread_detach( m_addr );
- m_addr = m_addr.init;
- }
- version (Darwin)
- {
- m_tmach = m_tmach.init;
- }
- rt_tlsgc_destroy( m_tlsgcdata );
- m_tlsgcdata = null;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // General Actions
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * Starts the thread and invokes the function or delegate passed upon
- * construction.
- *
- * In:
- * This routine may only be called once per thread instance.
- *
- * Throws:
- * ThreadException if the thread fails to start.
- */
- final Thread start() nothrow
- in
- {
- assert( !next && !prev );
- }
- body
- {
- auto wasThreaded = multiThreadedFlag;
- multiThreadedFlag = true;
- scope( failure )
- {
- if ( !wasThreaded )
- multiThreadedFlag = false;
- }
-
- version (Windows) {} else
- version (Posix)
- {
- pthread_attr_t attr;
-
- if ( pthread_attr_init( &attr ) )
- onThreadError( "Error initializing thread attributes" );
- if ( m_sz && pthread_attr_setstacksize( &attr, m_sz ) )
- onThreadError( "Error initializing thread stack size" );
- }
-
- version (Windows)
- {
- // NOTE: If a thread is just executing DllMain()
- // while another thread is started here, it holds an OS internal
- // lock that serializes DllMain with CreateThread. As the code
- // might request a synchronization on slock (e.g. in thread_findByAddr()),
- // we cannot hold that lock while creating the thread without
- // creating a deadlock
- //
- // Solution: Create the thread in suspended state and then
- // add and resume it with slock acquired
- assert(m_sz <= uint.max, "m_sz must be less than or equal to uint.max");
- m_hndl = cast(HANDLE) _beginthreadex( null, cast(uint) m_sz, &thread_entryPoint, cast(void*) this, CREATE_SUSPENDED, &m_addr );
- if ( cast(size_t) m_hndl == 0 )
- onThreadError( "Error creating thread" );
- }
-
- slock.lock_nothrow();
- scope(exit) slock.unlock_nothrow();
- {
- ++nAboutToStart;
- pAboutToStart = cast(Thread*)realloc(pAboutToStart, Thread.sizeof * nAboutToStart);
- pAboutToStart[nAboutToStart - 1] = this;
- version (Windows)
- {
- if ( ResumeThread( m_hndl ) == -1 )
- onThreadError( "Error resuming thread" );
- }
- else version (Posix)
- {
- // NOTE: This is also set to true by thread_entryPoint, but set it
- // here as well so the calling thread will see the isRunning
- // state immediately.
- atomicStore!(MemoryOrder.raw)(m_isRunning, true);
- scope( failure ) atomicStore!(MemoryOrder.raw)(m_isRunning, false);
-
- version (Shared)
- {
- import rt.sections;
- auto libs = pinLoadedLibraries();
- auto ps = cast(void**).malloc(2 * size_t.sizeof);
- if (ps is null) onOutOfMemoryError();
- ps[0] = cast(void*)this;
- ps[1] = cast(void*)libs;
- if ( pthread_create( &m_addr, &attr, &thread_entryPoint, ps ) != 0 )
- {
- unpinLoadedLibraries(libs);
- .free(ps);
- onThreadError( "Error creating thread" );
- }
- }
- else
- {
- if ( pthread_create( &m_addr, &attr, &thread_entryPoint, cast(void*) this ) != 0 )
- onThreadError( "Error creating thread" );
- }
- }
- version (Darwin)
- {
- m_tmach = pthread_mach_thread_np( m_addr );
- if ( m_tmach == m_tmach.init )
- onThreadError( "Error creating thread" );
- }
-
- return this;
- }
- }
-
- /**
- * Waits for this thread to complete. If the thread terminated as the
- * result of an unhandled exception, this exception will be rethrown.
- *
- * Params:
- * rethrow = Rethrow any unhandled exception which may have caused this
- * thread to terminate.
- *
- * Throws:
- * ThreadException if the operation fails.
- * Any exception not handled by the joined thread.
- *
- * Returns:
- * Any exception not handled by this thread if rethrow = false, null
- * otherwise.
- */
- final Throwable join( bool rethrow = true )
- {
- version (Windows)
- {
- if ( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
- throw new ThreadException( "Unable to join thread" );
- // NOTE: m_addr must be cleared before m_hndl is closed to avoid
- // a race condition with isRunning. The operation is done
- // with atomicStore to prevent compiler reordering.
- atomicStore!(MemoryOrder.raw)(*cast(shared)&m_addr, m_addr.init);
- CloseHandle( m_hndl );
- m_hndl = m_hndl.init;
- }
- else version (Posix)
- {
- if ( pthread_join( m_addr, null ) != 0 )
- throw new ThreadException( "Unable to join thread" );
- // NOTE: pthread_join acts as a substitute for pthread_detach,
- // which is normally called by the dtor. Setting m_addr
- // to zero ensures that pthread_detach will not be called
- // on object destruction.
- m_addr = m_addr.init;
- }
- if ( m_unhandled )
- {
- if ( rethrow )
- throw m_unhandled;
- return m_unhandled;
- }
- return null;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // General Properties
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * Gets the OS identifier for this thread.
- *
- * Returns:
- * If the thread hasn't been started yet, returns $(LREF ThreadID)$(D.init).
- * Otherwise, returns the result of $(D GetCurrentThreadId) on Windows,
- * and $(D pthread_self) on POSIX.
- *
- * The value is unique for the current process.
- */
- final @property ThreadID id() @safe @nogc
- {
- synchronized( this )
- {
- return m_addr;
- }
- }
-
-
- /**
- * Gets the user-readable label for this thread.
- *
- * Returns:
- * The name of this thread.
- */
- final @property string name() @safe @nogc
- {
- synchronized( this )
- {
- return m_name;
- }
- }
-
-
- /**
- * Sets the user-readable label for this thread.
- *
- * Params:
- * val = The new name of this thread.
- */
- final @property void name( string val ) @safe @nogc
- {
- synchronized( this )
- {
- m_name = val;
- }
- }
-
-
- /**
- * Gets the daemon status for this thread. While the runtime will wait for
- * all normal threads to complete before tearing down the process, daemon
- * threads are effectively ignored and thus will not prevent the process
- * from terminating. In effect, daemon threads will be terminated
- * automatically by the OS when the process exits.
- *
- * Returns:
- * true if this is a daemon thread.
- */
- final @property bool isDaemon() @safe @nogc
- {
- synchronized( this )
- {
- return m_isDaemon;
- }
- }
-
-
- /**
- * Sets the daemon status for this thread. While the runtime will wait for
- * all normal threads to complete before tearing down the process, daemon
- * threads are effectively ignored and thus will not prevent the process
- * from terminating. In effect, daemon threads will be terminated
- * automatically by the OS when the process exits.
- *
- * Params:
- * val = The new daemon status for this thread.
- */
- final @property void isDaemon( bool val ) @safe @nogc
- {
- synchronized( this )
- {
- m_isDaemon = val;
- }
- }
-
-
- /**
- * Tests whether this thread is running.
- *
- * Returns:
- * true if the thread is running, false if not.
- */
- final @property bool isRunning() nothrow @nogc
- {
- if ( m_addr == m_addr.init )
- {
- return false;
- }
-
- version (Windows)
- {
- uint ecode = 0;
- GetExitCodeThread( m_hndl, &ecode );
- return ecode == STILL_ACTIVE;
- }
- else version (Posix)
- {
- return atomicLoad(m_isRunning);
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // Thread Priority Actions
- ///////////////////////////////////////////////////////////////////////////
-
- version (Windows)
- {
- @property static int PRIORITY_MIN() @nogc nothrow pure @safe
- {
- return THREAD_PRIORITY_IDLE;
- }
-
- @property static const(int) PRIORITY_MAX() @nogc nothrow pure @safe
- {
- return THREAD_PRIORITY_TIME_CRITICAL;
- }
-
- @property static int PRIORITY_DEFAULT() @nogc nothrow pure @safe
- {
- return THREAD_PRIORITY_NORMAL;
- }
- }
- else
- {
- private struct Priority
- {
- int PRIORITY_MIN = int.min;
- int PRIORITY_DEFAULT = int.min;
- int PRIORITY_MAX = int.min;
- }
-
- /*
- Lazily loads one of the members stored in a hidden global variable of
- type `Priority`. Upon the first access of either member, the entire
- `Priority` structure is initialized. Multiple initializations from
- different threads calling this function are tolerated.
-
- `which` must be one of `PRIORITY_MIN`, `PRIORITY_DEFAULT`,
- `PRIORITY_MAX`.
- */
- private static int loadGlobal(string which)()
- {
- static shared Priority cache;
- auto local = atomicLoad(mixin("cache." ~ which));
- if (local != local.min) return local;
- // There will be benign races
- cache = loadPriorities;
- return atomicLoad(mixin("cache." ~ which));
- }
-
- /*
- Loads all priorities and returns them as a `Priority` structure. This
- function is thread-neutral.
- */
- private static Priority loadPriorities() @nogc nothrow @trusted
- {
- Priority result;
- version (Solaris)
- {
- pcparms_t pcParms;
- pcinfo_t pcInfo;
-
- pcParms.pc_cid = PC_CLNULL;
- if (priocntl(idtype_t.P_PID, P_MYID, PC_GETPARMS, &pcParms) == -1)
- assert( 0, "Unable to get scheduling class" );
-
- pcInfo.pc_cid = pcParms.pc_cid;
- // PC_GETCLINFO ignores the first two args, use dummy values
- if (priocntl(idtype_t.P_PID, 0, PC_GETCLINFO, &pcInfo) == -1)
- assert( 0, "Unable to get scheduling class info" );
-
- pri_t* clparms = cast(pri_t*)&pcParms.pc_clparms;
- pri_t* clinfo = cast(pri_t*)&pcInfo.pc_clinfo;
-
- result.PRIORITY_MAX = clparms[0];
-
- if (pcInfo.pc_clname == "RT")
- {
- m_isRTClass = true;
-
- // For RT class, just assume it can't be changed
- result.PRIORITY_MIN = clparms[0];
- result.PRIORITY_DEFAULT = clparms[0];
- }
- else
- {
- m_isRTClass = false;
-
- // For all other scheduling classes, there are
- // two key values -- uprilim and maxupri.
- // maxupri is the maximum possible priority defined
- // for the scheduling class, and valid priorities
- // range are in [-maxupri, maxupri].
- //
- // However, uprilim is an upper limit that the
- // current thread can set for the current scheduling
- // class, which can be less than maxupri. As such,
- // use this value for priorityMax since this is
- // the effective maximum.
-
- // maxupri
- result.PRIORITY_MIN = -clinfo[0];
- // by definition
- result.PRIORITY_DEFAULT = 0;
- }
- }
- else version (Posix)
- {
- int policy;
- sched_param param;
- pthread_getschedparam( pthread_self(), &policy, &param ) == 0
- || assert(0, "Internal error in pthread_getschedparam");
-
- result.PRIORITY_MIN = sched_get_priority_min( policy );
- result.PRIORITY_MIN != -1
- || assert(0, "Internal error in sched_get_priority_min");
- result.PRIORITY_DEFAULT = param.sched_priority;
- result.PRIORITY_MAX = sched_get_priority_max( policy );
- result.PRIORITY_MAX != -1 ||
- assert(0, "Internal error in sched_get_priority_max");
- }
- else
- {
- static assert(0, "Your code here.");
- }
- return result;
- }
-
- /**
- * The minimum scheduling priority that may be set for a thread. On
- * systems where multiple scheduling policies are defined, this value
- * represents the minimum valid priority for the scheduling policy of
- * the process.
- */
- @property static int PRIORITY_MIN() @nogc nothrow pure @trusted
- {
- return (cast(int function() @nogc nothrow pure @safe)
- &loadGlobal!"PRIORITY_MIN")();
- }
-
- /**
- * The maximum scheduling priority that may be set for a thread. On
- * systems where multiple scheduling policies are defined, this value
- * represents the maximum valid priority for the scheduling policy of
- * the process.
- */
- @property static const(int) PRIORITY_MAX() @nogc nothrow pure @trusted
- {
- return (cast(int function() @nogc nothrow pure @safe)
- &loadGlobal!"PRIORITY_MAX")();
- }
-
- /**
- * The default scheduling priority that is set for a thread. On
- * systems where multiple scheduling policies are defined, this value
- * represents the default priority for the scheduling policy of
- * the process.
- */
- @property static int PRIORITY_DEFAULT() @nogc nothrow pure @trusted
- {
- return (cast(int function() @nogc nothrow pure @safe)
- &loadGlobal!"PRIORITY_DEFAULT")();
- }
- }
-
- version (NetBSD)
- {
- //NetBSD does not support priority for default policy
- // and it is not possible change policy without root access
- int fakePriority = int.max;
- }
-
- /**
- * Gets the scheduling priority for the associated thread.
- *
- * Note: Getting the priority of a thread that already terminated
- * might return the default priority.
- *
- * Returns:
- * The scheduling priority of this thread.
- */
- final @property int priority()
- {
- version (Windows)
- {
- return GetThreadPriority( m_hndl );
- }
- else version (NetBSD)
- {
- return fakePriority==int.max? PRIORITY_DEFAULT : fakePriority;
- }
- else version (Posix)
- {
- int policy;
- sched_param param;
-
- if (auto err = pthread_getschedparam(m_addr, &policy, &param))
- {
- // ignore error if thread is not running => Bugzilla 8960
- if (!atomicLoad(m_isRunning)) return PRIORITY_DEFAULT;
- throw new ThreadException("Unable to get thread priority");
- }
- return param.sched_priority;
- }
- }
-
-
- /**
- * Sets the scheduling priority for the associated thread.
- *
- * Note: Setting the priority of a thread that already terminated
- * might have no effect.
- *
- * Params:
- * val = The new scheduling priority of this thread.
- */
- final @property void priority( int val )
- in
- {
- assert(val >= PRIORITY_MIN);
- assert(val <= PRIORITY_MAX);
- }
- body
- {
- version (Windows)
- {
- if ( !SetThreadPriority( m_hndl, val ) )
- throw new ThreadException( "Unable to set thread priority" );
- }
- else version (Solaris)
- {
- // the pthread_setschedprio(3c) and pthread_setschedparam functions
- // are broken for the default (TS / time sharing) scheduling class.
- // instead, we use priocntl(2) which gives us the desired behavior.
-
- // We hardcode the min and max priorities to the current value
- // so this is a no-op for RT threads.
- if (m_isRTClass)
- return;
-
- pcparms_t pcparm;
-
- pcparm.pc_cid = PC_CLNULL;
- if (priocntl(idtype_t.P_LWPID, P_MYID, PC_GETPARMS, &pcparm) == -1)
- throw new ThreadException( "Unable to get scheduling class" );
-
- pri_t* clparms = cast(pri_t*)&pcparm.pc_clparms;
-
- // clparms is filled in by the PC_GETPARMS call, only necessary
- // to adjust the element that contains the thread priority
- clparms[1] = cast(pri_t) val;
-
- if (priocntl(idtype_t.P_LWPID, P_MYID, PC_SETPARMS, &pcparm) == -1)
- throw new ThreadException( "Unable to set scheduling class" );
- }
- else version (NetBSD)
- {
- fakePriority = val;
- }
- else version (Posix)
- {
- static if (__traits(compiles, pthread_setschedprio))
- {
- if (auto err = pthread_setschedprio(m_addr, val))
- {
- // ignore error if thread is not running => Bugzilla 8960
- if (!atomicLoad(m_isRunning)) return;
- throw new ThreadException("Unable to set thread priority");
- }
- }
- else
- {
- // NOTE: pthread_setschedprio is not implemented on Darwin, FreeBSD, OpenBSD,
- // or DragonFlyBSD, so use the more complicated get/set sequence below.
- int policy;
- sched_param param;
-
- if (auto err = pthread_getschedparam(m_addr, &policy, &param))
- {
- // ignore error if thread is not running => Bugzilla 8960
- if (!atomicLoad(m_isRunning)) return;
- throw new ThreadException("Unable to set thread priority");
- }
- param.sched_priority = val;
- if (auto err = pthread_setschedparam(m_addr, policy, &param))
- {
- // ignore error if thread is not running => Bugzilla 8960
- if (!atomicLoad(m_isRunning)) return;
- throw new ThreadException("Unable to set thread priority");
- }
- }
- }
- }
-
-
- unittest
- {
- auto thr = Thread.getThis();
- immutable prio = thr.priority;
- scope (exit) thr.priority = prio;
-
- assert(prio == PRIORITY_DEFAULT);
- assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX);
- thr.priority = PRIORITY_MIN;
- assert(thr.priority == PRIORITY_MIN);
- thr.priority = PRIORITY_MAX;
- assert(thr.priority == PRIORITY_MAX);
- }
-
- unittest // Bugzilla 8960
- {
- import core.sync.semaphore;
-
- auto thr = new Thread({});
- thr.start();
- Thread.sleep(1.msecs); // wait a little so the thread likely has finished
- thr.priority = PRIORITY_MAX; // setting priority doesn't cause error
- auto prio = thr.priority; // getting priority doesn't cause error
- assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX);
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // Actions on Calling Thread
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * Suspends the calling thread for at least the supplied period. This may
- * result in multiple OS calls if period is greater than the maximum sleep
- * duration supported by the operating system.
- *
- * Params:
- * val = The minimum duration the calling thread should be suspended.
- *
- * In:
- * period must be non-negative.
- *
- * Example:
- * ------------------------------------------------------------------------
- *
- * Thread.sleep( dur!("msecs")( 50 ) ); // sleep for 50 milliseconds
- * Thread.sleep( dur!("seconds")( 5 ) ); // sleep for 5 seconds
- *
- * ------------------------------------------------------------------------
- */
- static void sleep( Duration val ) @nogc nothrow
- in
- {
- assert( !val.isNegative );
- }
- body
- {
- version (Windows)
- {
- auto maxSleepMillis = dur!("msecs")( uint.max - 1 );
-
- // avoid a non-zero time to be round down to 0
- if ( val > dur!"msecs"( 0 ) && val < dur!"msecs"( 1 ) )
- val = dur!"msecs"( 1 );
-
- // NOTE: In instances where all other threads in the process have a
- // lower priority than the current thread, the current thread
- // will not yield with a sleep time of zero. However, unlike
- // yield(), the user is not asking for a yield to occur but
- // only for execution to suspend for the requested interval.
- // Therefore, expected performance may not be met if a yield
- // is forced upon the user.
- while ( val > maxSleepMillis )
- {
- Sleep( cast(uint)
- maxSleepMillis.total!"msecs" );
- val -= maxSleepMillis;
- }
- Sleep( cast(uint) val.total!"msecs" );
- }
- else version (Posix)
- {
- timespec tin = void;
- timespec tout = void;
-
- val.split!("seconds", "nsecs")(tin.tv_sec, tin.tv_nsec);
- if ( val.total!"seconds" > tin.tv_sec.max )
- tin.tv_sec = tin.tv_sec.max;
- while ( true )
- {
- if ( !nanosleep( &tin, &tout ) )
- return;
- if ( errno != EINTR )
- assert(0, "Unable to sleep for the specified duration");
- tin = tout;
- }
- }
- }
-
-
- /**
- * Forces a context switch to occur away from the calling thread.
- */
- static void yield() @nogc nothrow
- {
- version (Windows)
- SwitchToThread();
- else version (Posix)
- sched_yield();
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // Thread Accessors
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * Provides a reference to the calling thread.
- *
- * Returns:
- * The thread object representing the calling thread. The result of
- * deleting this object is undefined. If the current thread is not
- * attached to the runtime, a null reference is returned.
- */
- static Thread getThis() @safe nothrow @nogc
- {
- // NOTE: This function may not be called until thread_init has
- // completed. See thread_suspendAll for more information
- // on why this might occur.
- return sm_this;
- }
-
-
- /**
- * Provides a list of all threads currently being tracked by the system.
- * Note that threads in the returned array might no longer run (see
- * $(D Thread.)$(LREF isRunning)).
- *
- * Returns:
- * An array containing references to all threads currently being
- * tracked by the system. The result of deleting any contained
- * objects is undefined.
- */
- static Thread[] getAll()
- {
- static void resize(ref Thread[] buf, size_t nlen)
- {
- buf.length = nlen;
- }
- return getAllImpl!resize();
- }
-
-
- /**
- * Operates on all threads currently being tracked by the system. The
- * result of deleting any Thread object is undefined.
- * Note that threads passed to the callback might no longer run (see
- * $(D Thread.)$(LREF isRunning)).
- *
- * Params:
- * dg = The supplied code as a delegate.
- *
- * Returns:
- * Zero if all elemented are visited, nonzero if not.
- */
- static int opApply(scope int delegate(ref Thread) dg)
- {
- import core.stdc.stdlib : free, realloc;
-
- static void resize(ref Thread[] buf, size_t nlen)
- {
- buf = (cast(Thread*)realloc(buf.ptr, nlen * Thread.sizeof))[0 .. nlen];
- }
- auto buf = getAllImpl!resize;
- scope(exit) if (buf.ptr) free(buf.ptr);
-
- foreach (t; buf)
- {
- if (auto res = dg(t))
- return res;
- }
- return 0;
- }
-
- unittest
- {
- auto t1 = new Thread({
- foreach (_; 0 .. 20)
- Thread.getAll;
- }).start;
- auto t2 = new Thread({
- foreach (_; 0 .. 20)
- GC.collect;
- }).start;
- t1.join();
- t2.join();
- }
-
- private static Thread[] getAllImpl(alias resize)()
- {
- import core.atomic;
-
- Thread[] buf;
- while (true)
- {
- immutable len = atomicLoad!(MemoryOrder.raw)(*cast(shared)&sm_tlen);
- resize(buf, len);
- assert(buf.length == len);
- synchronized (slock)
- {
- if (len == sm_tlen)
- {
- size_t pos;
- for (Thread t = sm_tbeg; t; t = t.next)
- buf[pos++] = t;
- return buf;
- }
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // Stuff That Should Go Away
- ///////////////////////////////////////////////////////////////////////////
-
-
-private:
- //
- // Initializes a thread object which has no associated executable function.
- // This is used for the main thread initialized in thread_init().
- //
- this(size_t sz = 0) @safe pure nothrow @nogc
- {
- if (sz)
- {
- version (Posix)
- {
- // stack size must be a multiple of PAGESIZE
- sz += PAGESIZE - 1;
- sz -= sz % PAGESIZE;
- // and at least PTHREAD_STACK_MIN
- if (PTHREAD_STACK_MIN > sz)
- sz = PTHREAD_STACK_MIN;
- }
- m_sz = sz;
- }
- m_call = Call.NO;
- m_curr = &m_main;
- }
-
-
- //
- // Thread entry point. Invokes the function or delegate passed on
- // construction (if any).
- //
- final void run()
- {
- switch ( m_call )
- {
- case Call.FN:
- m_fn();
- break;
- case Call.DG:
- m_dg();
- break;
- default:
- break;
- }
- }
-
-
-private:
- //
- // The type of routine passed on thread construction.
- //
- enum Call
- {
- NO,
- FN,
- DG
- }
-
-
- //
- // Standard types
- //
- version (Windows)
- {
- alias TLSKey = uint;
- }
- else version (Posix)
- {
- alias TLSKey = pthread_key_t;
- }
-
-
- //
- // Local storage
- //
- static Thread sm_this;
-
-
- //
- // Main process thread
- //
- __gshared Thread sm_main;
-
- version (FreeBSD)
- {
- // set when suspend failed and should be retried, see Issue 13416
- shared bool m_suspendagain;
- }
-
-
- //
- // Standard thread data
- //
- version (Windows)
- {
- HANDLE m_hndl;
- }
- else version (Darwin)
- {
- mach_port_t m_tmach;
- }
- ThreadID m_addr;
- Call m_call;
- string m_name;
- union
- {
- void function() m_fn;
- void delegate() m_dg;
- }
- size_t m_sz;
- version (Posix)
- {
- shared bool m_isRunning;
- }
- bool m_isDaemon;
- bool m_isInCriticalRegion;
- Throwable m_unhandled;
-
- version (Solaris)
- {
- __gshared bool m_isRTClass;
- }
-
-private:
- ///////////////////////////////////////////////////////////////////////////
- // Storage of Active Thread
- ///////////////////////////////////////////////////////////////////////////
-
-
- //
- // Sets a thread-local reference to the current thread object.
- //
- static void setThis( Thread t ) nothrow @nogc
- {
- sm_this = t;
- }
-
-
-private:
- ///////////////////////////////////////////////////////////////////////////
- // Thread Context and GC Scanning Support
- ///////////////////////////////////////////////////////////////////////////
-
-
- final void pushContext( Context* c ) nothrow @nogc
- in
- {
- assert( !c.within );
- }
- body
- {
- m_curr.ehContext = swapContext(c.ehContext);
- c.within = m_curr;
- m_curr = c;
- }
-
-
- final void popContext() nothrow @nogc
- in
- {
- assert( m_curr && m_curr.within );
- }
- body
- {
- Context* c = m_curr;
- m_curr = c.within;
- c.ehContext = swapContext(m_curr.ehContext);
- c.within = null;
- }
-
-
- final Context* topContext() nothrow @nogc
- in
- {
- assert( m_curr );
- }
- body
- {
- return m_curr;
- }
-
-
- static struct Context
- {
- void* bstack,
- tstack;
-
- /// Slot for the EH implementation to keep some state for each stack
- /// (will be necessary for exception chaining, etc.). Opaque as far as
- /// we are concerned here.
- void* ehContext;
-
- Context* within;
- Context* next,
- prev;
- }
-
-
- Context m_main;
- Context* m_curr;
- bool m_lock;
- void* m_tlsgcdata;
-
- version (Windows)
- {
- version (X86)
- {
- uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax
- }
- else version (X86_64)
- {
- ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax
- // r8,r9,r10,r11,r12,r13,r14,r15
- }
- else
- {
- static assert(false, "Architecture not supported." );
- }
- }
- else version (Darwin)
- {
- version (X86)
- {
- uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax
- }
- else version (X86_64)
- {
- ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax
- // r8,r9,r10,r11,r12,r13,r14,r15
- }
- else
- {
- static assert(false, "Architecture not supported." );
- }
- }
-
-
-private:
- ///////////////////////////////////////////////////////////////////////////
- // GC Scanning Support
- ///////////////////////////////////////////////////////////////////////////
-
-
- // NOTE: The GC scanning process works like so:
- //
- // 1. Suspend all threads.
- // 2. Scan the stacks of all suspended threads for roots.
- // 3. Resume all threads.
- //
- // Step 1 and 3 require a list of all threads in the system, while
- // step 2 requires a list of all thread stacks (each represented by
- // a Context struct). Traditionally, there was one stack per thread
- // and the Context structs were not necessary. However, Fibers have
- // changed things so that each thread has its own 'main' stack plus
- // an arbitrary number of nested stacks (normally referenced via
- // m_curr). Also, there may be 'free-floating' stacks in the system,
- // which are Fibers that are not currently executing on any specific
- // thread but are still being processed and still contain valid
- // roots.
- //
- // To support all of this, the Context struct has been created to
- // represent a stack range, and a global list of Context structs has
- // been added to enable scanning of these stack ranges. The lifetime
- // (and presence in the Context list) of a thread's 'main' stack will
- // be equivalent to the thread's lifetime. So the Ccontext will be
- // added to the list on thread entry, and removed from the list on
- // thread exit (which is essentially the same as the presence of a
- // Thread object in its own global list). The lifetime of a Fiber's
- // context, however, will be tied to the lifetime of the Fiber object
- // itself, and Fibers are expected to add/remove their Context struct
- // on construction/deletion.
-
-
- //
- // All use of the global thread lists/array should synchronize on this lock.
- //
- // Careful as the GC acquires this lock after the GC lock to suspend all
- // threads any GC usage with slock held can result in a deadlock through
- // lock order inversion.
- @property static Mutex slock() nothrow @nogc
- {
- return cast(Mutex)_slock.ptr;
- }
-
- @property static Mutex criticalRegionLock() nothrow @nogc
- {
- return cast(Mutex)_criticalRegionLock.ptr;
- }
-
- __gshared align(mutexAlign) void[mutexClassInstanceSize] _slock;
- __gshared align(mutexAlign) void[mutexClassInstanceSize] _criticalRegionLock;
-
- static void initLocks()
- {
- _slock[] = typeid(Mutex).initializer[];
- (cast(Mutex)_slock.ptr).__ctor();
-
- _criticalRegionLock[] = typeid(Mutex).initializer[];
- (cast(Mutex)_criticalRegionLock.ptr).__ctor();
- }
-
- static void termLocks()
- {
- (cast(Mutex)_slock.ptr).__dtor();
- (cast(Mutex)_criticalRegionLock.ptr).__dtor();
- }
-
- __gshared Context* sm_cbeg;
-
- __gshared Thread sm_tbeg;
- __gshared size_t sm_tlen;
-
- // can't use rt.util.array in public code
- __gshared Thread* pAboutToStart;
- __gshared size_t nAboutToStart;
-
- //
- // Used for ordering threads in the global thread list.
- //
- Thread prev;
- Thread next;
-
-
- ///////////////////////////////////////////////////////////////////////////
- // Global Context List Operations
- ///////////////////////////////////////////////////////////////////////////
-
-
- //
- // Add a context to the global context list.
- //
- static void add( Context* c ) nothrow @nogc
- in
- {
- assert( c );
- assert( !c.next && !c.prev );
- }
- body
- {
- slock.lock_nothrow();
- scope(exit) slock.unlock_nothrow();
- assert(!suspendDepth); // must be 0 b/c it's only set with slock held
-
- if (sm_cbeg)
- {
- c.next = sm_cbeg;
- sm_cbeg.prev = c;
- }
- sm_cbeg = c;
- }
-
-
- //
- // Remove a context from the global context list.
- //
- // This assumes slock being acquired. This isn't done here to
- // avoid double locking when called from remove(Thread)
- static void remove( Context* c ) nothrow @nogc
- in
- {
- assert( c );
- assert( c.next || c.prev );
- }
- body
- {
- if ( c.prev )
- c.prev.next = c.next;
- if ( c.next )
- c.next.prev = c.prev;
- if ( sm_cbeg == c )
- sm_cbeg = c.next;
- // NOTE: Don't null out c.next or c.prev because opApply currently
- // follows c.next after removing a node. This could be easily
- // addressed by simply returning the next node from this
- // function, however, a context should never be re-added to the
- // list anyway and having next and prev be non-null is a good way
- // to ensure that.
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // Global Thread List Operations
- ///////////////////////////////////////////////////////////////////////////
-
-
- //
- // Add a thread to the global thread list.
- //
- static void add( Thread t, bool rmAboutToStart = true ) nothrow @nogc
- in
- {
- assert( t );
- assert( !t.next && !t.prev );
- }
- body
- {
- slock.lock_nothrow();
- scope(exit) slock.unlock_nothrow();
- assert(t.isRunning); // check this with slock to ensure pthread_create already returned
- assert(!suspendDepth); // must be 0 b/c it's only set with slock held
-
- if (rmAboutToStart)
- {
- size_t idx = -1;
- foreach (i, thr; pAboutToStart[0 .. nAboutToStart])
- {
- if (thr is t)
- {
- idx = i;
- break;
- }
- }
- assert(idx != -1);
- import core.stdc.string : memmove;
- memmove(pAboutToStart + idx, pAboutToStart + idx + 1, Thread.sizeof * (nAboutToStart - idx - 1));
- pAboutToStart =
- cast(Thread*)realloc(pAboutToStart, Thread.sizeof * --nAboutToStart);
- }
-
- if (sm_tbeg)
- {
- t.next = sm_tbeg;
- sm_tbeg.prev = t;
- }
- sm_tbeg = t;
- ++sm_tlen;
- }
-
-
- //
- // Remove a thread from the global thread list.
- //
- static void remove( Thread t ) nothrow @nogc
- in
- {
- assert( t );
- }
- body
- {
- // Thread was already removed earlier, might happen b/c of thread_detachInstance
- if (!t.next && !t.prev)
- return;
- slock.lock_nothrow();
- {
- // NOTE: When a thread is removed from the global thread list its
- // main context is invalid and should be removed as well.
- // It is possible that t.m_curr could reference more
- // than just the main context if the thread exited abnormally
- // (if it was terminated), but we must assume that the user
- // retains a reference to them and that they may be re-used
- // elsewhere. Therefore, it is the responsibility of any
- // object that creates contexts to clean them up properly
- // when it is done with them.
- remove( &t.m_main );
-
- if ( t.prev )
- t.prev.next = t.next;
- if ( t.next )
- t.next.prev = t.prev;
- if ( sm_tbeg is t )
- sm_tbeg = t.next;
- t.prev = t.next = null;
- --sm_tlen;
- }
- // NOTE: Don't null out t.next or t.prev because opApply currently
- // follows t.next after removing a node. This could be easily
- // addressed by simply returning the next node from this
- // function, however, a thread should never be re-added to the
- // list anyway and having next and prev be non-null is a good way
- // to ensure that.
- slock.unlock_nothrow();
- }
-}
-
-///
-unittest
-{
- class DerivedThread : Thread
- {
- this()
- {
- super(&run);
- }
-
- private:
- void run()
- {
- // Derived thread running.
- }
- }
-
- void threadFunc()
- {
- // Composed thread running.
- }
-
- // create and start instances of each type
- auto derived = new DerivedThread().start();
- auto composed = new Thread(&threadFunc).start();
- new Thread({
- // Codes to run in the newly created thread.
- }).start();
-}
-
-unittest
-{
- int x = 0;
-
- new Thread(
- {
- x++;
- }).start().join();
- assert( x == 1 );
-}
-
-
-unittest
-{
- enum MSG = "Test message.";
- string caughtMsg;
-
- try
- {
- new Thread(
- {
- throw new Exception( MSG );
- }).start().join();
- assert( false, "Expected rethrown exception." );
- }
- catch ( Throwable t )
- {
- assert( t.msg == MSG );
- }
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// GC Support Routines
-///////////////////////////////////////////////////////////////////////////////
-
-version (CoreDdoc)
-{
- /**
- * Instruct the thread module, when initialized, to use a different set of
- * signals besides SIGUSR1 and SIGUSR2 for suspension and resumption of threads.
- * This function should be called at most once, prior to thread_init().
- * This function is Posix-only.
- */
- extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc
- {
- }
-}
-else version (Posix)
-{
- extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc
- in
- {
- assert(suspendSignalNumber == 0);
- assert(resumeSignalNumber == 0);
- assert(suspendSignalNo != 0);
- assert(resumeSignalNo != 0);
- }
- out
- {
- assert(suspendSignalNumber != 0);
- assert(resumeSignalNumber != 0);
- }
- body
- {
- suspendSignalNumber = suspendSignalNo;
- resumeSignalNumber = resumeSignalNo;
- }
-}
-
-version (Posix)
-{
- __gshared int suspendSignalNumber;
- __gshared int resumeSignalNumber;
-}
-
-/**
- * Initializes the thread module. This function must be called by the
- * garbage collector on startup and before any other thread routines
- * are called.
- */
-extern (C) void thread_init()
-{
- // NOTE: If thread_init itself performs any allocations then the thread
- // routines reserved for garbage collector use may be called while
- // thread_init is being processed. However, since no memory should
- // exist to be scanned at this point, it is sufficient for these
- // functions to detect the condition and return immediately.
-
- Thread.initLocks();
- // The Android VM runtime intercepts SIGUSR1 and apparently doesn't allow
- // its signal handler to run, so swap the two signals on Android, since
- // thread_resumeHandler does nothing.
- version (Android) thread_setGCSignals(SIGUSR2, SIGUSR1);
-
- version (Darwin)
- {
- }
- else version (Posix)
- {
- if ( suspendSignalNumber == 0 )
- {
- suspendSignalNumber = SIGUSR1;
- }
-
- if ( resumeSignalNumber == 0 )
- {
- resumeSignalNumber = SIGUSR2;
- }
-
- int status;
- sigaction_t sigusr1 = void;
- sigaction_t sigusr2 = void;
-
- // This is a quick way to zero-initialize the structs without using
- // memset or creating a link dependency on their static initializer.
- (cast(byte*) &sigusr1)[0 .. sigaction_t.sizeof] = 0;
- (cast(byte*) &sigusr2)[0 .. sigaction_t.sizeof] = 0;
-
- // NOTE: SA_RESTART indicates that system calls should restart if they
- // are interrupted by a signal, but this is not available on all
- // Posix systems, even those that support multithreading.
- static if ( __traits( compiles, SA_RESTART ) )
- sigusr1.sa_flags = SA_RESTART;
- else
- sigusr1.sa_flags = 0;
- sigusr1.sa_handler = &thread_suspendHandler;
- // NOTE: We want to ignore all signals while in this handler, so fill
- // sa_mask to indicate this.
- status = sigfillset( &sigusr1.sa_mask );
- assert( status == 0 );
-
- // NOTE: Since resumeSignalNumber should only be issued for threads within the
- // suspend handler, we don't want this signal to trigger a
- // restart.
- sigusr2.sa_flags = 0;
- sigusr2.sa_handler = &thread_resumeHandler;
- // NOTE: We want to ignore all signals while in this handler, so fill
- // sa_mask to indicate this.
- status = sigfillset( &sigusr2.sa_mask );
- assert( status == 0 );
-
- status = sigaction( suspendSignalNumber, &sigusr1, null );
- assert( status == 0 );
-
- status = sigaction( resumeSignalNumber, &sigusr2, null );
- assert( status == 0 );
-
- status = sem_init( &suspendCount, 0, 0 );
- assert( status == 0 );
- }
- Thread.sm_main = thread_attachThis();
-}
-
-
-/**
- * Terminates the thread module. No other thread routine may be called
- * afterwards.
- */
-extern (C) void thread_term()
-{
- assert(Thread.sm_tbeg && Thread.sm_tlen == 1);
- assert(!Thread.nAboutToStart);
- if (Thread.pAboutToStart) // in case realloc(p, 0) doesn't return null
- {
- free(Thread.pAboutToStart);
- Thread.pAboutToStart = null;
- }
- Thread.termLocks();
-}
-
-
-/**
- *
- */
-extern (C) bool thread_isMainThread() nothrow @nogc
-{
- return Thread.getThis() is Thread.sm_main;
-}
-
-
-/**
- * Registers the calling thread for use with the D Runtime. If this routine
- * is called for a thread which is already registered, no action is performed.
- *
- * NOTE: This routine does not run thread-local static constructors when called.
- * If full functionality as a D thread is desired, the following function
- * must be called after thread_attachThis:
- *
- * extern (C) void rt_moduleTlsCtor();
- */
-extern (C) Thread thread_attachThis()
-{
- GC.disable(); scope(exit) GC.enable();
-
- if (auto t = Thread.getThis())
- return t;
-
- Thread thisThread = new Thread();
- Thread.Context* thisContext = &thisThread.m_main;
- assert( thisContext == thisThread.m_curr );
-
- version (Windows)
- {
- thisThread.m_addr = GetCurrentThreadId();
- thisThread.m_hndl = GetCurrentThreadHandle();
- thisContext.bstack = getStackBottom();
- thisContext.tstack = thisContext.bstack;
- }
- else version (Posix)
- {
- thisThread.m_addr = pthread_self();
- thisContext.bstack = getStackBottom();
- thisContext.tstack = thisContext.bstack;
-
- atomicStore!(MemoryOrder.raw)(thisThread.m_isRunning, true);
- }
- thisThread.m_isDaemon = true;
- thisThread.m_tlsgcdata = rt_tlsgc_init();
- Thread.setThis( thisThread );
-
- version (Darwin)
- {
- thisThread.m_tmach = pthread_mach_thread_np( thisThread.m_addr );
- assert( thisThread.m_tmach != thisThread.m_tmach.init );
- }
-
- Thread.add( thisThread, false );
- Thread.add( thisContext );
- if ( Thread.sm_main !is null )
- multiThreadedFlag = true;
- return thisThread;
-}
-
-
-version (Windows)
-{
- // NOTE: These calls are not safe on Posix systems that use signals to
- // perform garbage collection. The suspendHandler uses getThis()
- // to get the thread handle so getThis() must be a simple call.
- // Mutexes can't safely be acquired inside signal handlers, and
- // even if they could, the mutex needed (Thread.slock) is held by
- // thread_suspendAll(). So in short, these routines will remain
- // Windows-specific. If they are truly needed elsewhere, the
- // suspendHandler will need a way to call a version of getThis()
- // that only does the TLS lookup without the fancy fallback stuff.
-
- /// ditto
- extern (C) Thread thread_attachByAddr( ThreadID addr )
- {
- return thread_attachByAddrB( addr, getThreadStackBottom( addr ) );
- }
-
-
- /// ditto
- extern (C) Thread thread_attachByAddrB( ThreadID addr, void* bstack )
- {
- GC.disable(); scope(exit) GC.enable();
-
- if (auto t = thread_findByAddr(addr))
- return t;
-
- Thread thisThread = new Thread();
- Thread.Context* thisContext = &thisThread.m_main;
- assert( thisContext == thisThread.m_curr );
-
- thisThread.m_addr = addr;
- thisContext.bstack = bstack;
- thisContext.tstack = thisContext.bstack;
-
- thisThread.m_isDaemon = true;
-
- if ( addr == GetCurrentThreadId() )
- {
- thisThread.m_hndl = GetCurrentThreadHandle();
- thisThread.m_tlsgcdata = rt_tlsgc_init();
- Thread.setThis( thisThread );
- }
- else
- {
- thisThread.m_hndl = OpenThreadHandle( addr );
- impersonate_thread(addr,
- {
- thisThread.m_tlsgcdata = rt_tlsgc_init();
- Thread.setThis( thisThread );
- });
- }
-
- Thread.add( thisThread, false );
- Thread.add( thisContext );
- if ( Thread.sm_main !is null )
- multiThreadedFlag = true;
- return thisThread;
- }
-}
-
-
-/**
- * Deregisters the calling thread from use with the runtime. If this routine
- * is called for a thread which is not registered, the result is undefined.
- *
- * NOTE: This routine does not run thread-local static destructors when called.
- * If full functionality as a D thread is desired, the following function
- * must be called after thread_detachThis, particularly if the thread is
- * being detached at some indeterminate time before program termination:
- *
- * $(D extern(C) void rt_moduleTlsDtor();)
- */
-extern (C) void thread_detachThis() nothrow @nogc
-{
- if (auto t = Thread.getThis())
- Thread.remove(t);
-}
-
-
-/**
- * Deregisters the given thread from use with the runtime. If this routine
- * is called for a thread which is not registered, the result is undefined.
- *
- * NOTE: This routine does not run thread-local static destructors when called.
- * If full functionality as a D thread is desired, the following function
- * must be called by the detached thread, particularly if the thread is
- * being detached at some indeterminate time before program termination:
- *
- * $(D extern(C) void rt_moduleTlsDtor();)
- */
-extern (C) void thread_detachByAddr( ThreadID addr )
-{
- if ( auto t = thread_findByAddr( addr ) )
- Thread.remove( t );
-}
-
-
-/// ditto
-extern (C) void thread_detachInstance( Thread t ) nothrow @nogc
-{
- Thread.remove( t );
-}
-
-
-unittest
-{
- import core.sync.semaphore;
- auto sem = new Semaphore();
-
- auto t = new Thread(
- {
- sem.notify();
- Thread.sleep(100.msecs);
- }).start();
-
- sem.wait(); // thread cannot be detached while being started
- thread_detachInstance(t);
- foreach (t2; Thread)
- assert(t !is t2);
- t.join();
-}
-
-
-/**
- * Search the list of all threads for a thread with the given thread identifier.
- *
- * Params:
- * addr = The thread identifier to search for.
- * Returns:
- * The thread object associated with the thread identifier, null if not found.
- */
-static Thread thread_findByAddr( ThreadID addr )
-{
- Thread.slock.lock_nothrow();
- scope(exit) Thread.slock.unlock_nothrow();
-
- // also return just spawned thread so that
- // DLL_THREAD_ATTACH knows it's a D thread
- foreach (t; Thread.pAboutToStart[0 .. Thread.nAboutToStart])
- if (t.m_addr == addr)
- return t;
-
- foreach (t; Thread)
- if (t.m_addr == addr)
- return t;
-
- return null;
-}
-
-
-/**
- * Sets the current thread to a specific reference. Only to be used
- * when dealing with externally-created threads (in e.g. C code).
- * The primary use of this function is when Thread.getThis() must
- * return a sensible value in, for example, TLS destructors. In
- * other words, don't touch this unless you know what you're doing.
- *
- * Params:
- * t = A reference to the current thread. May be null.
- */
-extern (C) void thread_setThis(Thread t) nothrow @nogc
-{
- Thread.setThis(t);
-}
-
-
-/**
- * Joins all non-daemon threads that are currently running. This is done by
- * performing successive scans through the thread list until a scan consists
- * of only daemon threads.
- */
-extern (C) void thread_joinAll()
-{
- Lagain:
- Thread.slock.lock_nothrow();
- // wait for just spawned threads
- if (Thread.nAboutToStart)
- {
- Thread.slock.unlock_nothrow();
- Thread.yield();
- goto Lagain;
- }
-
- // join all non-daemon threads, the main thread is also a daemon
- auto t = Thread.sm_tbeg;
- while (t)
- {
- if (!t.isRunning)
- {
- auto tn = t.next;
- Thread.remove(t);
- t = tn;
- }
- else if (t.isDaemon)
- {
- t = t.next;
- }
- else
- {
- Thread.slock.unlock_nothrow();
- t.join(); // might rethrow
- goto Lagain; // must restart iteration b/c of unlock
- }
- }
- Thread.slock.unlock_nothrow();
-}
-
-
-/**
- * Performs intermediate shutdown of the thread module.
- */
-shared static ~this()
-{
- // NOTE: The functionality related to garbage collection must be minimally
- // operable after this dtor completes. Therefore, only minimal
- // cleanup may occur.
- auto t = Thread.sm_tbeg;
- while (t)
- {
- auto tn = t.next;
- if (!t.isRunning)
- Thread.remove(t);
- t = tn;
- }
-}
-
-
-// Used for needLock below.
-private __gshared bool multiThreadedFlag = false;
-
-// Calls the given delegate, passing the current thread's stack pointer to it.
-private void callWithStackShell(scope void delegate(void* sp) nothrow fn) nothrow
-in
-{
- assert(fn);
-}
-body
-{
- // The purpose of the 'shell' is to ensure all the registers get
- // put on the stack so they'll be scanned. We only need to push
- // the callee-save registers.
- void *sp = void;
-
- version (GNU)
- {
- __builtin_unwind_init();
- sp = &sp;
- }
- else version (AsmX86_Posix)
- {
- size_t[3] regs = void;
- asm pure nothrow @nogc
- {
- mov [regs + 0 * 4], EBX;
- mov [regs + 1 * 4], ESI;
- mov [regs + 2 * 4], EDI;
-
- mov sp[EBP], ESP;
- }
- }
- else version (AsmX86_Windows)
- {
- size_t[3] regs = void;
- asm pure nothrow @nogc
- {
- mov [regs + 0 * 4], EBX;
- mov [regs + 1 * 4], ESI;
- mov [regs + 2 * 4], EDI;
-
- mov sp[EBP], ESP;
- }
- }
- else version (AsmX86_64_Posix)
- {
- size_t[5] regs = void;
- asm pure nothrow @nogc
- {
- mov [regs + 0 * 8], RBX;
- mov [regs + 1 * 8], R12;
- mov [regs + 2 * 8], R13;
- mov [regs + 3 * 8], R14;
- mov [regs + 4 * 8], R15;
-
- mov sp[RBP], RSP;
- }
- }
- else version (AsmX86_64_Windows)
- {
- size_t[7] regs = void;
- asm pure nothrow @nogc
- {
- mov [regs + 0 * 8], RBX;
- mov [regs + 1 * 8], RSI;
- mov [regs + 2 * 8], RDI;
- mov [regs + 3 * 8], R12;
- mov [regs + 4 * 8], R13;
- mov [regs + 5 * 8], R14;
- mov [regs + 6 * 8], R15;
-
- mov sp[RBP], RSP;
- }
- }
- else
- {
- static assert(false, "Architecture not supported.");
- }
-
- fn(sp);
-}
-
-// Used for suspendAll/resumeAll below.
-private __gshared uint suspendDepth = 0;
-
-/**
- * Suspend the specified thread and load stack and register information for
- * use by thread_scanAll. If the supplied thread is the calling thread,
- * stack and register information will be loaded but the thread will not
- * be suspended. If the suspend operation fails and the thread is not
- * running then it will be removed from the global thread list, otherwise
- * an exception will be thrown.
- *
- * Params:
- * t = The thread to suspend.
- *
- * Throws:
- * ThreadError if the suspend operation fails for a running thread.
- * Returns:
- * Whether the thread is now suspended (true) or terminated (false).
- */
-private bool suspend( Thread t ) nothrow
-{
- Duration waittime = dur!"usecs"(10);
- Lagain:
- if (!t.isRunning)
- {
- Thread.remove(t);
- return false;
- }
- else if (t.m_isInCriticalRegion)
- {
- Thread.criticalRegionLock.unlock_nothrow();
- Thread.sleep(waittime);
- if (waittime < dur!"msecs"(10)) waittime *= 2;
- Thread.criticalRegionLock.lock_nothrow();
- goto Lagain;
- }
-
- version (Windows)
- {
- if ( t.m_addr != GetCurrentThreadId() && SuspendThread( t.m_hndl ) == 0xFFFFFFFF )
- {
- if ( !t.isRunning )
- {
- Thread.remove( t );
- return false;
- }
- onThreadError( "Unable to suspend thread" );
- }
-
- CONTEXT context = void;
- context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
-
- if ( !GetThreadContext( t.m_hndl, &context ) )
- onThreadError( "Unable to load thread context" );
- version (X86)
- {
- if ( !t.m_lock )
- t.m_curr.tstack = cast(void*) context.Esp;
- // eax,ebx,ecx,edx,edi,esi,ebp,esp
- t.m_reg[0] = context.Eax;
- t.m_reg[1] = context.Ebx;
- t.m_reg[2] = context.Ecx;
- t.m_reg[3] = context.Edx;
- t.m_reg[4] = context.Edi;
- t.m_reg[5] = context.Esi;
- t.m_reg[6] = context.Ebp;
- t.m_reg[7] = context.Esp;
- }
- else version (X86_64)
- {
- if ( !t.m_lock )
- t.m_curr.tstack = cast(void*) context.Rsp;
- // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp
- t.m_reg[0] = context.Rax;
- t.m_reg[1] = context.Rbx;
- t.m_reg[2] = context.Rcx;
- t.m_reg[3] = context.Rdx;
- t.m_reg[4] = context.Rdi;
- t.m_reg[5] = context.Rsi;
- t.m_reg[6] = context.Rbp;
- t.m_reg[7] = context.Rsp;
- // r8,r9,r10,r11,r12,r13,r14,r15
- t.m_reg[8] = context.R8;
- t.m_reg[9] = context.R9;
- t.m_reg[10] = context.R10;
- t.m_reg[11] = context.R11;
- t.m_reg[12] = context.R12;
- t.m_reg[13] = context.R13;
- t.m_reg[14] = context.R14;
- t.m_reg[15] = context.R15;
- }
- else
- {
- static assert(false, "Architecture not supported." );
- }
- }
- else version (Darwin)
- {
- if ( t.m_addr != pthread_self() && thread_suspend( t.m_tmach ) != KERN_SUCCESS )
- {
- if ( !t.isRunning )
- {
- Thread.remove( t );
- return false;
- }
- onThreadError( "Unable to suspend thread" );
- }
-
- version (X86)
- {
- x86_thread_state32_t state = void;
- mach_msg_type_number_t count = x86_THREAD_STATE32_COUNT;
-
- if ( thread_get_state( t.m_tmach, x86_THREAD_STATE32, &state, &count ) != KERN_SUCCESS )
- onThreadError( "Unable to load thread state" );
- if ( !t.m_lock )
- t.m_curr.tstack = cast(void*) state.esp;
- // eax,ebx,ecx,edx,edi,esi,ebp,esp
- t.m_reg[0] = state.eax;
- t.m_reg[1] = state.ebx;
- t.m_reg[2] = state.ecx;
- t.m_reg[3] = state.edx;
- t.m_reg[4] = state.edi;
- t.m_reg[5] = state.esi;
- t.m_reg[6] = state.ebp;
- t.m_reg[7] = state.esp;
- }
- else version (X86_64)
- {
- x86_thread_state64_t state = void;
- mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
-
- if ( thread_get_state( t.m_tmach, x86_THREAD_STATE64, &state, &count ) != KERN_SUCCESS )
- onThreadError( "Unable to load thread state" );
- if ( !t.m_lock )
- t.m_curr.tstack = cast(void*) state.rsp;
- // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp
- t.m_reg[0] = state.rax;
- t.m_reg[1] = state.rbx;
- t.m_reg[2] = state.rcx;
- t.m_reg[3] = state.rdx;
- t.m_reg[4] = state.rdi;
- t.m_reg[5] = state.rsi;
- t.m_reg[6] = state.rbp;
- t.m_reg[7] = state.rsp;
- // r8,r9,r10,r11,r12,r13,r14,r15
- t.m_reg[8] = state.r8;
- t.m_reg[9] = state.r9;
- t.m_reg[10] = state.r10;
- t.m_reg[11] = state.r11;
- t.m_reg[12] = state.r12;
- t.m_reg[13] = state.r13;
- t.m_reg[14] = state.r14;
- t.m_reg[15] = state.r15;
- }
- else
- {
- static assert(false, "Architecture not supported." );
- }
- }
- else version (Posix)
- {
- if ( t.m_addr != pthread_self() )
- {
- if ( pthread_kill( t.m_addr, suspendSignalNumber ) != 0 )
- {
- if ( !t.isRunning )
- {
- Thread.remove( t );
- return false;
- }
- onThreadError( "Unable to suspend thread" );
- }
- }
- else if ( !t.m_lock )
- {
- t.m_curr.tstack = getStackTop();
- }
- }
- return true;
-}
-
-/**
- * Suspend all threads but the calling thread for "stop the world" garbage
- * collection runs. This function may be called multiple times, and must
- * be followed by a matching number of calls to thread_resumeAll before
- * processing is resumed.
- *
- * Throws:
- * ThreadError if the suspend operation fails for a running thread.
- */
-extern (C) void thread_suspendAll() nothrow
-{
- // NOTE: We've got an odd chicken & egg problem here, because while the GC
- // is required to call thread_init before calling any other thread
- // routines, thread_init may allocate memory which could in turn
- // trigger a collection. Thus, thread_suspendAll, thread_scanAll,
- // and thread_resumeAll must be callable before thread_init
- // completes, with the assumption that no other GC memory has yet
- // been allocated by the system, and thus there is no risk of losing
- // data if the global thread list is empty. The check of
- // Thread.sm_tbeg below is done to ensure thread_init has completed,
- // and therefore that calling Thread.getThis will not result in an
- // error. For the short time when Thread.sm_tbeg is null, there is
- // no reason not to simply call the multithreaded code below, with
- // the expectation that the foreach loop will never be entered.
- if ( !multiThreadedFlag && Thread.sm_tbeg )
- {
- if ( ++suspendDepth == 1 )
- suspend( Thread.getThis() );
-
- return;
- }
-
- Thread.slock.lock_nothrow();
- {
- if ( ++suspendDepth > 1 )
- return;
-
- Thread.criticalRegionLock.lock_nothrow();
- scope (exit) Thread.criticalRegionLock.unlock_nothrow();
- size_t cnt;
- auto t = Thread.sm_tbeg;
- while (t)
- {
- auto tn = t.next;
- if (suspend(t))
- ++cnt;
- t = tn;
- }
-
- version (Darwin)
- {}
- else version (Posix)
- {
- // subtract own thread
- assert(cnt >= 1);
- --cnt;
- Lagain:
- // wait for semaphore notifications
- for (; cnt; --cnt)
- {
- while (sem_wait(&suspendCount) != 0)
- {
- if (errno != EINTR)
- onThreadError("Unable to wait for semaphore");
- errno = 0;
- }
- }
- version (FreeBSD)
- {
- // avoid deadlocks, see Issue 13416
- t = Thread.sm_tbeg;
- while (t)
- {
- auto tn = t.next;
- if (t.m_suspendagain && suspend(t))
- ++cnt;
- t = tn;
- }
- if (cnt)
- goto Lagain;
- }
- }
- }
-}
-
-/**
- * Resume the specified thread and unload stack and register information.
- * If the supplied thread is the calling thread, stack and register
- * information will be unloaded but the thread will not be resumed. If
- * the resume operation fails and the thread is not running then it will
- * be removed from the global thread list, otherwise an exception will be
- * thrown.
- *
- * Params:
- * t = The thread to resume.
- *
- * Throws:
- * ThreadError if the resume fails for a running thread.
- */
-private void resume( Thread t ) nothrow
-{
- version (Windows)
- {
- if ( t.m_addr != GetCurrentThreadId() && ResumeThread( t.m_hndl ) == 0xFFFFFFFF )
- {
- if ( !t.isRunning )
- {
- Thread.remove( t );
- return;
- }
- onThreadError( "Unable to resume thread" );
- }
-
- if ( !t.m_lock )
- t.m_curr.tstack = t.m_curr.bstack;
- t.m_reg[0 .. $] = 0;
- }
- else version (Darwin)
- {
- if ( t.m_addr != pthread_self() && thread_resume( t.m_tmach ) != KERN_SUCCESS )
- {
- if ( !t.isRunning )
- {
- Thread.remove( t );
- return;
- }
- onThreadError( "Unable to resume thread" );
- }
-
- if ( !t.m_lock )
- t.m_curr.tstack = t.m_curr.bstack;
- t.m_reg[0 .. $] = 0;
- }
- else version (Posix)
- {
- if ( t.m_addr != pthread_self() )
- {
- if ( pthread_kill( t.m_addr, resumeSignalNumber ) != 0 )
- {
- if ( !t.isRunning )
- {
- Thread.remove( t );
- return;
- }
- onThreadError( "Unable to resume thread" );
- }
- }
- else if ( !t.m_lock )
- {
- t.m_curr.tstack = t.m_curr.bstack;
- }
- }
-}
-
-/**
- * Resume all threads but the calling thread for "stop the world" garbage
- * collection runs. This function must be called once for each preceding
- * call to thread_suspendAll before the threads are actually resumed.
- *
- * In:
- * This routine must be preceded by a call to thread_suspendAll.
- *
- * Throws:
- * ThreadError if the resume operation fails for a running thread.
- */
-extern (C) void thread_resumeAll() nothrow
-in
-{
- assert( suspendDepth > 0 );
-}
-body
-{
- // NOTE: See thread_suspendAll for the logic behind this.
- if ( !multiThreadedFlag && Thread.sm_tbeg )
- {
- if ( --suspendDepth == 0 )
- resume( Thread.getThis() );
- return;
- }
-
- scope(exit) Thread.slock.unlock_nothrow();
- {
- if ( --suspendDepth > 0 )
- return;
-
- for ( Thread t = Thread.sm_tbeg; t; t = t.next )
- {
- // NOTE: We do not need to care about critical regions at all
- // here. thread_suspendAll takes care of everything.
- resume( t );
- }
- }
-}
-
-/**
- * Indicates the kind of scan being performed by $(D thread_scanAllType).
- */
-enum ScanType
-{
- stack, /// The stack and/or registers are being scanned.
- tls, /// TLS data is being scanned.
-}
-
-alias ScanAllThreadsFn = void delegate(void*, void*) nothrow; /// The scanning function.
-alias ScanAllThreadsTypeFn = void delegate(ScanType, void*, void*) nothrow; /// ditto
-
-/**
- * The main entry point for garbage collection. The supplied delegate
- * will be passed ranges representing both stack and register values.
- *
- * Params:
- * scan = The scanner function. It should scan from p1 through p2 - 1.
- *
- * In:
- * This routine must be preceded by a call to thread_suspendAll.
- */
-extern (C) void thread_scanAllType( scope ScanAllThreadsTypeFn scan ) nothrow
-in
-{
- assert( suspendDepth > 0 );
-}
-body
-{
- callWithStackShell(sp => scanAllTypeImpl(scan, sp));
-}
-
-
-private void scanAllTypeImpl( scope ScanAllThreadsTypeFn scan, void* curStackTop ) nothrow
-{
- Thread thisThread = null;
- void* oldStackTop = null;
-
- if ( Thread.sm_tbeg )
- {
- thisThread = Thread.getThis();
- if ( !thisThread.m_lock )
- {
- oldStackTop = thisThread.m_curr.tstack;
- thisThread.m_curr.tstack = curStackTop;
- }
- }
-
- scope( exit )
- {
- if ( Thread.sm_tbeg )
- {
- if ( !thisThread.m_lock )
- {
- thisThread.m_curr.tstack = oldStackTop;
- }
- }
- }
-
- // NOTE: Synchronizing on Thread.slock is not needed because this
- // function may only be called after all other threads have
- // been suspended from within the same lock.
- if (Thread.nAboutToStart)
- scan(ScanType.stack, Thread.pAboutToStart, Thread.pAboutToStart + Thread.nAboutToStart);
-
- for ( Thread.Context* c = Thread.sm_cbeg; c; c = c.next )
- {
- version (StackGrowsDown)
- {
- // NOTE: We can't index past the bottom of the stack
- // so don't do the "+1" for StackGrowsDown.
- if ( c.tstack && c.tstack < c.bstack )
- scan( ScanType.stack, c.tstack, c.bstack );
- }
- else
- {
- if ( c.bstack && c.bstack < c.tstack )
- scan( ScanType.stack, c.bstack, c.tstack + 1 );
- }
- }
-
- for ( Thread t = Thread.sm_tbeg; t; t = t.next )
- {
- version (Windows)
- {
- // Ideally, we'd pass ScanType.regs or something like that, but this
- // would make portability annoying because it only makes sense on Windows.
- scan( ScanType.stack, t.m_reg.ptr, t.m_reg.ptr + t.m_reg.length );
- }
-
- if (t.m_tlsgcdata !is null)
- rt_tlsgc_scan(t.m_tlsgcdata, (p1, p2) => scan(ScanType.tls, p1, p2));
- }
-}
-
-/**
- * The main entry point for garbage collection. The supplied delegate
- * will be passed ranges representing both stack and register values.
- *
- * Params:
- * scan = The scanner function. It should scan from p1 through p2 - 1.
- *
- * In:
- * This routine must be preceded by a call to thread_suspendAll.
- */
-extern (C) void thread_scanAll( scope ScanAllThreadsFn scan ) nothrow
-{
- thread_scanAllType((type, p1, p2) => scan(p1, p2));
-}
-
-
-/**
- * Signals that the code following this call is a critical region. Any code in
- * this region must finish running before the calling thread can be suspended
- * by a call to thread_suspendAll.
- *
- * This function is, in particular, meant to help maintain garbage collector
- * invariants when a lock is not used.
- *
- * A critical region is exited with thread_exitCriticalRegion.
- *
- * $(RED Warning):
- * Using critical regions is extremely error-prone. For instance, using locks
- * inside a critical region can easily result in a deadlock when another thread
- * holding the lock already got suspended.
- *
- * The term and concept of a 'critical region' comes from
- * $(LINK2 https://github.com/mono/mono/blob/521f4a198e442573c400835ef19bbb36b60b0ebb/mono/metadata/sgen-gc.h#L925 Mono's SGen garbage collector).
- *
- * In:
- * The calling thread must be attached to the runtime.
- */
-extern (C) void thread_enterCriticalRegion() @nogc
-in
-{
- assert(Thread.getThis());
-}
-body
-{
- synchronized (Thread.criticalRegionLock)
- Thread.getThis().m_isInCriticalRegion = true;
-}
-
-
-/**
- * Signals that the calling thread is no longer in a critical region. Following
- * a call to this function, the thread can once again be suspended.
- *
- * In:
- * The calling thread must be attached to the runtime.
- */
-extern (C) void thread_exitCriticalRegion() @nogc
-in
-{
- assert(Thread.getThis());
-}
-body
-{
- synchronized (Thread.criticalRegionLock)
- Thread.getThis().m_isInCriticalRegion = false;
-}
-
-
-/**
- * Returns true if the current thread is in a critical region; otherwise, false.
- *
- * In:
- * The calling thread must be attached to the runtime.
- */
-extern (C) bool thread_inCriticalRegion() @nogc
-in
-{
- assert(Thread.getThis());
-}
-body
-{
- synchronized (Thread.criticalRegionLock)
- return Thread.getThis().m_isInCriticalRegion;
-}
-
-
-/**
-* A callback for thread errors in D during collections. Since an allocation is not possible
-* a preallocated ThreadError will be used as the Error instance
-*
-* Throws:
-* ThreadError.
-*/
-private void onThreadError(string msg = null, Throwable next = null) nothrow
-{
- __gshared ThreadError error = new ThreadError(null);
- error.msg = msg;
- error.next = next;
- import core.exception : SuppressTraceInfo;
- error.info = SuppressTraceInfo.instance;
- throw error;
-}
-
-
-unittest
-{
- assert(!thread_inCriticalRegion());
-
- {
- thread_enterCriticalRegion();
-
- scope (exit)
- thread_exitCriticalRegion();
-
- assert(thread_inCriticalRegion());
- }
-
- assert(!thread_inCriticalRegion());
-}
-
-unittest
-{
- // NOTE: This entire test is based on the assumption that no
- // memory is allocated after the child thread is
- // started. If an allocation happens, a collection could
- // trigger, which would cause the synchronization below
- // to cause a deadlock.
- // NOTE: DO NOT USE LOCKS IN CRITICAL REGIONS IN NORMAL CODE.
-
- import core.sync.semaphore;
-
- auto sema = new Semaphore(),
- semb = new Semaphore();
-
- auto thr = new Thread(
- {
- thread_enterCriticalRegion();
- assert(thread_inCriticalRegion());
- sema.notify();
-
- semb.wait();
- assert(thread_inCriticalRegion());
-
- thread_exitCriticalRegion();
- assert(!thread_inCriticalRegion());
- sema.notify();
-
- semb.wait();
- assert(!thread_inCriticalRegion());
- });
-
- thr.start();
-
- sema.wait();
- synchronized (Thread.criticalRegionLock)
- assert(thr.m_isInCriticalRegion);
- semb.notify();
-
- sema.wait();
- synchronized (Thread.criticalRegionLock)
- assert(!thr.m_isInCriticalRegion);
- semb.notify();
-
- thr.join();
-}
-
-unittest
-{
- import core.sync.semaphore;
-
- shared bool inCriticalRegion;
- auto sema = new Semaphore(),
- semb = new Semaphore();
-
- auto thr = new Thread(
- {
- thread_enterCriticalRegion();
- inCriticalRegion = true;
- sema.notify();
- semb.wait();
-
- Thread.sleep(dur!"msecs"(1));
- inCriticalRegion = false;
- thread_exitCriticalRegion();
- });
- thr.start();
-
- sema.wait();
- assert(inCriticalRegion);
- semb.notify();
-
- thread_suspendAll();
- assert(!inCriticalRegion);
- thread_resumeAll();
-}
-
-/**
- * Indicates whether an address has been marked by the GC.
- */
-enum IsMarked : int
-{
- no, /// Address is not marked.
- yes, /// Address is marked.
- unknown, /// Address is not managed by the GC.
-}
-
-alias IsMarkedDg = int delegate( void* addr ) nothrow; /// The isMarked callback function.
-
-/**
- * This routine allows the runtime to process any special per-thread handling
- * for the GC. This is needed for taking into account any memory that is
- * referenced by non-scanned pointers but is about to be freed. That currently
- * means the array append cache.
- *
- * Params:
- * isMarked = The function used to check if $(D addr) is marked.
- *
- * In:
- * This routine must be called just prior to resuming all threads.
- */
-extern(C) void thread_processGCMarks( scope IsMarkedDg isMarked ) nothrow
-{
- for ( Thread t = Thread.sm_tbeg; t; t = t.next )
- {
- /* Can be null if collection was triggered between adding a
- * thread and calling rt_tlsgc_init.
- */
- if (t.m_tlsgcdata !is null)
- rt_tlsgc_processGCMarks(t.m_tlsgcdata, isMarked);
- }
-}
-
-
-extern (C) @nogc nothrow
-{
- version (CRuntime_Glibc) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr);
- version (FreeBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr);
- version (NetBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr);
- version (OpenBSD) int pthread_stackseg_np(pthread_t thread, stack_t* sinfo);
- version (DragonFlyBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr);
- version (Solaris) int thr_stksegment(stack_t* stk);
- version (CRuntime_Bionic) int pthread_getattr_np(pthread_t thid, pthread_attr_t* attr);
- version (CRuntime_Musl) int pthread_getattr_np(pthread_t, pthread_attr_t*);
- version (CRuntime_UClibc) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr);
-}
-
-
-private void* getStackTop() nothrow @nogc
-{
- version (D_InlineAsm_X86)
- asm pure nothrow @nogc { naked; mov EAX, ESP; ret; }
- else version (D_InlineAsm_X86_64)
- asm pure nothrow @nogc { naked; mov RAX, RSP; ret; }
- else version (GNU)
- return __builtin_frame_address(0);
- else
- static assert(false, "Architecture not supported.");
-}
-
-
-private void* getStackBottom() nothrow @nogc
-{
- version (Windows)
- {
- version (D_InlineAsm_X86)
- asm pure nothrow @nogc { naked; mov EAX, FS:4; ret; }
- else version (D_InlineAsm_X86_64)
- asm pure nothrow @nogc
- { naked;
- mov RAX, 8;
- mov RAX, GS:[RAX];
- ret;
- }
- else version (GNU_InlineAsm)
- {
- void *bottom;
-
- version (X86)
- asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
- else version (X86_64)
- asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
- else
- static assert(false, "Platform not supported.");
-
- return bottom;
- }
- else
- static assert(false, "Architecture not supported.");
- }
- else version (Darwin)
- {
- import core.sys.darwin.pthread;
- return pthread_get_stackaddr_np(pthread_self());
- }
- else version (CRuntime_Glibc)
- {
- pthread_attr_t attr;
- void* addr; size_t size;
-
- pthread_getattr_np(pthread_self(), &attr);
- pthread_attr_getstack(&attr, &addr, &size);
- pthread_attr_destroy(&attr);
- version (StackGrowsDown)
- addr += size;
- return addr;
- }
- else version (FreeBSD)
- {
- pthread_attr_t attr;
- void* addr; size_t size;
-
- pthread_attr_init(&attr);
- pthread_attr_get_np(pthread_self(), &attr);
- pthread_attr_getstack(&attr, &addr, &size);
- pthread_attr_destroy(&attr);
- version (StackGrowsDown)
- addr += size;
- return addr;
- }
- else version (NetBSD)
- {
- pthread_attr_t attr;
- void* addr; size_t size;
-
- pthread_attr_init(&attr);
- pthread_attr_get_np(pthread_self(), &attr);
- pthread_attr_getstack(&attr, &addr, &size);
- pthread_attr_destroy(&attr);
- version (StackGrowsDown)
- addr += size;
- return addr;
- }
- else version (OpenBSD)
- {
- stack_t stk;
-
- pthread_stackseg_np(pthread_self(), &stk);
- return stk.ss_sp;
- }
- else version (DragonFlyBSD)
- {
- pthread_attr_t attr;
- void* addr; size_t size;
-
- pthread_attr_init(&attr);
- pthread_attr_get_np(pthread_self(), &attr);
- pthread_attr_getstack(&attr, &addr, &size);
- pthread_attr_destroy(&attr);
- version (StackGrowsDown)
- addr += size;
- return addr;
- }
- else version (Solaris)
- {
- stack_t stk;
-
- thr_stksegment(&stk);
- return stk.ss_sp;
- }
- else version (CRuntime_Bionic)
- {
- pthread_attr_t attr;
- void* addr; size_t size;
-
- pthread_getattr_np(pthread_self(), &attr);
- pthread_attr_getstack(&attr, &addr, &size);
- pthread_attr_destroy(&attr);
- version (StackGrowsDown)
- addr += size;
- return addr;
- }
- else version (CRuntime_Musl)
- {
- pthread_attr_t attr;
- void* addr; size_t size;
-
- pthread_getattr_np(pthread_self(), &attr);
- pthread_attr_getstack(&attr, &addr, &size);
- pthread_attr_destroy(&attr);
- version (StackGrowsDown)
- addr += size;
- return addr;
- }
- else version (CRuntime_UClibc)
- {
- pthread_attr_t attr;
- void* addr; size_t size;
-
- pthread_getattr_np(pthread_self(), &attr);
- pthread_attr_getstack(&attr, &addr, &size);
- pthread_attr_destroy(&attr);
- version (StackGrowsDown)
- addr += size;
- return addr;
- }
- else
- static assert(false, "Platform not supported.");
-}
-
-
-/**
- * Returns the stack top of the currently active stack within the calling
- * thread.
- *
- * In:
- * The calling thread must be attached to the runtime.
- *
- * Returns:
- * The address of the stack top.
- */
-extern (C) void* thread_stackTop() nothrow @nogc
-in
-{
- // Not strictly required, but it gives us more flexibility.
- assert(Thread.getThis());
-}
-body
-{
- return getStackTop();
-}
-
-
-/**
- * Returns the stack bottom of the currently active stack within the calling
- * thread.
- *
- * In:
- * The calling thread must be attached to the runtime.
- *
- * Returns:
- * The address of the stack bottom.
- */
-extern (C) void* thread_stackBottom() nothrow @nogc
-in
-{
- assert(Thread.getThis());
-}
-body
-{
- return Thread.getThis().topContext().bstack;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Thread Group
-///////////////////////////////////////////////////////////////////////////////
-
-
-/**
- * This class is intended to simplify certain common programming techniques.
- */
-class ThreadGroup
-{
- /**
- * Creates and starts a new Thread object that executes fn and adds it to
- * the list of tracked threads.
- *
- * Params:
- * fn = The thread function.
- *
- * Returns:
- * A reference to the newly created thread.
- */
- final Thread create( void function() fn )
- {
- Thread t = new Thread( fn ).start();
-
- synchronized( this )
- {
- m_all[t] = t;
- }
- return t;
- }
-
-
- /**
- * Creates and starts a new Thread object that executes dg and adds it to
- * the list of tracked threads.
- *
- * Params:
- * dg = The thread function.
- *
- * Returns:
- * A reference to the newly created thread.
- */
- final Thread create( void delegate() dg )
- {
- Thread t = new Thread( dg ).start();
-
- synchronized( this )
- {
- m_all[t] = t;
- }
- return t;
- }
-
-
- /**
- * Add t to the list of tracked threads if it is not already being tracked.
- *
- * Params:
- * t = The thread to add.
- *
- * In:
- * t must not be null.
- */
- final void add( Thread t )
- in
- {
- assert( t );
- }
- body
- {
- synchronized( this )
- {
- m_all[t] = t;
- }
- }
-
-
- /**
- * Removes t from the list of tracked threads. No operation will be
- * performed if t is not currently being tracked by this object.
- *
- * Params:
- * t = The thread to remove.
- *
- * In:
- * t must not be null.
- */
- final void remove( Thread t )
- in
- {
- assert( t );
- }
- body
- {
- synchronized( this )
- {
- m_all.remove( t );
- }
- }
-
-
- /**
- * Operates on all threads currently tracked by this object.
- */
- final int opApply( scope int delegate( ref Thread ) dg )
- {
- synchronized( this )
- {
- int ret = 0;
-
- // NOTE: This loop relies on the knowledge that m_all uses the
- // Thread object for both the key and the mapped value.
- foreach ( Thread t; m_all.keys )
- {
- ret = dg( t );
- if ( ret )
- break;
- }
- return ret;
- }
- }
-
-
- /**
- * Iteratively joins all tracked threads. This function will block add,
- * remove, and opApply until it completes.
- *
- * Params:
- * rethrow = Rethrow any unhandled exception which may have caused the
- * current thread to terminate.
- *
- * Throws:
- * Any exception not handled by the joined threads.
- */
- final void joinAll( bool rethrow = true )
- {
- synchronized( this )
- {
- // NOTE: This loop relies on the knowledge that m_all uses the
- // Thread object for both the key and the mapped value.
- foreach ( Thread t; m_all.keys )
- {
- t.join( rethrow );
- }
- }
- }
-
-
-private:
- Thread[Thread] m_all;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Fiber Platform Detection and Memory Allocation
-///////////////////////////////////////////////////////////////////////////////
-
-
-private
-{
- version (D_InlineAsm_X86)
- {
- version (Windows)
- version = AsmX86_Windows;
- else version (Posix)
- version = AsmX86_Posix;
-
- version (Darwin)
- version = AlignFiberStackTo16Byte;
- }
- else version (D_InlineAsm_X86_64)
- {
- version (Windows)
- {
- version = AsmX86_64_Windows;
- version = AlignFiberStackTo16Byte;
- }
- else version (Posix)
- {
- version = AsmX86_64_Posix;
- version = AlignFiberStackTo16Byte;
- }
- }
- else version (X86)
- {
- version = AlignFiberStackTo16Byte;
-
- version (CET)
- {
- // fiber_switchContext does not support shadow stack from
- // Intel CET. So use ucontext implementation.
- }
- else
- {
- version = AsmExternal;
-
- version (MinGW)
- version = GNU_AsmX86_Windows;
- else version (Posix)
- version = AsmX86_Posix;
- }
- }
- else version (X86_64)
- {
- version = AlignFiberStackTo16Byte;
-
- version (CET)
- {
- // fiber_switchContext does not support shadow stack from
- // Intel CET. So use ucontext implementation.
- }
- else version (D_X32)
- {
- // let X32 be handled by ucontext swapcontext
- }
- else
- {
- version = AsmExternal;
-
- version (MinGW)
- version = GNU_AsmX86_64_Windows;
- else version (Posix)
- version = AsmX86_64_Posix;
- }
- }
- else version (PPC)
- {
- version (Posix)
- {
- version = AsmPPC_Posix;
- version = AsmExternal;
- }
- }
- else version (PPC64)
- {
- version (Posix)
- {
- version = AlignFiberStackTo16Byte;
- }
- }
- else version (MIPS_O32)
- {
- version (Posix)
- {
- version = AsmMIPS_O32_Posix;
- version = AsmExternal;
- }
- }
- else version (AArch64)
- {
- version (Posix)
- {
- version = AsmAArch64_Posix;
- version = AsmExternal;
- version = AlignFiberStackTo16Byte;
- }
- }
- else version (ARM)
- {
- version (Posix)
- {
- version = AsmARM_Posix;
- version = AsmExternal;
- }
- }
- else version (SPARC)
- {
- // NOTE: The SPARC ABI specifies only doubleword alignment.
- version = AlignFiberStackTo16Byte;
- }
- else version (SPARC64)
- {
- version = AlignFiberStackTo16Byte;
- }
-
- version (Posix)
- {
- import core.sys.posix.unistd; // for sysconf
-
- version (AsmX86_Windows) {} else
- version (AsmX86_Posix) {} else
- version (AsmX86_64_Windows) {} else
- version (AsmX86_64_Posix) {} else
- version (AsmExternal) {} else
- {
- // NOTE: The ucontext implementation requires architecture specific
- // data definitions to operate so testing for it must be done
- // by checking for the existence of ucontext_t rather than by
- // a version identifier. Please note that this is considered
- // an obsolescent feature according to the POSIX spec, so a
- // custom solution is still preferred.
- import core.sys.posix.ucontext;
- }
- }
-
- static immutable size_t PAGESIZE;
- version (Posix) static immutable size_t PTHREAD_STACK_MIN;
-}
-
-
-shared static this()
-{
- version (Windows)
- {
- SYSTEM_INFO info;
- GetSystemInfo(&info);
-
- PAGESIZE = info.dwPageSize;
- assert(PAGESIZE < int.max);
- }
- else version (Posix)
- {
- PAGESIZE = cast(size_t)sysconf(_SC_PAGESIZE);
- PTHREAD_STACK_MIN = cast(size_t)sysconf(_SC_THREAD_STACK_MIN);
- }
- else
- {
- static assert(0, "unimplemented");
- }
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Fiber Entry Point and Context Switch
-///////////////////////////////////////////////////////////////////////////////
-
-
-private
-{
- extern (C) void fiber_entryPoint() nothrow
- {
- Fiber obj = Fiber.getThis();
- assert( obj );
-
- assert( Thread.getThis().m_curr is obj.m_ctxt );
- atomicStore!(MemoryOrder.raw)(*cast(shared)&Thread.getThis().m_lock, false);
- obj.m_ctxt.tstack = obj.m_ctxt.bstack;
- obj.m_state = Fiber.State.EXEC;
-
- try
- {
- obj.run();
- }
- catch ( Throwable t )
- {
- obj.m_unhandled = t;
- }
-
- static if ( __traits( compiles, ucontext_t ) )
- obj.m_ucur = &obj.m_utxt;
-
- obj.m_state = Fiber.State.TERM;
- obj.switchOut();
- }
-
- // Look above the definition of 'class Fiber' for some information about the implementation of this routine
- version (AsmExternal)
- {
- extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc;
- version (AArch64)
- extern (C) void fiber_trampoline() nothrow;
- }
- else
- extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc
- {
- // NOTE: The data pushed and popped in this routine must match the
- // default stack created by Fiber.initStack or the initial
- // switch into a new context will fail.
-
- version (AsmX86_Windows)
- {
- asm pure nothrow @nogc
- {
- naked;
-
- // save current stack state
- push EBP;
- mov EBP, ESP;
- push EDI;
- push ESI;
- push EBX;
- push dword ptr FS:[0];
- push dword ptr FS:[4];
- push dword ptr FS:[8];
- push EAX;
-
- // store oldp again with more accurate address
- mov EAX, dword ptr 8[EBP];
- mov [EAX], ESP;
- // load newp to begin context switch
- mov ESP, dword ptr 12[EBP];
-
- // load saved state from new stack
- pop EAX;
- pop dword ptr FS:[8];
- pop dword ptr FS:[4];
- pop dword ptr FS:[0];
- pop EBX;
- pop ESI;
- pop EDI;
- pop EBP;
-
- // 'return' to complete switch
- pop ECX;
- jmp ECX;
- }
- }
- else version (AsmX86_64_Windows)
- {
- asm pure nothrow @nogc
- {
- naked;
-
- // save current stack state
- // NOTE: When changing the layout of registers on the stack,
- // make sure that the XMM registers are still aligned.
- // On function entry, the stack is guaranteed to not
- // be aligned to 16 bytes because of the return address
- // on the stack.
- push RBP;
- mov RBP, RSP;
- push R12;
- push R13;
- push R14;
- push R15;
- push RDI;
- push RSI;
- // 7 registers = 56 bytes; stack is now aligned to 16 bytes
- sub RSP, 160;
- movdqa [RSP + 144], XMM6;
- movdqa [RSP + 128], XMM7;
- movdqa [RSP + 112], XMM8;
- movdqa [RSP + 96], XMM9;
- movdqa [RSP + 80], XMM10;
- movdqa [RSP + 64], XMM11;
- movdqa [RSP + 48], XMM12;
- movdqa [RSP + 32], XMM13;
- movdqa [RSP + 16], XMM14;
- movdqa [RSP], XMM15;
- push RBX;
- xor RAX,RAX;
- push qword ptr GS:[RAX];
- push qword ptr GS:8[RAX];
- push qword ptr GS:16[RAX];
-
- // store oldp
- mov [RCX], RSP;
- // load newp to begin context switch
- mov RSP, RDX;
-
- // load saved state from new stack
- pop qword ptr GS:16[RAX];
- pop qword ptr GS:8[RAX];
- pop qword ptr GS:[RAX];
- pop RBX;
- movdqa XMM15, [RSP];
- movdqa XMM14, [RSP + 16];
- movdqa XMM13, [RSP + 32];
- movdqa XMM12, [RSP + 48];
- movdqa XMM11, [RSP + 64];
- movdqa XMM10, [RSP + 80];
- movdqa XMM9, [RSP + 96];
- movdqa XMM8, [RSP + 112];
- movdqa XMM7, [RSP + 128];
- movdqa XMM6, [RSP + 144];
- add RSP, 160;
- pop RSI;
- pop RDI;
- pop R15;
- pop R14;
- pop R13;
- pop R12;
- pop RBP;
-
- // 'return' to complete switch
- pop RCX;
- jmp RCX;
- }
- }
- else version (AsmX86_Posix)
- {
- asm pure nothrow @nogc
- {
- naked;
-
- // save current stack state
- push EBP;
- mov EBP, ESP;
- push EDI;
- push ESI;
- push EBX;
- push EAX;
-
- // store oldp again with more accurate address
- mov EAX, dword ptr 8[EBP];
- mov [EAX], ESP;
- // load newp to begin context switch
- mov ESP, dword ptr 12[EBP];
-
- // load saved state from new stack
- pop EAX;
- pop EBX;
- pop ESI;
- pop EDI;
- pop EBP;
-
- // 'return' to complete switch
- pop ECX;
- jmp ECX;
- }
- }
- else version (AsmX86_64_Posix)
- {
- asm pure nothrow @nogc
- {
- naked;
-
- // save current stack state
- push RBP;
- mov RBP, RSP;
- push RBX;
- push R12;
- push R13;
- push R14;
- push R15;
-
- // store oldp
- mov [RDI], RSP;
- // load newp to begin context switch
- mov RSP, RSI;
-
- // load saved state from new stack
- pop R15;
- pop R14;
- pop R13;
- pop R12;
- pop RBX;
- pop RBP;
-
- // 'return' to complete switch
- pop RCX;
- jmp RCX;
- }
- }
- else static if ( __traits( compiles, ucontext_t ) )
- {
- Fiber cfib = Fiber.getThis();
- void* ucur = cfib.m_ucur;
-
- *oldp = &ucur;
- swapcontext( **(cast(ucontext_t***) oldp),
- *(cast(ucontext_t**) newp) );
- }
- else
- static assert(0, "Not implemented");
- }
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Fiber
-///////////////////////////////////////////////////////////////////////////////
-/*
- * Documentation of Fiber internals:
- *
- * The main routines to implement when porting Fibers to new architectures are
- * fiber_switchContext and initStack. Some version constants have to be defined
- * for the new platform as well, search for "Fiber Platform Detection and Memory Allocation".
- *
- * Fibers are based on a concept called 'Context'. A Context describes the execution
- * state of a Fiber or main thread which is fully described by the stack, some
- * registers and a return address at which the Fiber/Thread should continue executing.
- * Please note that not only each Fiber has a Context, but each thread also has got a
- * Context which describes the threads stack and state. If you call Fiber fib; fib.call
- * the first time in a thread you switch from Threads Context into the Fibers Context.
- * If you call fib.yield in that Fiber you switch out of the Fibers context and back
- * into the Thread Context. (However, this is not always the case. You can call a Fiber
- * from within another Fiber, then you switch Contexts between the Fibers and the Thread
- * Context is not involved)
- *
- * In all current implementations the registers and the return address are actually
- * saved on a Contexts stack.
- *
- * The fiber_switchContext routine has got two parameters:
- * void** a: This is the _location_ where we have to store the current stack pointer,
- * the stack pointer of the currently executing Context (Fiber or Thread).
- * void* b: This is the pointer to the stack of the Context which we want to switch into.
- * Note that we get the same pointer here as the one we stored into the void** a
- * in a previous call to fiber_switchContext.
- *
- * In the simplest case, a fiber_switchContext rountine looks like this:
- * fiber_switchContext:
- * push {return Address}
- * push {registers}
- * copy {stack pointer} into {location pointed to by a}
- * //We have now switch to the stack of a different Context!
- * copy {b} into {stack pointer}
- * pop {registers}
- * pop {return Address}
- * jump to {return Address}
- *
- * The GC uses the value returned in parameter a to scan the Fibers stack. It scans from
- * the stack base to that value. As the GC dislikes false pointers we can actually optimize
- * this a little: By storing registers which can not contain references to memory managed
- * by the GC outside of the region marked by the stack base pointer and the stack pointer
- * saved in fiber_switchContext we can prevent the GC from scanning them.
- * Such registers are usually floating point registers and the return address. In order to
- * implement this, we return a modified stack pointer from fiber_switchContext. However,
- * we have to remember that when we restore the registers from the stack!
- *
- * --------------------------- <= Stack Base
- * | Frame | <= Many other stack frames
- * | Frame |
- * |-------------------------| <= The last stack frame. This one is created by fiber_switchContext
- * | registers with pointers |
- * | | <= Stack pointer. GC stops scanning here
- * | return address |
- * |floating point registers |
- * --------------------------- <= Real Stack End
- *
- * fiber_switchContext:
- * push {registers with pointers}
- * copy {stack pointer} into {location pointed to by a}
- * push {return Address}
- * push {Floating point registers}
- * //We have now switch to the stack of a different Context!
- * copy {b} into {stack pointer}
- * //We now have to adjust the stack pointer to point to 'Real Stack End' so we can pop
- * //the FP registers
- * //+ or - depends on if your stack grows downwards or upwards
- * {stack pointer} = {stack pointer} +- ({FPRegisters}.sizeof + {return address}.sizeof}
- * pop {Floating point registers}
- * pop {return Address}
- * pop {registers with pointers}
- * jump to {return Address}
- *
- * So the question now is which registers need to be saved? This depends on the specific
- * architecture ABI of course, but here are some general guidelines:
- * - If a register is callee-save (if the callee modifies the register it must saved and
- * restored by the callee) it needs to be saved/restored in switchContext
- * - If a register is caller-save it needn't be saved/restored. (Calling fiber_switchContext
- * is a function call and the compiler therefore already must save these registers before
- * calling fiber_switchContext)
- * - Argument registers used for passing parameters to functions needn't be saved/restored
- * - The return register needn't be saved/restored (fiber_switchContext hasn't got a return type)
- * - All scratch registers needn't be saved/restored
- * - The link register usually needn't be saved/restored (but sometimes it must be cleared -
- * see below for details)
- * - The frame pointer register - if it exists - is usually callee-save
- * - All current implementations do not save control registers
- *
- * What happens on the first switch into a Fiber? We never saved a state for this fiber before,
- * but the initial state is prepared in the initStack routine. (This routine will also be called
- * when a Fiber is being resetted). initStack must produce exactly the same stack layout as the
- * part of fiber_switchContext which saves the registers. Pay special attention to set the stack
- * pointer correctly if you use the GC optimization mentioned before. the return Address saved in
- * initStack must be the address of fiber_entrypoint.
- *
- * There's now a small but important difference between the first context switch into a fiber and
- * further context switches. On the first switch, Fiber.call is used and the returnAddress in
- * fiber_switchContext will point to fiber_entrypoint. The important thing here is that this jump
- * is a _function call_, we call fiber_entrypoint by jumping before it's function prologue. On later
- * calls, the user used yield() in a function, and therefore the return address points into a user
- * function, after the yield call. So here the jump in fiber_switchContext is a _function return_,
- * not a function call!
- *
- * The most important result of this is that on entering a function, i.e. fiber_entrypoint, we
- * would have to provide a return address / set the link register once fiber_entrypoint
- * returns. Now fiber_entrypoint does never return and therefore the actual value of the return
- * address / link register is never read/used and therefore doesn't matter. When fiber_switchContext
- * performs a _function return_ the value in the link register doesn't matter either.
- * However, the link register will still be saved to the stack in fiber_entrypoint and some
- * exception handling / stack unwinding code might read it from this stack location and crash.
- * The exact solution depends on your architecture, but see the ARM implementation for a way
- * to deal with this issue.
- *
- * The ARM implementation is meant to be used as a kind of documented example implementation.
- * Look there for a concrete example.
- *
- * FIXME: fiber_entrypoint might benefit from a @noreturn attribute, but D doesn't have one.
- */
-
-/**
- * This class provides a cooperative concurrency mechanism integrated with the
- * threading and garbage collection functionality. Calling a fiber may be
- * considered a blocking operation that returns when the fiber yields (via
- * Fiber.yield()). Execution occurs within the context of the calling thread
- * so synchronization is not necessary to guarantee memory visibility so long
- * as the same thread calls the fiber each time. Please note that there is no
- * requirement that a fiber be bound to one specific thread. Rather, fibers
- * may be freely passed between threads so long as they are not currently
- * executing. Like threads, a new fiber thread may be created using either
- * derivation or composition, as in the following example.
- *
- * Warning:
- * Status registers are not saved by the current implementations. This means
- * floating point exception status bits (overflow, divide by 0), rounding mode
- * and similar stuff is set per-thread, not per Fiber!
- *
- * Warning:
- * On ARM FPU registers are not saved if druntime was compiled as ARM_SoftFloat.
- * If such a build is used on a ARM_SoftFP system which actually has got a FPU
- * and other libraries are using the FPU registers (other code is compiled
- * as ARM_SoftFP) this can cause problems. Druntime must be compiled as
- * ARM_SoftFP in this case.
- *
- * Example:
- * ----------------------------------------------------------------------
- *
- * class DerivedFiber : Fiber
- * {
- * this()
- * {
- * super( &run );
- * }
- *
- * private :
- * void run()
- * {
- * printf( "Derived fiber running.\n" );
- * }
- * }
- *
- * void fiberFunc()
- * {
- * printf( "Composed fiber running.\n" );
- * Fiber.yield();
- * printf( "Composed fiber running.\n" );
- * }
- *
- * // create instances of each type
- * Fiber derived = new DerivedFiber();
- * Fiber composed = new Fiber( &fiberFunc );
- *
- * // call both fibers once
- * derived.call();
- * composed.call();
- * printf( "Execution returned to calling context.\n" );
- * composed.call();
- *
- * // since each fiber has run to completion, each should have state TERM
- * assert( derived.state == Fiber.State.TERM );
- * assert( composed.state == Fiber.State.TERM );
- *
- * ----------------------------------------------------------------------
- *
- * Authors: Based on a design by Mikola Lysenko.
- */
-class Fiber
-{
- ///////////////////////////////////////////////////////////////////////////
- // Initialization
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * Initializes a fiber object which is associated with a static
- * D function.
- *
- * Params:
- * fn = The fiber function.
- * sz = The stack size for this fiber.
- * guardPageSize = size of the guard page to trap fiber's stack
- * overflows
- *
- * In:
- * fn must not be null.
- */
- this( void function() fn, size_t sz = PAGESIZE*4,
- size_t guardPageSize = PAGESIZE ) nothrow
- in
- {
- assert( fn );
- }
- body
- {
- allocStack( sz, guardPageSize );
- reset( fn );
- }
-
-
- /**
- * Initializes a fiber object which is associated with a dynamic
- * D function.
- *
- * Params:
- * dg = The fiber function.
- * sz = The stack size for this fiber.
- * guardPageSize = size of the guard page to trap fiber's stack
- * overflows
- *
- * In:
- * dg must not be null.
- */
- this( void delegate() dg, size_t sz = PAGESIZE*4,
- size_t guardPageSize = PAGESIZE ) nothrow
- in
- {
- assert( dg );
- }
- body
- {
- allocStack( sz, guardPageSize);
- reset( dg );
- }
-
-
- /**
- * Cleans up any remaining resources used by this object.
- */
- ~this() nothrow @nogc
- {
- // NOTE: A live reference to this object will exist on its associated
- // stack from the first time its call() method has been called
- // until its execution completes with State.TERM. Thus, the only
- // times this dtor should be called are either if the fiber has
- // terminated (and therefore has no active stack) or if the user
- // explicitly deletes this object. The latter case is an error
- // but is not easily tested for, since State.HOLD may imply that
- // the fiber was just created but has never been run. There is
- // not a compelling case to create a State.INIT just to offer a
- // means of ensuring the user isn't violating this object's
- // contract, so for now this requirement will be enforced by
- // documentation only.
- freeStack();
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // General Actions
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * Transfers execution to this fiber object. The calling context will be
- * suspended until the fiber calls Fiber.yield() or until it terminates
- * via an unhandled exception.
- *
- * Params:
- * rethrow = Rethrow any unhandled exception which may have caused this
- * fiber to terminate.
- *
- * In:
- * This fiber must be in state HOLD.
- *
- * Throws:
- * Any exception not handled by the joined thread.
- *
- * Returns:
- * Any exception not handled by this fiber if rethrow = false, null
- * otherwise.
- */
- // Not marked with any attributes, even though `nothrow @nogc` works
- // because it calls arbitrary user code. Most of the implementation
- // is already `@nogc nothrow`, but in order for `Fiber.call` to
- // propagate the attributes of the user's function, the Fiber
- // class needs to be templated.
- final Throwable call( Rethrow rethrow = Rethrow.yes )
- {
- return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no);
- }
-
- /// ditto
- final Throwable call( Rethrow rethrow )()
- {
- callImpl();
- if ( m_unhandled )
- {
- Throwable t = m_unhandled;
- m_unhandled = null;
- static if ( rethrow )
- throw t;
- else
- return t;
- }
- return null;
- }
-
- /// ditto
- deprecated("Please pass Fiber.Rethrow.yes or .no instead of a boolean.")
- final Throwable call( bool rethrow )
- {
- return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no);
- }
-
- private void callImpl() nothrow @nogc
- in
- {
- assert( m_state == State.HOLD );
- }
- body
- {
- Fiber cur = getThis();
-
- static if ( __traits( compiles, ucontext_t ) )
- m_ucur = cur ? &cur.m_utxt : &Fiber.sm_utxt;
-
- setThis( this );
- this.switchIn();
- setThis( cur );
-
- static if ( __traits( compiles, ucontext_t ) )
- m_ucur = null;
-
- // NOTE: If the fiber has terminated then the stack pointers must be
- // reset. This ensures that the stack for this fiber is not
- // scanned if the fiber has terminated. This is necessary to
- // prevent any references lingering on the stack from delaying
- // the collection of otherwise dead objects. The most notable
- // being the current object, which is referenced at the top of
- // fiber_entryPoint.
- if ( m_state == State.TERM )
- {
- m_ctxt.tstack = m_ctxt.bstack;
- }
- }
-
- /// Flag to control rethrow behavior of $(D $(LREF call))
- enum Rethrow : bool { no, yes }
-
- /**
- * Resets this fiber so that it may be re-used, optionally with a
- * new function/delegate. This routine should only be called for
- * fibers that have terminated, as doing otherwise could result in
- * scope-dependent functionality that is not executed.
- * Stack-based classes, for example, may not be cleaned up
- * properly if a fiber is reset before it has terminated.
- *
- * In:
- * This fiber must be in state TERM or HOLD.
- */
- final void reset() nothrow @nogc
- in
- {
- assert( m_state == State.TERM || m_state == State.HOLD );
- }
- body
- {
- m_ctxt.tstack = m_ctxt.bstack;
- m_state = State.HOLD;
- initStack();
- m_unhandled = null;
- }
-
- /// ditto
- final void reset( void function() fn ) nothrow @nogc
- {
- reset();
- m_fn = fn;
- m_call = Call.FN;
- }
-
- /// ditto
- final void reset( void delegate() dg ) nothrow @nogc
- {
- reset();
- m_dg = dg;
- m_call = Call.DG;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // General Properties
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * A fiber may occupy one of three states: HOLD, EXEC, and TERM. The HOLD
- * state applies to any fiber that is suspended and ready to be called.
- * The EXEC state will be set for any fiber that is currently executing.
- * And the TERM state is set when a fiber terminates. Once a fiber
- * terminates, it must be reset before it may be called again.
- */
- enum State
- {
- HOLD, ///
- EXEC, ///
- TERM ///
- }
-
-
- /**
- * Gets the current state of this fiber.
- *
- * Returns:
- * The state of this fiber as an enumerated value.
- */
- final @property State state() const @safe pure nothrow @nogc
- {
- return m_state;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // Actions on Calling Fiber
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * Forces a context switch to occur away from the calling fiber.
- */
- static void yield() nothrow @nogc
- {
- Fiber cur = getThis();
- assert( cur, "Fiber.yield() called with no active fiber" );
- assert( cur.m_state == State.EXEC );
-
- static if ( __traits( compiles, ucontext_t ) )
- cur.m_ucur = &cur.m_utxt;
-
- cur.m_state = State.HOLD;
- cur.switchOut();
- cur.m_state = State.EXEC;
- }
-
-
- /**
- * Forces a context switch to occur away from the calling fiber and then
- * throws obj in the calling fiber.
- *
- * Params:
- * t = The object to throw.
- *
- * In:
- * t must not be null.
- */
- static void yieldAndThrow( Throwable t ) nothrow @nogc
- in
- {
- assert( t );
- }
- body
- {
- Fiber cur = getThis();
- assert( cur, "Fiber.yield() called with no active fiber" );
- assert( cur.m_state == State.EXEC );
-
- static if ( __traits( compiles, ucontext_t ) )
- cur.m_ucur = &cur.m_utxt;
-
- cur.m_unhandled = t;
- cur.m_state = State.HOLD;
- cur.switchOut();
- cur.m_state = State.EXEC;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // Fiber Accessors
- ///////////////////////////////////////////////////////////////////////////
-
-
- /**
- * Provides a reference to the calling fiber or null if no fiber is
- * currently active.
- *
- * Returns:
- * The fiber object representing the calling fiber or null if no fiber
- * is currently active within this thread. The result of deleting this object is undefined.
- */
- static Fiber getThis() @safe nothrow @nogc
- {
- return sm_this;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // Static Initialization
- ///////////////////////////////////////////////////////////////////////////
-
-
- version (Posix)
- {
- static this()
- {
- static if ( __traits( compiles, ucontext_t ) )
- {
- int status = getcontext( &sm_utxt );
- assert( status == 0 );
- }
- }
- }
-
-private:
- //
- // Initializes a fiber object which has no associated executable function.
- //
- this() @safe pure nothrow @nogc
- {
- m_call = Call.NO;
- }
-
-
- //
- // Fiber entry point. Invokes the function or delegate passed on
- // construction (if any).
- //
- final void run()
- {
- switch ( m_call )
- {
- case Call.FN:
- m_fn();
- break;
- case Call.DG:
- m_dg();
- break;
- default:
- break;
- }
- }
-
-
-private:
- //
- // The type of routine passed on fiber construction.
- //
- enum Call
- {
- NO,
- FN,
- DG
- }
-
-
- //
- // Standard fiber data
- //
- Call m_call;
- union
- {
- void function() m_fn;
- void delegate() m_dg;
- }
- bool m_isRunning;
- Throwable m_unhandled;
- State m_state;
-
-
-private:
- ///////////////////////////////////////////////////////////////////////////
- // Stack Management
- ///////////////////////////////////////////////////////////////////////////
-
-
- //
- // Allocate a new stack for this fiber.
- //
- final void allocStack( size_t sz, size_t guardPageSize ) nothrow
- in
- {
- assert( !m_pmem && !m_ctxt );
- }
- body
- {
- // adjust alloc size to a multiple of PAGESIZE
- sz += PAGESIZE - 1;
- sz -= sz % PAGESIZE;
-
- // NOTE: This instance of Thread.Context is dynamic so Fiber objects
- // can be collected by the GC so long as no user level references
- // to the object exist. If m_ctxt were not dynamic then its
- // presence in the global context list would be enough to keep
- // this object alive indefinitely. An alternative to allocating
- // room for this struct explicitly would be to mash it into the
- // base of the stack being allocated below. However, doing so
- // requires too much special logic to be worthwhile.
- m_ctxt = new Thread.Context;
-
- static if ( __traits( compiles, VirtualAlloc ) )
- {
- // reserve memory for stack
- m_pmem = VirtualAlloc( null,
- sz + guardPageSize,
- MEM_RESERVE,
- PAGE_NOACCESS );
- if ( !m_pmem )
- onOutOfMemoryError();
-
- version (StackGrowsDown)
- {
- void* stack = m_pmem + guardPageSize;
- void* guard = m_pmem;
- void* pbase = stack + sz;
- }
- else
- {
- void* stack = m_pmem;
- void* guard = m_pmem + sz;
- void* pbase = stack;
- }
-
- // allocate reserved stack segment
- stack = VirtualAlloc( stack,
- sz,
- MEM_COMMIT,
- PAGE_READWRITE );
- if ( !stack )
- onOutOfMemoryError();
-
- if (guardPageSize)
- {
- // allocate reserved guard page
- guard = VirtualAlloc( guard,
- guardPageSize,
- MEM_COMMIT,
- PAGE_READWRITE | PAGE_GUARD );
- if ( !guard )
- onOutOfMemoryError();
- }
-
- m_ctxt.bstack = pbase;
- m_ctxt.tstack = pbase;
- m_size = sz;
- }
- else
- {
- version (Posix) import core.sys.posix.sys.mman; // mmap
- version (FreeBSD) import core.sys.freebsd.sys.mman : MAP_ANON;
- version (NetBSD) import core.sys.netbsd.sys.mman : MAP_ANON;
- version (OpenBSD) import core.sys.openbsd.sys.mman : MAP_ANON;
- version (DragonFlyBSD) import core.sys.dragonflybsd.sys.mman : MAP_ANON;
- version (CRuntime_Glibc) import core.sys.linux.sys.mman : MAP_ANON;
- version (Darwin) import core.sys.darwin.sys.mman : MAP_ANON;
- version (CRuntime_UClibc) import core.sys.linux.sys.mman : MAP_ANON;
-
- static if ( __traits( compiles, mmap ) )
- {
- // Allocate more for the memory guard
- sz += guardPageSize;
-
- m_pmem = mmap( null,
- sz,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON,
- -1,
- 0 );
- if ( m_pmem == MAP_FAILED )
- m_pmem = null;
- }
- else static if ( __traits( compiles, valloc ) )
- {
- m_pmem = valloc( sz );
- }
- else static if ( __traits( compiles, malloc ) )
- {
- m_pmem = malloc( sz );
- }
- else
- {
- m_pmem = null;
- }
-
- if ( !m_pmem )
- onOutOfMemoryError();
-
- version (StackGrowsDown)
- {
- m_ctxt.bstack = m_pmem + sz;
- m_ctxt.tstack = m_pmem + sz;
- void* guard = m_pmem;
- }
- else
- {
- m_ctxt.bstack = m_pmem;
- m_ctxt.tstack = m_pmem;
- void* guard = m_pmem + sz - guardPageSize;
- }
- m_size = sz;
-
- static if ( __traits( compiles, mmap ) )
- {
- if (guardPageSize)
- {
- // protect end of stack
- if ( mprotect(guard, guardPageSize, PROT_NONE) == -1 )
- abort();
- }
- }
- else
- {
- // Supported only for mmap allocated memory - results are
- // undefined if applied to memory not obtained by mmap
- }
- }
-
- Thread.add( m_ctxt );
- }
-
-
- //
- // Free this fiber's stack.
- //
- final void freeStack() nothrow @nogc
- in
- {
- assert( m_pmem && m_ctxt );
- }
- body
- {
- // NOTE: m_ctxt is guaranteed to be alive because it is held in the
- // global context list.
- Thread.slock.lock_nothrow();
- scope(exit) Thread.slock.unlock_nothrow();
- Thread.remove( m_ctxt );
-
- static if ( __traits( compiles, VirtualAlloc ) )
- {
- VirtualFree( m_pmem, 0, MEM_RELEASE );
- }
- else
- {
- import core.sys.posix.sys.mman; // munmap
-
- static if ( __traits( compiles, mmap ) )
- {
- munmap( m_pmem, m_size );
- }
- else static if ( __traits( compiles, valloc ) )
- {
- free( m_pmem );
- }
- else static if ( __traits( compiles, malloc ) )
- {
- free( m_pmem );
- }
- }
- m_pmem = null;
- m_ctxt = null;
- }
-
-
- //
- // Initialize the allocated stack.
- // Look above the definition of 'class Fiber' for some information about the implementation of this routine
- //
- final void initStack() nothrow @nogc
- in
- {
- assert( m_ctxt.tstack && m_ctxt.tstack == m_ctxt.bstack );
- assert( cast(size_t) m_ctxt.bstack % (void*).sizeof == 0 );
- }
- body
- {
- void* pstack = m_ctxt.tstack;
- scope( exit ) m_ctxt.tstack = pstack;
-
- void push( size_t val ) nothrow
- {
- version (StackGrowsDown)
- {
- pstack -= size_t.sizeof;
- *(cast(size_t*) pstack) = val;
- }
- else
- {
- pstack += size_t.sizeof;
- *(cast(size_t*) pstack) = val;
- }
- }
-
- // NOTE: On OS X the stack must be 16-byte aligned according
- // to the IA-32 call spec. For x86_64 the stack also needs to
- // be aligned to 16-byte according to SysV AMD64 ABI.
- version (AlignFiberStackTo16Byte)
- {
- version (StackGrowsDown)
- {
- pstack = cast(void*)(cast(size_t)(pstack) - (cast(size_t)(pstack) & 0x0F));
- }
- else
- {
- pstack = cast(void*)(cast(size_t)(pstack) + (cast(size_t)(pstack) & 0x0F));
- }
- }
-
- version (AsmX86_Windows)
- {
- version (StackGrowsDown) {} else static assert( false );
-
- // On Windows Server 2008 and 2008 R2, an exploit mitigation
- // technique known as SEHOP is activated by default. To avoid
- // hijacking of the exception handler chain, the presence of a
- // Windows-internal handler (ntdll.dll!FinalExceptionHandler) at
- // its end is tested by RaiseException. If it is not present, all
- // handlers are disregarded, and the program is thus aborted
- // (see http://blogs.technet.com/b/srd/archive/2009/02/02/
- // preventing-the-exploitation-of-seh-overwrites-with-sehop.aspx).
- // For new threads, this handler is installed by Windows immediately
- // after creation. To make exception handling work in fibers, we
- // have to insert it for our new stacks manually as well.
- //
- // To do this, we first determine the handler by traversing the SEH
- // chain of the current thread until its end, and then construct a
- // registration block for the last handler on the newly created
- // thread. We then continue to push all the initial register values
- // for the first context switch as for the other implementations.
- //
- // Note that this handler is never actually invoked, as we install
- // our own one on top of it in the fiber entry point function.
- // Thus, it should not have any effects on OSes not implementing
- // exception chain verification.
-
- alias fp_t = void function(); // Actual signature not relevant.
- static struct EXCEPTION_REGISTRATION
- {
- EXCEPTION_REGISTRATION* next; // sehChainEnd if last one.
- fp_t handler;
- }
- enum sehChainEnd = cast(EXCEPTION_REGISTRATION*) 0xFFFFFFFF;
-
- __gshared static fp_t finalHandler = null;
- if ( finalHandler is null )
- {
- static EXCEPTION_REGISTRATION* fs0() nothrow
- {
- asm pure nothrow @nogc
- {
- naked;
- mov EAX, FS:[0];
- ret;
- }
- }
- auto reg = fs0();
- while ( reg.next != sehChainEnd ) reg = reg.next;
-
- // Benign races are okay here, just to avoid re-lookup on every
- // fiber creation.
- finalHandler = reg.handler;
- }
-
- // When linking with /safeseh (supported by LDC, but not DMD)
- // the exception chain must not extend to the very top
- // of the stack, otherwise the exception chain is also considered
- // invalid. Reserving additional 4 bytes at the top of the stack will
- // keep the EXCEPTION_REGISTRATION below that limit
- size_t reserve = EXCEPTION_REGISTRATION.sizeof + 4;
- pstack -= reserve;
- *(cast(EXCEPTION_REGISTRATION*)pstack) =
- EXCEPTION_REGISTRATION( sehChainEnd, finalHandler );
-
- push( cast(size_t) &fiber_entryPoint ); // EIP
- push( cast(size_t) m_ctxt.bstack - reserve ); // EBP
- push( 0x00000000 ); // EDI
- push( 0x00000000 ); // ESI
- push( 0x00000000 ); // EBX
- push( cast(size_t) m_ctxt.bstack - reserve ); // FS:[0]
- push( cast(size_t) m_ctxt.bstack ); // FS:[4]
- push( cast(size_t) m_ctxt.bstack - m_size ); // FS:[8]
- push( 0x00000000 ); // EAX
- }
- else version (AsmX86_64_Windows)
- {
- // Using this trampoline instead of the raw fiber_entryPoint
- // ensures that during context switches, source and destination
- // stacks have the same alignment. Otherwise, the stack would need
- // to be shifted by 8 bytes for the first call, as fiber_entryPoint
- // is an actual function expecting a stack which is not aligned
- // to 16 bytes.
- static void trampoline()
- {
- asm pure nothrow @nogc
- {
- naked;
- sub RSP, 32; // Shadow space (Win64 calling convention)
- call fiber_entryPoint;
- xor RCX, RCX; // This should never be reached, as
- jmp RCX; // fiber_entryPoint must never return.
- }
- }
-
- push( cast(size_t) &trampoline ); // RIP
- push( 0x00000000_00000000 ); // RBP
- push( 0x00000000_00000000 ); // R12
- push( 0x00000000_00000000 ); // R13
- push( 0x00000000_00000000 ); // R14
- push( 0x00000000_00000000 ); // R15
- push( 0x00000000_00000000 ); // RDI
- push( 0x00000000_00000000 ); // RSI
- push( 0x00000000_00000000 ); // XMM6 (high)
- push( 0x00000000_00000000 ); // XMM6 (low)
- push( 0x00000000_00000000 ); // XMM7 (high)
- push( 0x00000000_00000000 ); // XMM7 (low)
- push( 0x00000000_00000000 ); // XMM8 (high)
- push( 0x00000000_00000000 ); // XMM8 (low)
- push( 0x00000000_00000000 ); // XMM9 (high)
- push( 0x00000000_00000000 ); // XMM9 (low)
- push( 0x00000000_00000000 ); // XMM10 (high)
- push( 0x00000000_00000000 ); // XMM10 (low)
- push( 0x00000000_00000000 ); // XMM11 (high)
- push( 0x00000000_00000000 ); // XMM11 (low)
- push( 0x00000000_00000000 ); // XMM12 (high)
- push( 0x00000000_00000000 ); // XMM12 (low)
- push( 0x00000000_00000000 ); // XMM13 (high)
- push( 0x00000000_00000000 ); // XMM13 (low)
- push( 0x00000000_00000000 ); // XMM14 (high)
- push( 0x00000000_00000000 ); // XMM14 (low)
- push( 0x00000000_00000000 ); // XMM15 (high)
- push( 0x00000000_00000000 ); // XMM15 (low)
- push( 0x00000000_00000000 ); // RBX
- push( 0xFFFFFFFF_FFFFFFFF ); // GS:[0]
- version (StackGrowsDown)
- {
- push( cast(size_t) m_ctxt.bstack ); // GS:[8]
- push( cast(size_t) m_ctxt.bstack - m_size ); // GS:[16]
- }
- else
- {
- push( cast(size_t) m_ctxt.bstack ); // GS:[8]
- push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16]
- }
- }
- else version (AsmX86_Posix)
- {
- push( 0x00000000 ); // Return address of fiber_entryPoint call
- push( cast(size_t) &fiber_entryPoint ); // EIP
- push( cast(size_t) m_ctxt.bstack ); // EBP
- push( 0x00000000 ); // EDI
- push( 0x00000000 ); // ESI
- push( 0x00000000 ); // EBX
- push( 0x00000000 ); // EAX
- }
- else version (AsmX86_64_Posix)
- {
- push( 0x00000000_00000000 ); // Return address of fiber_entryPoint call
- push( cast(size_t) &fiber_entryPoint ); // RIP
- push( cast(size_t) m_ctxt.bstack ); // RBP
- push( 0x00000000_00000000 ); // RBX
- push( 0x00000000_00000000 ); // R12
- push( 0x00000000_00000000 ); // R13
- push( 0x00000000_00000000 ); // R14
- push( 0x00000000_00000000 ); // R15
- }
- else version (AsmPPC_Posix)
- {
- version (StackGrowsDown)
- {
- pstack -= int.sizeof * 5;
- }
- else
- {
- pstack += int.sizeof * 5;
- }
-
- push( cast(size_t) &fiber_entryPoint ); // link register
- push( 0x00000000 ); // control register
- push( 0x00000000 ); // old stack pointer
-
- // GPR values
- version (StackGrowsDown)
- {
- pstack -= int.sizeof * 20;
- }
- else
- {
- pstack += int.sizeof * 20;
- }
-
- assert( (cast(size_t) pstack & 0x0f) == 0 );
- }
- else version (AsmMIPS_O32_Posix)
- {
- version (StackGrowsDown) {}
- else static assert(0);
-
- /* We keep the FP registers and the return address below
- * the stack pointer, so they don't get scanned by the
- * GC. The last frame before swapping the stack pointer is
- * organized like the following.
- *
- * |-----------|<= frame pointer
- * | $gp |
- * | $s0-8 |
- * |-----------|<= stack pointer
- * | $ra |
- * | align(8) |
- * | $f20-30 |
- * |-----------|
- *
- */
- enum SZ_GP = 10 * size_t.sizeof; // $gp + $s0-8
- enum SZ_RA = size_t.sizeof; // $ra
- version (MIPS_HardFloat)
- {
- enum SZ_FP = 6 * 8; // $f20-30
- enum ALIGN = -(SZ_FP + SZ_RA) & (8 - 1);
- }
- else
- {
- enum SZ_FP = 0;
- enum ALIGN = 0;
- }
-
- enum BELOW = SZ_FP + ALIGN + SZ_RA;
- enum ABOVE = SZ_GP;
- enum SZ = BELOW + ABOVE;
-
- (cast(ubyte*)pstack - SZ)[0 .. SZ] = 0;
- pstack -= ABOVE;
- *cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint;
- }
- else version (AsmAArch64_Posix)
- {
- // Like others, FP registers and return address (lr) are kept
- // below the saved stack top (tstack) to hide from GC scanning.
- // fiber_switchContext expects newp sp to look like this:
- // 19: x19
- // ...
- // 9: x29 (fp) <-- newp tstack
- // 8: x30 (lr) [&fiber_entryPoint]
- // 7: d8
- // ...
- // 0: d15
-
- version (StackGrowsDown) {}
- else
- static assert(false, "Only full descending stacks supported on AArch64");
-
- // Only need to set return address (lr). Everything else is fine
- // zero initialized.
- pstack -= size_t.sizeof * 11; // skip past x19-x29
- push(cast(size_t) &fiber_trampoline); // see threadasm.S for docs
- pstack += size_t.sizeof; // adjust sp (newp) above lr
- }
- else version (AsmARM_Posix)
- {
- /* We keep the FP registers and the return address below
- * the stack pointer, so they don't get scanned by the
- * GC. The last frame before swapping the stack pointer is
- * organized like the following.
- *
- * | |-----------|<= 'frame starts here'
- * | | fp | (the actual frame pointer, r11 isn't
- * | | r10-r4 | updated and still points to the previous frame)
- * | |-----------|<= stack pointer
- * | | lr |
- * | | 4byte pad |
- * | | d15-d8 |(if FP supported)
- * | |-----------|
- * Y
- * stack grows down: The pointer value here is smaller than some lines above
- */
- // frame pointer can be zero, r10-r4 also zero initialized
- version (StackGrowsDown)
- pstack -= int.sizeof * 8;
- else
- static assert(false, "Only full descending stacks supported on ARM");
-
- // link register
- push( cast(size_t) &fiber_entryPoint );
- /*
- * We do not push padding and d15-d8 as those are zero initialized anyway
- * Position the stack pointer above the lr register
- */
- pstack += int.sizeof * 1;
- }
- else version (GNU_AsmX86_Windows)
- {
- version (StackGrowsDown) {} else static assert( false );
-
- // Currently, MinGW doesn't utilize SEH exceptions.
- // See DMD AsmX86_Windows If this code ever becomes fails and SEH is used.
-
- push( 0x00000000 ); // Return address of fiber_entryPoint call
- push( cast(size_t) &fiber_entryPoint ); // EIP
- push( 0x00000000 ); // EBP
- push( 0x00000000 ); // EDI
- push( 0x00000000 ); // ESI
- push( 0x00000000 ); // EBX
- push( 0xFFFFFFFF ); // FS:[0] - Current SEH frame
- push( cast(size_t) m_ctxt.bstack ); // FS:[4] - Top of stack
- push( cast(size_t) m_ctxt.bstack - m_size ); // FS:[8] - Bottom of stack
- push( 0x00000000 ); // EAX
- }
- else version (GNU_AsmX86_64_Windows)
- {
- push( 0x00000000_00000000 ); // Return address of fiber_entryPoint call
- push( cast(size_t) &fiber_entryPoint ); // RIP
- push( 0x00000000_00000000 ); // RBP
- push( 0x00000000_00000000 ); // RBX
- push( 0x00000000_00000000 ); // R12
- push( 0x00000000_00000000 ); // R13
- push( 0x00000000_00000000 ); // R14
- push( 0x00000000_00000000 ); // R15
- push( 0xFFFFFFFF_FFFFFFFF ); // GS:[0] - Current SEH frame
- version (StackGrowsDown)
- {
- push( cast(size_t) m_ctxt.bstack ); // GS:[8] - Top of stack
- push( cast(size_t) m_ctxt.bstack - m_size ); // GS:[16] - Bottom of stack
- }
- else
- {
- push( cast(size_t) m_ctxt.bstack ); // GS:[8] - Top of stack
- push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16] - Bottom of stack
- }
- }
- else static if ( __traits( compiles, ucontext_t ) )
- {
- getcontext( &m_utxt );
- m_utxt.uc_stack.ss_sp = m_pmem;
- m_utxt.uc_stack.ss_size = m_size;
- makecontext( &m_utxt, &fiber_entryPoint, 0 );
- // NOTE: If ucontext is being used then the top of the stack will
- // be a pointer to the ucontext_t struct for that fiber.
- push( cast(size_t) &m_utxt );
- }
- else
- static assert(0, "Not implemented");
- }
-
-
- Thread.Context* m_ctxt;
- size_t m_size;
- void* m_pmem;
-
- static if ( __traits( compiles, ucontext_t ) )
- {
- // NOTE: The static ucontext instance is used to represent the context
- // of the executing thread.
- static ucontext_t sm_utxt = void;
- ucontext_t m_utxt = void;
- ucontext_t* m_ucur = null;
- }
- else static if (GNU_Enable_CET)
- {
- // When libphobos was built with --enable-cet, these fields need to
- // always be present in the Fiber class layout.
- import core.sys.posix.ucontext;
- static ucontext_t sm_utxt = void;
- ucontext_t m_utxt = void;
- ucontext_t* m_ucur = null;
- }
-
-
-private:
- ///////////////////////////////////////////////////////////////////////////
- // Storage of Active Fiber
- ///////////////////////////////////////////////////////////////////////////
-
-
- //
- // Sets a thread-local reference to the current fiber object.
- //
- static void setThis( Fiber f ) nothrow @nogc
- {
- sm_this = f;
- }
-
- static Fiber sm_this;
-
-
-private:
- ///////////////////////////////////////////////////////////////////////////
- // Context Switching
- ///////////////////////////////////////////////////////////////////////////
-
-
- //
- // Switches into the stack held by this fiber.
- //
- final void switchIn() nothrow @nogc
- {
- Thread tobj = Thread.getThis();
- void** oldp = &tobj.m_curr.tstack;
- void* newp = m_ctxt.tstack;
-
- // NOTE: The order of operations here is very important. The current
- // stack top must be stored before m_lock is set, and pushContext
- // must not be called until after m_lock is set. This process
- // is intended to prevent a race condition with the suspend
- // mechanism used for garbage collection. If it is not followed,
- // a badly timed collection could cause the GC to scan from the
- // bottom of one stack to the top of another, or to miss scanning
- // a stack that still contains valid data. The old stack pointer
- // oldp will be set again before the context switch to guarantee
- // that it points to exactly the correct stack location so the
- // successive pop operations will succeed.
- *oldp = getStackTop();
- atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true);
- tobj.pushContext( m_ctxt );
-
- fiber_switchContext( oldp, newp );
-
- // NOTE: As above, these operations must be performed in a strict order
- // to prevent Bad Things from happening.
- tobj.popContext();
- atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false);
- tobj.m_curr.tstack = tobj.m_curr.bstack;
- }
-
-
- //
- // Switches out of the current stack and into the enclosing stack.
- //
- final void switchOut() nothrow @nogc
- {
- Thread tobj = Thread.getThis();
- void** oldp = &m_ctxt.tstack;
- void* newp = tobj.m_curr.within.tstack;
-
- // NOTE: The order of operations here is very important. The current
- // stack top must be stored before m_lock is set, and pushContext
- // must not be called until after m_lock is set. This process
- // is intended to prevent a race condition with the suspend
- // mechanism used for garbage collection. If it is not followed,
- // a badly timed collection could cause the GC to scan from the
- // bottom of one stack to the top of another, or to miss scanning
- // a stack that still contains valid data. The old stack pointer
- // oldp will be set again before the context switch to guarantee
- // that it points to exactly the correct stack location so the
- // successive pop operations will succeed.
- *oldp = getStackTop();
- atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true);
-
- fiber_switchContext( oldp, newp );
-
- // NOTE: As above, these operations must be performed in a strict order
- // to prevent Bad Things from happening.
- // NOTE: If use of this fiber is multiplexed across threads, the thread
- // executing here may be different from the one above, so get the
- // current thread handle before unlocking, etc.
- tobj = Thread.getThis();
- atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false);
- tobj.m_curr.tstack = tobj.m_curr.bstack;
- }
-}
-
-
-version (unittest)
-{
- class TestFiber : Fiber
- {
- this()
- {
- super(&run);
- }
-
- void run()
- {
- foreach (i; 0 .. 1000)
- {
- sum += i;
- Fiber.yield();
- }
- }
-
- enum expSum = 1000 * 999 / 2;
- size_t sum;
- }
-
- void runTen()
- {
- TestFiber[10] fibs;
- foreach (ref fib; fibs)
- fib = new TestFiber();
-
- bool cont;
- do {
- cont = false;
- foreach (fib; fibs) {
- if (fib.state == Fiber.State.HOLD)
- {
- fib.call();
- cont |= fib.state != Fiber.State.TERM;
- }
- }
- } while (cont);
-
- foreach (fib; fibs)
- {
- assert(fib.sum == TestFiber.expSum);
- }
- }
-}
-
-
-// Single thread running separate fibers
-unittest
-{
- runTen();
-}
-
-
-// Multiple threads running separate fibers
-unittest
-{
- auto group = new ThreadGroup();
- foreach (_; 0 .. 4)
- {
- group.create(&runTen);
- }
- group.joinAll();
-}
-
-
-// Multiple threads running shared fibers
-version (PPC) version = UnsafeFiberMigration;
-version (PPC64) version = UnsafeFiberMigration;
-
-version (UnsafeFiberMigration)
-{
- // XBUG: core.thread fibers are supposed to be safe to migrate across
- // threads, however, there is a problem: GCC always assumes that the
- // address of thread-local variables don't change while on a given stack.
- // In consequence, migrating fibers between threads currently is an unsafe
- // thing to do, and will break on some targets (possibly PR26461).
-}
-else
-{
- version = FiberMigrationUnittest;
-}
-
-version (FiberMigrationUnittest)
-unittest
-{
- shared bool[10] locks;
- TestFiber[10] fibs;
-
- void runShared()
- {
- bool cont;
- do {
- cont = false;
- foreach (idx; 0 .. 10)
- {
- if (cas(&locks[idx], false, true))
- {
- if (fibs[idx].state == Fiber.State.HOLD)
- {
- fibs[idx].call();
- cont |= fibs[idx].state != Fiber.State.TERM;
- }
- locks[idx] = false;
- }
- else
- {
- cont = true;
- }
- }
- } while (cont);
- }
-
- foreach (ref fib; fibs)
- {
- fib = new TestFiber();
- }
-
- auto group = new ThreadGroup();
- foreach (_; 0 .. 4)
- {
- group.create(&runShared);
- }
- group.joinAll();
-
- foreach (fib; fibs)
- {
- assert(fib.sum == TestFiber.expSum);
- }
-}
-
-
-// Test exception handling inside fibers.
-version (Win32) {
- // broken on win32 under windows server 2012: bug 13821
-} else unittest {
- enum MSG = "Test message.";
- string caughtMsg;
- (new Fiber({
- try
- {
- throw new Exception(MSG);
- }
- catch (Exception e)
- {
- caughtMsg = e.msg;
- }
- })).call();
- assert(caughtMsg == MSG);
-}
-
-
-unittest
-{
- int x = 0;
-
- (new Fiber({
- x++;
- })).call();
- assert( x == 1 );
-}
-
-nothrow unittest
-{
- new Fiber({}).call!(Fiber.Rethrow.no)();
-}
-
-unittest
-{
- new Fiber({}).call(Fiber.Rethrow.yes);
- new Fiber({}).call(Fiber.Rethrow.no);
-}
-
-deprecated unittest
-{
- new Fiber({}).call(true);
- new Fiber({}).call(false);
-}
-
-version (Win32) {
- // broken on win32 under windows server 2012: bug 13821
-} else unittest {
- enum MSG = "Test message.";
-
- try
- {
- (new Fiber({
- throw new Exception( MSG );
- })).call();
- assert( false, "Expected rethrown exception." );
- }
- catch ( Throwable t )
- {
- assert( t.msg == MSG );
- }
-}
-
-// Test exception chaining when switching contexts in finally blocks.
-unittest
-{
- static void throwAndYield(string msg) {
- try {
- throw new Exception(msg);
- } finally {
- Fiber.yield();
- }
- }
-
- static void fiber(string name) {
- try {
- try {
- throwAndYield(name ~ ".1");
- } finally {
- throwAndYield(name ~ ".2");
- }
- } catch (Exception e) {
- assert(e.msg == name ~ ".1");
- assert(e.next);
- assert(e.next.msg == name ~ ".2");
- assert(!e.next.next);
- }
- }
-
- auto first = new Fiber(() => fiber("first"));
- auto second = new Fiber(() => fiber("second"));
- first.call();
- second.call();
- first.call();
- second.call();
- first.call();
- second.call();
- assert(first.state == Fiber.State.TERM);
- assert(second.state == Fiber.State.TERM);
-}
-
-// Test Fiber resetting
-unittest
-{
- static string method;
-
- static void foo()
- {
- method = "foo";
- }
-
- void bar()
- {
- method = "bar";
- }
-
- static void expect(Fiber fib, string s)
- {
- assert(fib.state == Fiber.State.HOLD);
- fib.call();
- assert(fib.state == Fiber.State.TERM);
- assert(method == s); method = null;
- }
- auto fib = new Fiber(&foo);
- expect(fib, "foo");
-
- fib.reset();
- expect(fib, "foo");
-
- fib.reset(&foo);
- expect(fib, "foo");
-
- fib.reset(&bar);
- expect(fib, "bar");
-
- fib.reset(function void(){method = "function";});
- expect(fib, "function");
-
- fib.reset(delegate void(){method = "delegate";});
- expect(fib, "delegate");
-}
-
-// Test unsafe reset in hold state
-unittest
-{
- auto fib = new Fiber(function {ubyte[2048] buf = void; Fiber.yield();}, 4096);
- foreach (_; 0 .. 10)
- {
- fib.call();
- assert(fib.state == Fiber.State.HOLD);
- fib.reset();
- }
-}
-
-// stress testing GC stack scanning
-unittest
-{
- import core.memory;
-
- static void unreferencedThreadObject()
- {
- static void sleep() { Thread.sleep(dur!"msecs"(100)); }
- auto thread = new Thread(&sleep).start();
- }
- unreferencedThreadObject();
- GC.collect();
-
- static class Foo
- {
- this(int value)
- {
- _value = value;
- }
-
- int bar()
- {
- return _value;
- }
-
- int _value;
- }
-
- static void collect()
- {
- auto foo = new Foo(2);
- assert(foo.bar() == 2);
- GC.collect();
- Fiber.yield();
- GC.collect();
- assert(foo.bar() == 2);
- }
-
- auto fiber = new Fiber(&collect);
-
- fiber.call();
- GC.collect();
- fiber.call();
-
- // thread reference
- auto foo = new Foo(2);
-
- void collect2()
- {
- assert(foo.bar() == 2);
- GC.collect();
- Fiber.yield();
- GC.collect();
- assert(foo.bar() == 2);
- }
-
- fiber = new Fiber(&collect2);
-
- fiber.call();
- GC.collect();
- fiber.call();
-
- static void recurse(size_t cnt)
- {
- --cnt;
- Fiber.yield();
- if (cnt)
- {
- auto fib = new Fiber(() { recurse(cnt); });
- fib.call();
- GC.collect();
- fib.call();
- }
- }
- fiber = new Fiber(() { recurse(20); });
- fiber.call();
-}
-
-
-version (AsmX86_64_Windows)
-{
- // Test Windows x64 calling convention
- unittest
- {
- void testNonvolatileRegister(alias REG)()
- {
- auto zeroRegister = new Fiber(() {
- mixin("asm pure nothrow @nogc { naked; xor "~REG~", "~REG~"; ret; }");
- });
- long after;
-
- mixin("asm pure nothrow @nogc { mov "~REG~", 0xFFFFFFFFFFFFFFFF; }");
- zeroRegister.call();
- mixin("asm pure nothrow @nogc { mov after, "~REG~"; }");
-
- assert(after == -1);
- }
-
- void testNonvolatileRegisterSSE(alias REG)()
- {
- auto zeroRegister = new Fiber(() {
- mixin("asm pure nothrow @nogc { naked; xorpd "~REG~", "~REG~"; ret; }");
- });
- long[2] before = [0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF], after;
-
- mixin("asm pure nothrow @nogc { movdqu "~REG~", before; }");
- zeroRegister.call();
- mixin("asm pure nothrow @nogc { movdqu after, "~REG~"; }");
-
- assert(before == after);
- }
-
- testNonvolatileRegister!("R12")();
- testNonvolatileRegister!("R13")();
- testNonvolatileRegister!("R14")();
- testNonvolatileRegister!("R15")();
- testNonvolatileRegister!("RDI")();
- testNonvolatileRegister!("RSI")();
- testNonvolatileRegister!("RBX")();
-
- testNonvolatileRegisterSSE!("XMM6")();
- testNonvolatileRegisterSSE!("XMM7")();
- testNonvolatileRegisterSSE!("XMM8")();
- testNonvolatileRegisterSSE!("XMM9")();
- testNonvolatileRegisterSSE!("XMM10")();
- testNonvolatileRegisterSSE!("XMM11")();
- testNonvolatileRegisterSSE!("XMM12")();
- testNonvolatileRegisterSSE!("XMM13")();
- testNonvolatileRegisterSSE!("XMM14")();
- testNonvolatileRegisterSSE!("XMM15")();
- }
-}
-
-
-version (D_InlineAsm_X86_64)
-{
- unittest
- {
- void testStackAlignment()
- {
- void* pRSP;
- asm pure nothrow @nogc
- {
- mov pRSP, RSP;
- }
- assert((cast(size_t)pRSP & 0xF) == 0);
- }
-
- auto fib = new Fiber(&testStackAlignment);
- fib.call();
- }
-}
-
-// regression test for Issue 13416
-version (FreeBSD) unittest
-{
- static void loop()
- {
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- auto thr = pthread_self();
- foreach (i; 0 .. 50)
- pthread_attr_get_np(thr, &attr);
- pthread_attr_destroy(&attr);
- }
-
- auto thr = new Thread(&loop).start();
- foreach (i; 0 .. 50)
- {
- thread_suspendAll();
- thread_resumeAll();
- }
- thr.join();
-}
-
-version (DragonFlyBSD) unittest
-{
- static void loop()
- {
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- auto thr = pthread_self();
- foreach (i; 0 .. 50)
- pthread_attr_get_np(thr, &attr);
- pthread_attr_destroy(&attr);
- }
-
- auto thr = new Thread(&loop).start();
- foreach (i; 0 .. 50)
- {
- thread_suspendAll();
- thread_resumeAll();
- }
- thr.join();
-}
-
-unittest
-{
- // use >PAGESIZE to avoid stack overflow (e.g. in an syscall)
- auto thr = new Thread(function{}, 4096 + 1).start();
- thr.join();
-}
-
-/**
- * Represents the ID of a thread, as returned by $(D Thread.)$(LREF id).
- * The exact type varies from platform to platform.
- */
-version (Windows)
- alias ThreadID = uint;
-else
-version (Posix)
- alias ThreadID = pthread_t;
diff --git a/libphobos/libdruntime/core/thread/context.d b/libphobos/libdruntime/core/thread/context.d
new file mode 100644
index 0000000..1b3c0ca
--- /dev/null
+++ b/libphobos/libdruntime/core/thread/context.d
@@ -0,0 +1,65 @@
+/**
+ * The thread module provides support for thread creation and management.
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2012.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
+ * Source: $(DRUNTIMESRC core/thread/package.d)
+ */
+
+module core.thread.context;
+
+struct StackContext
+{
+ void* bstack, tstack;
+
+ /// Slot for the EH implementation to keep some state for each stack
+ /// (will be necessary for exception chaining, etc.). Opaque as far as
+ /// we are concerned here.
+ void* ehContext;
+ StackContext* within;
+ StackContext* next, prev;
+}
+
+struct Callable
+{
+ void opAssign(void function() fn) pure nothrow @nogc @safe
+ {
+ () @trusted { m_fn = fn; }();
+ m_type = Call.FN;
+ }
+ void opAssign(void delegate() dg) pure nothrow @nogc @safe
+ {
+ () @trusted { m_dg = dg; }();
+ m_type = Call.DG;
+ }
+ void opCall()
+ {
+ switch (m_type)
+ {
+ case Call.FN:
+ m_fn();
+ break;
+ case Call.DG:
+ m_dg();
+ break;
+ default:
+ break;
+ }
+ }
+private:
+ enum Call
+ {
+ NO,
+ FN,
+ DG
+ }
+ Call m_type = Call.NO;
+ union
+ {
+ void function() m_fn;
+ void delegate() m_dg;
+ }
+}
diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d
new file mode 100644
index 0000000..f4c04ce
--- /dev/null
+++ b/libphobos/libdruntime/core/thread/fiber.d
@@ -0,0 +1,2141 @@
+/**
+ * The fiber module provides OS-indepedent lightweight threads aka fibers.
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2012.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
+ * Source: $(DRUNTIMESRC core/thread/fiber.d)
+ */
+
+/* NOTE: This file has been patched from the original DMD distribution to
+ * work with the GDC compiler.
+ */
+module core.thread.fiber;
+
+import core.thread.osthread;
+import core.thread.threadgroup;
+import core.thread.types;
+import core.thread.context;
+
+///////////////////////////////////////////////////////////////////////////////
+// Fiber Platform Detection
+///////////////////////////////////////////////////////////////////////////////
+
+version (GNU)
+{
+ import gcc.builtins;
+ import gcc.config;
+ version (GNU_StackGrowsDown)
+ version = StackGrowsDown;
+}
+else
+{
+ // this should be true for most architectures
+ version = StackGrowsDown;
+}
+
+version (Windows)
+{
+ import core.stdc.stdlib : malloc, free;
+ import core.sys.windows.winbase;
+ import core.sys.windows.winnt;
+}
+
+private
+{
+ version (D_InlineAsm_X86)
+ {
+ version (Windows)
+ version = AsmX86_Windows;
+ else version (Posix)
+ version = AsmX86_Posix;
+
+ version = AlignFiberStackTo16Byte;
+ }
+ else version (D_InlineAsm_X86_64)
+ {
+ version (Windows)
+ {
+ version = AsmX86_64_Windows;
+ version = AlignFiberStackTo16Byte;
+ }
+ else version (Posix)
+ {
+ version = AsmX86_64_Posix;
+ version = AlignFiberStackTo16Byte;
+ }
+ }
+ else version (X86)
+ {
+ version = AlignFiberStackTo16Byte;
+
+ version (CET)
+ {
+ // fiber_switchContext does not support shadow stack from
+ // Intel CET. So use ucontext implementation.
+ }
+ else
+ {
+ version = AsmExternal;
+
+ version (MinGW)
+ version = GNU_AsmX86_Windows;
+ else version (OSX)
+ version = AsmX86_Posix;
+ else version (Posix)
+ version = AsmX86_Posix;
+ }
+ }
+ else version (X86_64)
+ {
+ version = AlignFiberStackTo16Byte;
+
+ version (CET)
+ {
+ // fiber_switchContext does not support shadow stack from
+ // Intel CET. So use ucontext implementation.
+ }
+ else version (D_X32)
+ {
+ // let X32 be handled by ucontext swapcontext
+ }
+ else
+ {
+ version = AsmExternal;
+
+ version (MinGW)
+ version = GNU_AsmX86_64_Windows;
+ else version (OSX)
+ version = AsmX86_64_Posix;
+ else version (Posix)
+ version = AsmX86_64_Posix;
+ }
+ }
+ else version (PPC)
+ {
+ version (OSX)
+ {
+ version = AsmPPC_Darwin;
+ version = AsmExternal;
+ version = AlignFiberStackTo16Byte;
+ }
+ else version (Posix)
+ {
+ version = AsmPPC_Posix;
+ version = AsmExternal;
+ }
+ }
+ else version (PPC64)
+ {
+ version (OSX)
+ {
+ version = AsmPPC_Darwin;
+ version = AsmExternal;
+ version = AlignFiberStackTo16Byte;
+ }
+ else version (Posix)
+ {
+ version = AlignFiberStackTo16Byte;
+ }
+ }
+ else version (MIPS_O32)
+ {
+ version (Posix)
+ {
+ version = AsmMIPS_O32_Posix;
+ version = AsmExternal;
+ }
+ }
+ else version (AArch64)
+ {
+ version (Posix)
+ {
+ version = AsmAArch64_Posix;
+ version = AsmExternal;
+ version = AlignFiberStackTo16Byte;
+ }
+ }
+ else version (ARM)
+ {
+ version (Posix)
+ {
+ version = AsmARM_Posix;
+ version = AsmExternal;
+ }
+ }
+ else version (SPARC)
+ {
+ // NOTE: The SPARC ABI specifies only doubleword alignment.
+ version = AlignFiberStackTo16Byte;
+ }
+ else version (SPARC64)
+ {
+ version = AlignFiberStackTo16Byte;
+ }
+
+ version (Posix)
+ {
+ version (AsmX86_Windows) {} else
+ version (AsmX86_Posix) {} else
+ version (AsmX86_64_Windows) {} else
+ version (AsmX86_64_Posix) {} else
+ version (AsmExternal) {} else
+ {
+ // NOTE: The ucontext implementation requires architecture specific
+ // data definitions to operate so testing for it must be done
+ // by checking for the existence of ucontext_t rather than by
+ // a version identifier. Please note that this is considered
+ // an obsolescent feature according to the POSIX spec, so a
+ // custom solution is still preferred.
+ import core.sys.posix.ucontext;
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Fiber Entry Point and Context Switch
+///////////////////////////////////////////////////////////////////////////////
+
+private
+{
+ import core.atomic : atomicStore, cas, MemoryOrder;
+ import core.exception : onOutOfMemoryError;
+ import core.stdc.stdlib : abort;
+
+ extern (C) void fiber_entryPoint() nothrow
+ {
+ Fiber obj = Fiber.getThis();
+ assert( obj );
+
+ assert( Thread.getThis().m_curr is obj.m_ctxt );
+ atomicStore!(MemoryOrder.raw)(*cast(shared)&Thread.getThis().m_lock, false);
+ obj.m_ctxt.tstack = obj.m_ctxt.bstack;
+ obj.m_state = Fiber.State.EXEC;
+
+ try
+ {
+ obj.run();
+ }
+ catch ( Throwable t )
+ {
+ obj.m_unhandled = t;
+ }
+
+ static if ( __traits( compiles, ucontext_t ) )
+ obj.m_ucur = &obj.m_utxt;
+
+ obj.m_state = Fiber.State.TERM;
+ obj.switchOut();
+ }
+
+ // Look above the definition of 'class Fiber' for some information about the implementation of this routine
+ version (AsmExternal)
+ {
+ extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc;
+ version (AArch64)
+ extern (C) void fiber_trampoline() nothrow;
+ }
+ else
+ extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc
+ {
+ // NOTE: The data pushed and popped in this routine must match the
+ // default stack created by Fiber.initStack or the initial
+ // switch into a new context will fail.
+
+ version (AsmX86_Windows)
+ {
+ asm pure nothrow @nogc
+ {
+ naked;
+
+ // save current stack state
+ push EBP;
+ mov EBP, ESP;
+ push EDI;
+ push ESI;
+ push EBX;
+ push dword ptr FS:[0];
+ push dword ptr FS:[4];
+ push dword ptr FS:[8];
+ push EAX;
+
+ // store oldp again with more accurate address
+ mov EAX, dword ptr 8[EBP];
+ mov [EAX], ESP;
+ // load newp to begin context switch
+ mov ESP, dword ptr 12[EBP];
+
+ // load saved state from new stack
+ pop EAX;
+ pop dword ptr FS:[8];
+ pop dword ptr FS:[4];
+ pop dword ptr FS:[0];
+ pop EBX;
+ pop ESI;
+ pop EDI;
+ pop EBP;
+
+ // 'return' to complete switch
+ pop ECX;
+ jmp ECX;
+ }
+ }
+ else version (AsmX86_64_Windows)
+ {
+ asm pure nothrow @nogc
+ {
+ naked;
+
+ // save current stack state
+ // NOTE: When changing the layout of registers on the stack,
+ // make sure that the XMM registers are still aligned.
+ // On function entry, the stack is guaranteed to not
+ // be aligned to 16 bytes because of the return address
+ // on the stack.
+ push RBP;
+ mov RBP, RSP;
+ push R12;
+ push R13;
+ push R14;
+ push R15;
+ push RDI;
+ push RSI;
+ // 7 registers = 56 bytes; stack is now aligned to 16 bytes
+ sub RSP, 160;
+ movdqa [RSP + 144], XMM6;
+ movdqa [RSP + 128], XMM7;
+ movdqa [RSP + 112], XMM8;
+ movdqa [RSP + 96], XMM9;
+ movdqa [RSP + 80], XMM10;
+ movdqa [RSP + 64], XMM11;
+ movdqa [RSP + 48], XMM12;
+ movdqa [RSP + 32], XMM13;
+ movdqa [RSP + 16], XMM14;
+ movdqa [RSP], XMM15;
+ push RBX;
+ xor RAX,RAX;
+ push qword ptr GS:[RAX];
+ push qword ptr GS:8[RAX];
+ push qword ptr GS:16[RAX];
+
+ // store oldp
+ mov [RCX], RSP;
+ // load newp to begin context switch
+ mov RSP, RDX;
+
+ // load saved state from new stack
+ pop qword ptr GS:16[RAX];
+ pop qword ptr GS:8[RAX];
+ pop qword ptr GS:[RAX];
+ pop RBX;
+ movdqa XMM15, [RSP];
+ movdqa XMM14, [RSP + 16];
+ movdqa XMM13, [RSP + 32];
+ movdqa XMM12, [RSP + 48];
+ movdqa XMM11, [RSP + 64];
+ movdqa XMM10, [RSP + 80];
+ movdqa XMM9, [RSP + 96];
+ movdqa XMM8, [RSP + 112];
+ movdqa XMM7, [RSP + 128];
+ movdqa XMM6, [RSP + 144];
+ add RSP, 160;
+ pop RSI;
+ pop RDI;
+ pop R15;
+ pop R14;
+ pop R13;
+ pop R12;
+ pop RBP;
+
+ // 'return' to complete switch
+ pop RCX;
+ jmp RCX;
+ }
+ }
+ else version (AsmX86_Posix)
+ {
+ asm pure nothrow @nogc
+ {
+ naked;
+
+ // save current stack state
+ push EBP;
+ mov EBP, ESP;
+ push EDI;
+ push ESI;
+ push EBX;
+ push EAX;
+
+ // store oldp again with more accurate address
+ mov EAX, dword ptr 8[EBP];
+ mov [EAX], ESP;
+ // load newp to begin context switch
+ mov ESP, dword ptr 12[EBP];
+
+ // load saved state from new stack
+ pop EAX;
+ pop EBX;
+ pop ESI;
+ pop EDI;
+ pop EBP;
+
+ // 'return' to complete switch
+ pop ECX;
+ jmp ECX;
+ }
+ }
+ else version (AsmX86_64_Posix)
+ {
+ asm pure nothrow @nogc
+ {
+ naked;
+
+ // save current stack state
+ push RBP;
+ mov RBP, RSP;
+ push RBX;
+ push R12;
+ push R13;
+ push R14;
+ push R15;
+
+ // store oldp
+ mov [RDI], RSP;
+ // load newp to begin context switch
+ mov RSP, RSI;
+
+ // load saved state from new stack
+ pop R15;
+ pop R14;
+ pop R13;
+ pop R12;
+ pop RBX;
+ pop RBP;
+
+ // 'return' to complete switch
+ pop RCX;
+ jmp RCX;
+ }
+ }
+ else static if ( __traits( compiles, ucontext_t ) )
+ {
+ Fiber cfib = Fiber.getThis();
+ void* ucur = cfib.m_ucur;
+
+ *oldp = &ucur;
+ swapcontext( **(cast(ucontext_t***) oldp),
+ *(cast(ucontext_t**) newp) );
+ }
+ else
+ static assert(0, "Not implemented");
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Fiber
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Documentation of Fiber internals:
+ *
+ * The main routines to implement when porting Fibers to new architectures are
+ * fiber_switchContext and initStack. Some version constants have to be defined
+ * for the new platform as well, search for "Fiber Platform Detection and Memory Allocation".
+ *
+ * Fibers are based on a concept called 'Context'. A Context describes the execution
+ * state of a Fiber or main thread which is fully described by the stack, some
+ * registers and a return address at which the Fiber/Thread should continue executing.
+ * Please note that not only each Fiber has a Context, but each thread also has got a
+ * Context which describes the threads stack and state. If you call Fiber fib; fib.call
+ * the first time in a thread you switch from Threads Context into the Fibers Context.
+ * If you call fib.yield in that Fiber you switch out of the Fibers context and back
+ * into the Thread Context. (However, this is not always the case. You can call a Fiber
+ * from within another Fiber, then you switch Contexts between the Fibers and the Thread
+ * Context is not involved)
+ *
+ * In all current implementations the registers and the return address are actually
+ * saved on a Contexts stack.
+ *
+ * The fiber_switchContext routine has got two parameters:
+ * void** a: This is the _location_ where we have to store the current stack pointer,
+ * the stack pointer of the currently executing Context (Fiber or Thread).
+ * void* b: This is the pointer to the stack of the Context which we want to switch into.
+ * Note that we get the same pointer here as the one we stored into the void** a
+ * in a previous call to fiber_switchContext.
+ *
+ * In the simplest case, a fiber_switchContext rountine looks like this:
+ * fiber_switchContext:
+ * push {return Address}
+ * push {registers}
+ * copy {stack pointer} into {location pointed to by a}
+ * //We have now switch to the stack of a different Context!
+ * copy {b} into {stack pointer}
+ * pop {registers}
+ * pop {return Address}
+ * jump to {return Address}
+ *
+ * The GC uses the value returned in parameter a to scan the Fibers stack. It scans from
+ * the stack base to that value. As the GC dislikes false pointers we can actually optimize
+ * this a little: By storing registers which can not contain references to memory managed
+ * by the GC outside of the region marked by the stack base pointer and the stack pointer
+ * saved in fiber_switchContext we can prevent the GC from scanning them.
+ * Such registers are usually floating point registers and the return address. In order to
+ * implement this, we return a modified stack pointer from fiber_switchContext. However,
+ * we have to remember that when we restore the registers from the stack!
+ *
+ * --------------------------- <= Stack Base
+ * | Frame | <= Many other stack frames
+ * | Frame |
+ * |-------------------------| <= The last stack frame. This one is created by fiber_switchContext
+ * | registers with pointers |
+ * | | <= Stack pointer. GC stops scanning here
+ * | return address |
+ * |floating point registers |
+ * --------------------------- <= Real Stack End
+ *
+ * fiber_switchContext:
+ * push {registers with pointers}
+ * copy {stack pointer} into {location pointed to by a}
+ * push {return Address}
+ * push {Floating point registers}
+ * //We have now switch to the stack of a different Context!
+ * copy {b} into {stack pointer}
+ * //We now have to adjust the stack pointer to point to 'Real Stack End' so we can pop
+ * //the FP registers
+ * //+ or - depends on if your stack grows downwards or upwards
+ * {stack pointer} = {stack pointer} +- ({FPRegisters}.sizeof + {return address}.sizeof}
+ * pop {Floating point registers}
+ * pop {return Address}
+ * pop {registers with pointers}
+ * jump to {return Address}
+ *
+ * So the question now is which registers need to be saved? This depends on the specific
+ * architecture ABI of course, but here are some general guidelines:
+ * - If a register is callee-save (if the callee modifies the register it must saved and
+ * restored by the callee) it needs to be saved/restored in switchContext
+ * - If a register is caller-save it needn't be saved/restored. (Calling fiber_switchContext
+ * is a function call and the compiler therefore already must save these registers before
+ * calling fiber_switchContext)
+ * - Argument registers used for passing parameters to functions needn't be saved/restored
+ * - The return register needn't be saved/restored (fiber_switchContext hasn't got a return type)
+ * - All scratch registers needn't be saved/restored
+ * - The link register usually needn't be saved/restored (but sometimes it must be cleared -
+ * see below for details)
+ * - The frame pointer register - if it exists - is usually callee-save
+ * - All current implementations do not save control registers
+ *
+ * What happens on the first switch into a Fiber? We never saved a state for this fiber before,
+ * but the initial state is prepared in the initStack routine. (This routine will also be called
+ * when a Fiber is being resetted). initStack must produce exactly the same stack layout as the
+ * part of fiber_switchContext which saves the registers. Pay special attention to set the stack
+ * pointer correctly if you use the GC optimization mentioned before. the return Address saved in
+ * initStack must be the address of fiber_entrypoint.
+ *
+ * There's now a small but important difference between the first context switch into a fiber and
+ * further context switches. On the first switch, Fiber.call is used and the returnAddress in
+ * fiber_switchContext will point to fiber_entrypoint. The important thing here is that this jump
+ * is a _function call_, we call fiber_entrypoint by jumping before it's function prologue. On later
+ * calls, the user used yield() in a function, and therefore the return address points into a user
+ * function, after the yield call. So here the jump in fiber_switchContext is a _function return_,
+ * not a function call!
+ *
+ * The most important result of this is that on entering a function, i.e. fiber_entrypoint, we
+ * would have to provide a return address / set the link register once fiber_entrypoint
+ * returns. Now fiber_entrypoint does never return and therefore the actual value of the return
+ * address / link register is never read/used and therefore doesn't matter. When fiber_switchContext
+ * performs a _function return_ the value in the link register doesn't matter either.
+ * However, the link register will still be saved to the stack in fiber_entrypoint and some
+ * exception handling / stack unwinding code might read it from this stack location and crash.
+ * The exact solution depends on your architecture, but see the ARM implementation for a way
+ * to deal with this issue.
+ *
+ * The ARM implementation is meant to be used as a kind of documented example implementation.
+ * Look there for a concrete example.
+ *
+ * FIXME: fiber_entrypoint might benefit from a @noreturn attribute, but D doesn't have one.
+ */
+
+/**
+ * This class provides a cooperative concurrency mechanism integrated with the
+ * threading and garbage collection functionality. Calling a fiber may be
+ * considered a blocking operation that returns when the fiber yields (via
+ * Fiber.yield()). Execution occurs within the context of the calling thread
+ * so synchronization is not necessary to guarantee memory visibility so long
+ * as the same thread calls the fiber each time. Please note that there is no
+ * requirement that a fiber be bound to one specific thread. Rather, fibers
+ * may be freely passed between threads so long as they are not currently
+ * executing. Like threads, a new fiber thread may be created using either
+ * derivation or composition, as in the following example.
+ *
+ * Warning:
+ * Status registers are not saved by the current implementations. This means
+ * floating point exception status bits (overflow, divide by 0), rounding mode
+ * and similar stuff is set per-thread, not per Fiber!
+ *
+ * Warning:
+ * On ARM FPU registers are not saved if druntime was compiled as ARM_SoftFloat.
+ * If such a build is used on a ARM_SoftFP system which actually has got a FPU
+ * and other libraries are using the FPU registers (other code is compiled
+ * as ARM_SoftFP) this can cause problems. Druntime must be compiled as
+ * ARM_SoftFP in this case.
+ *
+ * Authors: Based on a design by Mikola Lysenko.
+ */
+class Fiber
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Initialization
+ ///////////////////////////////////////////////////////////////////////////
+
+ version (Windows)
+ // exception handling walks the stack, invoking DbgHelp.dll which
+ // needs up to 16k of stack space depending on the version of DbgHelp.dll,
+ // the existence of debug symbols and other conditions. Avoid causing
+ // stack overflows by defaulting to a larger stack size
+ enum defaultStackPages = 8;
+ else
+ enum defaultStackPages = 4;
+
+ /**
+ * Initializes a fiber object which is associated with a static
+ * D function.
+ *
+ * Params:
+ * fn = The fiber function.
+ * sz = The stack size for this fiber.
+ * guardPageSize = size of the guard page to trap fiber's stack
+ * overflows. Beware that using this will increase
+ * the number of mmaped regions on platforms using mmap
+ * so an OS-imposed limit may be hit.
+ *
+ * In:
+ * fn must not be null.
+ */
+ this( void function() fn, size_t sz = PAGESIZE * defaultStackPages,
+ size_t guardPageSize = PAGESIZE ) nothrow
+ in
+ {
+ assert( fn );
+ }
+ do
+ {
+ allocStack( sz, guardPageSize );
+ reset( fn );
+ }
+
+
+ /**
+ * Initializes a fiber object which is associated with a dynamic
+ * D function.
+ *
+ * Params:
+ * dg = The fiber function.
+ * sz = The stack size for this fiber.
+ * guardPageSize = size of the guard page to trap fiber's stack
+ * overflows. Beware that using this will increase
+ * the number of mmaped regions on platforms using mmap
+ * so an OS-imposed limit may be hit.
+ *
+ * In:
+ * dg must not be null.
+ */
+ this( void delegate() dg, size_t sz = PAGESIZE * defaultStackPages,
+ size_t guardPageSize = PAGESIZE ) nothrow
+ in
+ {
+ assert( dg );
+ }
+ do
+ {
+ allocStack( sz, guardPageSize );
+ reset( dg );
+ }
+
+
+ /**
+ * Cleans up any remaining resources used by this object.
+ */
+ ~this() nothrow @nogc
+ {
+ // NOTE: A live reference to this object will exist on its associated
+ // stack from the first time its call() method has been called
+ // until its execution completes with State.TERM. Thus, the only
+ // times this dtor should be called are either if the fiber has
+ // terminated (and therefore has no active stack) or if the user
+ // explicitly deletes this object. The latter case is an error
+ // but is not easily tested for, since State.HOLD may imply that
+ // the fiber was just created but has never been run. There is
+ // not a compelling case to create a State.INIT just to offer a
+ // means of ensuring the user isn't violating this object's
+ // contract, so for now this requirement will be enforced by
+ // documentation only.
+ freeStack();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // General Actions
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Transfers execution to this fiber object. The calling context will be
+ * suspended until the fiber calls Fiber.yield() or until it terminates
+ * via an unhandled exception.
+ *
+ * Params:
+ * rethrow = Rethrow any unhandled exception which may have caused this
+ * fiber to terminate.
+ *
+ * In:
+ * This fiber must be in state HOLD.
+ *
+ * Throws:
+ * Any exception not handled by the joined thread.
+ *
+ * Returns:
+ * Any exception not handled by this fiber if rethrow = false, null
+ * otherwise.
+ */
+ // Not marked with any attributes, even though `nothrow @nogc` works
+ // because it calls arbitrary user code. Most of the implementation
+ // is already `@nogc nothrow`, but in order for `Fiber.call` to
+ // propagate the attributes of the user's function, the Fiber
+ // class needs to be templated.
+ final Throwable call( Rethrow rethrow = Rethrow.yes )
+ {
+ return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no);
+ }
+
+ /// ditto
+ final Throwable call( Rethrow rethrow )()
+ {
+ callImpl();
+ if ( m_unhandled )
+ {
+ Throwable t = m_unhandled;
+ m_unhandled = null;
+ static if ( rethrow )
+ throw t;
+ else
+ return t;
+ }
+ return null;
+ }
+
+ private void callImpl() nothrow @nogc
+ in
+ {
+ assert( m_state == State.HOLD );
+ }
+ do
+ {
+ Fiber cur = getThis();
+
+ static if ( __traits( compiles, ucontext_t ) )
+ m_ucur = cur ? &cur.m_utxt : &Fiber.sm_utxt;
+
+ setThis( this );
+ this.switchIn();
+ setThis( cur );
+
+ static if ( __traits( compiles, ucontext_t ) )
+ m_ucur = null;
+
+ // NOTE: If the fiber has terminated then the stack pointers must be
+ // reset. This ensures that the stack for this fiber is not
+ // scanned if the fiber has terminated. This is necessary to
+ // prevent any references lingering on the stack from delaying
+ // the collection of otherwise dead objects. The most notable
+ // being the current object, which is referenced at the top of
+ // fiber_entryPoint.
+ if ( m_state == State.TERM )
+ {
+ m_ctxt.tstack = m_ctxt.bstack;
+ }
+ }
+
+ /// Flag to control rethrow behavior of $(D $(LREF call))
+ enum Rethrow : bool { no, yes }
+
+ /**
+ * Resets this fiber so that it may be re-used, optionally with a
+ * new function/delegate. This routine should only be called for
+ * fibers that have terminated, as doing otherwise could result in
+ * scope-dependent functionality that is not executed.
+ * Stack-based classes, for example, may not be cleaned up
+ * properly if a fiber is reset before it has terminated.
+ *
+ * In:
+ * This fiber must be in state TERM or HOLD.
+ */
+ final void reset() nothrow @nogc
+ in
+ {
+ assert( m_state == State.TERM || m_state == State.HOLD );
+ }
+ do
+ {
+ m_ctxt.tstack = m_ctxt.bstack;
+ m_state = State.HOLD;
+ initStack();
+ m_unhandled = null;
+ }
+
+ /// ditto
+ final void reset( void function() fn ) nothrow @nogc
+ {
+ reset();
+ m_call = fn;
+ }
+
+ /// ditto
+ final void reset( void delegate() dg ) nothrow @nogc
+ {
+ reset();
+ m_call = dg;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // General Properties
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /// A fiber may occupy one of three states: HOLD, EXEC, and TERM.
+ enum State
+ {
+ /** The HOLD state applies to any fiber that is suspended and ready to
+ be called. */
+ HOLD,
+ /** The EXEC state will be set for any fiber that is currently
+ executing. */
+ EXEC,
+ /** The TERM state is set when a fiber terminates. Once a fiber
+ terminates, it must be reset before it may be called again. */
+ TERM
+ }
+
+
+ /**
+ * Gets the current state of this fiber.
+ *
+ * Returns:
+ * The state of this fiber as an enumerated value.
+ */
+ final @property State state() const @safe pure nothrow @nogc
+ {
+ return m_state;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Actions on Calling Fiber
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Forces a context switch to occur away from the calling fiber.
+ */
+ static void yield() nothrow @nogc
+ {
+ Fiber cur = getThis();
+ assert( cur, "Fiber.yield() called with no active fiber" );
+ assert( cur.m_state == State.EXEC );
+
+ static if ( __traits( compiles, ucontext_t ) )
+ cur.m_ucur = &cur.m_utxt;
+
+ cur.m_state = State.HOLD;
+ cur.switchOut();
+ cur.m_state = State.EXEC;
+ }
+
+
+ /**
+ * Forces a context switch to occur away from the calling fiber and then
+ * throws obj in the calling fiber.
+ *
+ * Params:
+ * t = The object to throw.
+ *
+ * In:
+ * t must not be null.
+ */
+ static void yieldAndThrow( Throwable t ) nothrow @nogc
+ in
+ {
+ assert( t );
+ }
+ do
+ {
+ Fiber cur = getThis();
+ assert( cur, "Fiber.yield() called with no active fiber" );
+ assert( cur.m_state == State.EXEC );
+
+ static if ( __traits( compiles, ucontext_t ) )
+ cur.m_ucur = &cur.m_utxt;
+
+ cur.m_unhandled = t;
+ cur.m_state = State.HOLD;
+ cur.switchOut();
+ cur.m_state = State.EXEC;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Fiber Accessors
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Provides a reference to the calling fiber or null if no fiber is
+ * currently active.
+ *
+ * Returns:
+ * The fiber object representing the calling fiber or null if no fiber
+ * is currently active within this thread. The result of deleting this object is undefined.
+ */
+ static Fiber getThis() @safe nothrow @nogc
+ {
+ version (GNU) pragma(inline, false);
+ return sm_this;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Static Initialization
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ version (Posix)
+ {
+ static this()
+ {
+ static if ( __traits( compiles, ucontext_t ) )
+ {
+ int status = getcontext( &sm_utxt );
+ assert( status == 0 );
+ }
+ }
+ }
+
+private:
+
+ //
+ // Fiber entry point. Invokes the function or delegate passed on
+ // construction (if any).
+ //
+ final void run()
+ {
+ m_call();
+ }
+
+ //
+ // Standard fiber data
+ //
+ Callable m_call;
+ bool m_isRunning;
+ Throwable m_unhandled;
+ State m_state;
+
+
+private:
+ ///////////////////////////////////////////////////////////////////////////
+ // Stack Management
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ //
+ // Allocate a new stack for this fiber.
+ //
+ final void allocStack( size_t sz, size_t guardPageSize ) nothrow
+ in
+ {
+ assert( !m_pmem && !m_ctxt );
+ }
+ do
+ {
+ // adjust alloc size to a multiple of PAGESIZE
+ sz += PAGESIZE - 1;
+ sz -= sz % PAGESIZE;
+
+ // NOTE: This instance of Thread.Context is dynamic so Fiber objects
+ // can be collected by the GC so long as no user level references
+ // to the object exist. If m_ctxt were not dynamic then its
+ // presence in the global context list would be enough to keep
+ // this object alive indefinitely. An alternative to allocating
+ // room for this struct explicitly would be to mash it into the
+ // base of the stack being allocated below. However, doing so
+ // requires too much special logic to be worthwhile.
+ m_ctxt = new StackContext;
+
+ version (Windows)
+ {
+ // reserve memory for stack
+ m_pmem = VirtualAlloc( null,
+ sz + guardPageSize,
+ MEM_RESERVE,
+ PAGE_NOACCESS );
+ if ( !m_pmem )
+ onOutOfMemoryError();
+
+ version (StackGrowsDown)
+ {
+ void* stack = m_pmem + guardPageSize;
+ void* guard = m_pmem;
+ void* pbase = stack + sz;
+ }
+ else
+ {
+ void* stack = m_pmem;
+ void* guard = m_pmem + sz;
+ void* pbase = stack;
+ }
+
+ // allocate reserved stack segment
+ stack = VirtualAlloc( stack,
+ sz,
+ MEM_COMMIT,
+ PAGE_READWRITE );
+ if ( !stack )
+ onOutOfMemoryError();
+
+ if (guardPageSize)
+ {
+ // allocate reserved guard page
+ guard = VirtualAlloc( guard,
+ guardPageSize,
+ MEM_COMMIT,
+ PAGE_READWRITE | PAGE_GUARD );
+ if ( !guard )
+ onOutOfMemoryError();
+ }
+
+ m_ctxt.bstack = pbase;
+ m_ctxt.tstack = pbase;
+ m_size = sz;
+ }
+ else
+ {
+ version (Posix) import core.sys.posix.sys.mman; // mmap, MAP_ANON
+
+ static if ( __traits( compiles, ucontext_t ) )
+ {
+ // Stack size must be at least the minimum allowable by the OS.
+ if (sz < MINSIGSTKSZ)
+ sz = MINSIGSTKSZ;
+ }
+
+ static if ( __traits( compiles, mmap ) )
+ {
+ // Allocate more for the memory guard
+ sz += guardPageSize;
+
+ m_pmem = mmap( null,
+ sz,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON,
+ -1,
+ 0 );
+ if ( m_pmem == MAP_FAILED )
+ m_pmem = null;
+ }
+ else static if ( __traits( compiles, valloc ) )
+ {
+ m_pmem = valloc( sz );
+ }
+ else static if ( __traits( compiles, malloc ) )
+ {
+ m_pmem = malloc( sz );
+ }
+ else
+ {
+ m_pmem = null;
+ }
+
+ if ( !m_pmem )
+ onOutOfMemoryError();
+
+ version (StackGrowsDown)
+ {
+ m_ctxt.bstack = m_pmem + sz;
+ m_ctxt.tstack = m_pmem + sz;
+ void* guard = m_pmem;
+ }
+ else
+ {
+ m_ctxt.bstack = m_pmem;
+ m_ctxt.tstack = m_pmem;
+ void* guard = m_pmem + sz - guardPageSize;
+ }
+ m_size = sz;
+
+ static if ( __traits( compiles, mmap ) )
+ {
+ if (guardPageSize)
+ {
+ // protect end of stack
+ if ( mprotect(guard, guardPageSize, PROT_NONE) == -1 )
+ abort();
+ }
+ }
+ else
+ {
+ // Supported only for mmap allocated memory - results are
+ // undefined if applied to memory not obtained by mmap
+ }
+ }
+
+ Thread.add( m_ctxt );
+ }
+
+
+ //
+ // Free this fiber's stack.
+ //
+ final void freeStack() nothrow @nogc
+ in
+ {
+ assert( m_pmem && m_ctxt );
+ }
+ do
+ {
+ // NOTE: m_ctxt is guaranteed to be alive because it is held in the
+ // global context list.
+ Thread.slock.lock_nothrow();
+ scope(exit) Thread.slock.unlock_nothrow();
+ Thread.remove( m_ctxt );
+
+ version (Windows)
+ {
+ VirtualFree( m_pmem, 0, MEM_RELEASE );
+ }
+ else
+ {
+ import core.sys.posix.sys.mman; // munmap
+
+ static if ( __traits( compiles, mmap ) )
+ {
+ munmap( m_pmem, m_size );
+ }
+ else static if ( __traits( compiles, valloc ) )
+ {
+ free( m_pmem );
+ }
+ else static if ( __traits( compiles, malloc ) )
+ {
+ free( m_pmem );
+ }
+ }
+ m_pmem = null;
+ m_ctxt = null;
+ }
+
+
+ //
+ // Initialize the allocated stack.
+ // Look above the definition of 'class Fiber' for some information about the implementation of this routine
+ //
+ final void initStack() nothrow @nogc
+ in
+ {
+ assert( m_ctxt.tstack && m_ctxt.tstack == m_ctxt.bstack );
+ assert( cast(size_t) m_ctxt.bstack % (void*).sizeof == 0 );
+ }
+ do
+ {
+ void* pstack = m_ctxt.tstack;
+ scope( exit ) m_ctxt.tstack = pstack;
+
+ void push( size_t val ) nothrow
+ {
+ version (StackGrowsDown)
+ {
+ pstack -= size_t.sizeof;
+ *(cast(size_t*) pstack) = val;
+ }
+ else
+ {
+ pstack += size_t.sizeof;
+ *(cast(size_t*) pstack) = val;
+ }
+ }
+
+ // NOTE: On OS X the stack must be 16-byte aligned according
+ // to the IA-32 call spec. For x86_64 the stack also needs to
+ // be aligned to 16-byte according to SysV AMD64 ABI.
+ version (AlignFiberStackTo16Byte)
+ {
+ version (StackGrowsDown)
+ {
+ pstack = cast(void*)(cast(size_t)(pstack) - (cast(size_t)(pstack) & 0x0F));
+ }
+ else
+ {
+ pstack = cast(void*)(cast(size_t)(pstack) + (cast(size_t)(pstack) & 0x0F));
+ }
+ }
+
+ version (AsmX86_Windows)
+ {
+ version (StackGrowsDown) {} else static assert( false );
+
+ // On Windows Server 2008 and 2008 R2, an exploit mitigation
+ // technique known as SEHOP is activated by default. To avoid
+ // hijacking of the exception handler chain, the presence of a
+ // Windows-internal handler (ntdll.dll!FinalExceptionHandler) at
+ // its end is tested by RaiseException. If it is not present, all
+ // handlers are disregarded, and the program is thus aborted
+ // (see http://blogs.technet.com/b/srd/archive/2009/02/02/
+ // preventing-the-exploitation-of-seh-overwrites-with-sehop.aspx).
+ // For new threads, this handler is installed by Windows immediately
+ // after creation. To make exception handling work in fibers, we
+ // have to insert it for our new stacks manually as well.
+ //
+ // To do this, we first determine the handler by traversing the SEH
+ // chain of the current thread until its end, and then construct a
+ // registration block for the last handler on the newly created
+ // thread. We then continue to push all the initial register values
+ // for the first context switch as for the other implementations.
+ //
+ // Note that this handler is never actually invoked, as we install
+ // our own one on top of it in the fiber entry point function.
+ // Thus, it should not have any effects on OSes not implementing
+ // exception chain verification.
+
+ alias fp_t = void function(); // Actual signature not relevant.
+ static struct EXCEPTION_REGISTRATION
+ {
+ EXCEPTION_REGISTRATION* next; // sehChainEnd if last one.
+ fp_t handler;
+ }
+ enum sehChainEnd = cast(EXCEPTION_REGISTRATION*) 0xFFFFFFFF;
+
+ __gshared static fp_t finalHandler = null;
+ if ( finalHandler is null )
+ {
+ static EXCEPTION_REGISTRATION* fs0() nothrow
+ {
+ asm pure nothrow @nogc
+ {
+ naked;
+ mov EAX, FS:[0];
+ ret;
+ }
+ }
+ auto reg = fs0();
+ while ( reg.next != sehChainEnd ) reg = reg.next;
+
+ // Benign races are okay here, just to avoid re-lookup on every
+ // fiber creation.
+ finalHandler = reg.handler;
+ }
+
+ // When linking with /safeseh (supported by LDC, but not DMD)
+ // the exception chain must not extend to the very top
+ // of the stack, otherwise the exception chain is also considered
+ // invalid. Reserving additional 4 bytes at the top of the stack will
+ // keep the EXCEPTION_REGISTRATION below that limit
+ size_t reserve = EXCEPTION_REGISTRATION.sizeof + 4;
+ pstack -= reserve;
+ *(cast(EXCEPTION_REGISTRATION*)pstack) =
+ EXCEPTION_REGISTRATION( sehChainEnd, finalHandler );
+ auto pChainEnd = pstack;
+
+ push( cast(size_t) &fiber_entryPoint ); // EIP
+ push( cast(size_t) m_ctxt.bstack - reserve ); // EBP
+ push( 0x00000000 ); // EDI
+ push( 0x00000000 ); // ESI
+ push( 0x00000000 ); // EBX
+ push( cast(size_t) pChainEnd ); // FS:[0]
+ push( cast(size_t) m_ctxt.bstack ); // FS:[4]
+ push( cast(size_t) m_ctxt.bstack - m_size ); // FS:[8]
+ push( 0x00000000 ); // EAX
+ }
+ else version (AsmX86_64_Windows)
+ {
+ // Using this trampoline instead of the raw fiber_entryPoint
+ // ensures that during context switches, source and destination
+ // stacks have the same alignment. Otherwise, the stack would need
+ // to be shifted by 8 bytes for the first call, as fiber_entryPoint
+ // is an actual function expecting a stack which is not aligned
+ // to 16 bytes.
+ static void trampoline()
+ {
+ asm pure nothrow @nogc
+ {
+ naked;
+ sub RSP, 32; // Shadow space (Win64 calling convention)
+ call fiber_entryPoint;
+ xor RCX, RCX; // This should never be reached, as
+ jmp RCX; // fiber_entryPoint must never return.
+ }
+ }
+
+ push( cast(size_t) &trampoline ); // RIP
+ push( 0x00000000_00000000 ); // RBP
+ push( 0x00000000_00000000 ); // R12
+ push( 0x00000000_00000000 ); // R13
+ push( 0x00000000_00000000 ); // R14
+ push( 0x00000000_00000000 ); // R15
+ push( 0x00000000_00000000 ); // RDI
+ push( 0x00000000_00000000 ); // RSI
+ push( 0x00000000_00000000 ); // XMM6 (high)
+ push( 0x00000000_00000000 ); // XMM6 (low)
+ push( 0x00000000_00000000 ); // XMM7 (high)
+ push( 0x00000000_00000000 ); // XMM7 (low)
+ push( 0x00000000_00000000 ); // XMM8 (high)
+ push( 0x00000000_00000000 ); // XMM8 (low)
+ push( 0x00000000_00000000 ); // XMM9 (high)
+ push( 0x00000000_00000000 ); // XMM9 (low)
+ push( 0x00000000_00000000 ); // XMM10 (high)
+ push( 0x00000000_00000000 ); // XMM10 (low)
+ push( 0x00000000_00000000 ); // XMM11 (high)
+ push( 0x00000000_00000000 ); // XMM11 (low)
+ push( 0x00000000_00000000 ); // XMM12 (high)
+ push( 0x00000000_00000000 ); // XMM12 (low)
+ push( 0x00000000_00000000 ); // XMM13 (high)
+ push( 0x00000000_00000000 ); // XMM13 (low)
+ push( 0x00000000_00000000 ); // XMM14 (high)
+ push( 0x00000000_00000000 ); // XMM14 (low)
+ push( 0x00000000_00000000 ); // XMM15 (high)
+ push( 0x00000000_00000000 ); // XMM15 (low)
+ push( 0x00000000_00000000 ); // RBX
+ push( 0xFFFFFFFF_FFFFFFFF ); // GS:[0]
+ version (StackGrowsDown)
+ {
+ push( cast(size_t) m_ctxt.bstack ); // GS:[8]
+ push( cast(size_t) m_ctxt.bstack - m_size ); // GS:[16]
+ }
+ else
+ {
+ push( cast(size_t) m_ctxt.bstack ); // GS:[8]
+ push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16]
+ }
+ }
+ else version (AsmX86_Posix)
+ {
+ push( 0x00000000 ); // Return address of fiber_entryPoint call
+ push( cast(size_t) &fiber_entryPoint ); // EIP
+ push( cast(size_t) m_ctxt.bstack ); // EBP
+ push( 0x00000000 ); // EDI
+ push( 0x00000000 ); // ESI
+ push( 0x00000000 ); // EBX
+ push( 0x00000000 ); // EAX
+ }
+ else version (AsmX86_64_Posix)
+ {
+ push( 0x00000000_00000000 ); // Return address of fiber_entryPoint call
+ push( cast(size_t) &fiber_entryPoint ); // RIP
+ push( cast(size_t) m_ctxt.bstack ); // RBP
+ push( 0x00000000_00000000 ); // RBX
+ push( 0x00000000_00000000 ); // R12
+ push( 0x00000000_00000000 ); // R13
+ push( 0x00000000_00000000 ); // R14
+ push( 0x00000000_00000000 ); // R15
+ }
+ else version (AsmPPC_Posix)
+ {
+ version (StackGrowsDown)
+ {
+ pstack -= int.sizeof * 5;
+ }
+ else
+ {
+ pstack += int.sizeof * 5;
+ }
+
+ push( cast(size_t) &fiber_entryPoint ); // link register
+ push( 0x00000000 ); // control register
+ push( 0x00000000 ); // old stack pointer
+
+ // GPR values
+ version (StackGrowsDown)
+ {
+ pstack -= int.sizeof * 20;
+ }
+ else
+ {
+ pstack += int.sizeof * 20;
+ }
+
+ assert( (cast(size_t) pstack & 0x0f) == 0 );
+ }
+ else version (AsmPPC_Darwin)
+ {
+ version (StackGrowsDown) {}
+ else static assert(false, "PowerPC Darwin only supports decrementing stacks");
+
+ uint wsize = size_t.sizeof;
+
+ // linkage + regs + FPRs + VRs
+ uint space = 8 * wsize + 20 * wsize + 18 * 8 + 12 * 16;
+ (cast(ubyte*)pstack - space)[0 .. space] = 0;
+
+ pstack -= wsize * 6;
+ *cast(size_t*)pstack = cast(size_t) &fiber_entryPoint; // LR
+ pstack -= wsize * 22;
+
+ // On Darwin PPC64 pthread self is in R13 (which is reserved).
+ // At present, it is not safe to migrate fibers between threads, but if that
+ // changes, then updating the value of R13 will also need to be handled.
+ version (PPC64)
+ *cast(size_t*)(pstack + wsize) = cast(size_t) Thread.getThis().m_addr;
+ assert( (cast(size_t) pstack & 0x0f) == 0 );
+ }
+ else version (AsmMIPS_O32_Posix)
+ {
+ version (StackGrowsDown) {}
+ else static assert(0);
+
+ /* We keep the FP registers and the return address below
+ * the stack pointer, so they don't get scanned by the
+ * GC. The last frame before swapping the stack pointer is
+ * organized like the following.
+ *
+ * |-----------|<= frame pointer
+ * | $gp |
+ * | $s0-8 |
+ * |-----------|<= stack pointer
+ * | $ra |
+ * | align(8) |
+ * | $f20-30 |
+ * |-----------|
+ *
+ */
+ enum SZ_GP = 10 * size_t.sizeof; // $gp + $s0-8
+ enum SZ_RA = size_t.sizeof; // $ra
+ version (MIPS_HardFloat)
+ {
+ enum SZ_FP = 6 * 8; // $f20-30
+ enum ALIGN = -(SZ_FP + SZ_RA) & (8 - 1);
+ }
+ else
+ {
+ enum SZ_FP = 0;
+ enum ALIGN = 0;
+ }
+
+ enum BELOW = SZ_FP + ALIGN + SZ_RA;
+ enum ABOVE = SZ_GP;
+ enum SZ = BELOW + ABOVE;
+
+ (cast(ubyte*)pstack - SZ)[0 .. SZ] = 0;
+ pstack -= ABOVE;
+ *cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint;
+ }
+ else version (AsmAArch64_Posix)
+ {
+ // Like others, FP registers and return address (lr) are kept
+ // below the saved stack top (tstack) to hide from GC scanning.
+ // fiber_switchContext expects newp sp to look like this:
+ // 19: x19
+ // ...
+ // 9: x29 (fp) <-- newp tstack
+ // 8: x30 (lr) [&fiber_entryPoint]
+ // 7: d8
+ // ...
+ // 0: d15
+
+ version (StackGrowsDown) {}
+ else
+ static assert(false, "Only full descending stacks supported on AArch64");
+
+ // Only need to set return address (lr). Everything else is fine
+ // zero initialized.
+ pstack -= size_t.sizeof * 11; // skip past x19-x29
+ push(cast(size_t) &fiber_trampoline); // see threadasm.S for docs
+ pstack += size_t.sizeof; // adjust sp (newp) above lr
+ }
+ else version (AsmARM_Posix)
+ {
+ /* We keep the FP registers and the return address below
+ * the stack pointer, so they don't get scanned by the
+ * GC. The last frame before swapping the stack pointer is
+ * organized like the following.
+ *
+ * | |-----------|<= 'frame starts here'
+ * | | fp | (the actual frame pointer, r11 isn't
+ * | | r10-r4 | updated and still points to the previous frame)
+ * | |-----------|<= stack pointer
+ * | | lr |
+ * | | 4byte pad |
+ * | | d15-d8 |(if FP supported)
+ * | |-----------|
+ * Y
+ * stack grows down: The pointer value here is smaller than some lines above
+ */
+ // frame pointer can be zero, r10-r4 also zero initialized
+ version (StackGrowsDown)
+ pstack -= int.sizeof * 8;
+ else
+ static assert(false, "Only full descending stacks supported on ARM");
+
+ // link register
+ push( cast(size_t) &fiber_entryPoint );
+ /*
+ * We do not push padding and d15-d8 as those are zero initialized anyway
+ * Position the stack pointer above the lr register
+ */
+ pstack += int.sizeof * 1;
+ }
+ else version (GNU_AsmX86_Windows)
+ {
+ version (StackGrowsDown) {} else static assert( false );
+
+ // Currently, MinGW doesn't utilize SEH exceptions.
+ // See DMD AsmX86_Windows If this code ever becomes fails and SEH is used.
+
+ push( 0x00000000 ); // Return address of fiber_entryPoint call
+ push( cast(size_t) &fiber_entryPoint ); // EIP
+ push( 0x00000000 ); // EBP
+ push( 0x00000000 ); // EDI
+ push( 0x00000000 ); // ESI
+ push( 0x00000000 ); // EBX
+ push( 0xFFFFFFFF ); // FS:[0] - Current SEH frame
+ push( cast(size_t) m_ctxt.bstack ); // FS:[4] - Top of stack
+ push( cast(size_t) m_ctxt.bstack - m_size ); // FS:[8] - Bottom of stack
+ push( 0x00000000 ); // EAX
+ }
+ else version (GNU_AsmX86_64_Windows)
+ {
+ push( 0x00000000_00000000 ); // Return address of fiber_entryPoint call
+ push( cast(size_t) &fiber_entryPoint ); // RIP
+ push( 0x00000000_00000000 ); // RBP
+ push( 0x00000000_00000000 ); // RBX
+ push( 0x00000000_00000000 ); // R12
+ push( 0x00000000_00000000 ); // R13
+ push( 0x00000000_00000000 ); // R14
+ push( 0x00000000_00000000 ); // R15
+ push( 0xFFFFFFFF_FFFFFFFF ); // GS:[0] - Current SEH frame
+ version (StackGrowsDown)
+ {
+ push( cast(size_t) m_ctxt.bstack ); // GS:[8] - Top of stack
+ push( cast(size_t) m_ctxt.bstack - m_size ); // GS:[16] - Bottom of stack
+ }
+ else
+ {
+ push( cast(size_t) m_ctxt.bstack ); // GS:[8] - Top of stack
+ push( cast(size_t) m_ctxt.bstack + m_size ); // GS:[16] - Bottom of stack
+ }
+ }
+ else static if ( __traits( compiles, ucontext_t ) )
+ {
+ getcontext( &m_utxt );
+ m_utxt.uc_stack.ss_sp = m_pmem;
+ m_utxt.uc_stack.ss_size = m_size;
+ makecontext( &m_utxt, &fiber_entryPoint, 0 );
+ // NOTE: If ucontext is being used then the top of the stack will
+ // be a pointer to the ucontext_t struct for that fiber.
+ push( cast(size_t) &m_utxt );
+ }
+ else
+ static assert(0, "Not implemented");
+ }
+
+
+ StackContext* m_ctxt;
+ size_t m_size;
+ void* m_pmem;
+
+ static if ( __traits( compiles, ucontext_t ) )
+ {
+ // NOTE: The static ucontext instance is used to represent the context
+ // of the executing thread.
+ static ucontext_t sm_utxt = void;
+ ucontext_t m_utxt = void;
+ ucontext_t* m_ucur = null;
+ }
+ else static if (GNU_Enable_CET)
+ {
+ // When libphobos was built with --enable-cet, these fields need to
+ // always be present in the Fiber class layout.
+ import core.sys.posix.ucontext;
+ static ucontext_t sm_utxt = void;
+ ucontext_t m_utxt = void;
+ ucontext_t* m_ucur = null;
+ }
+
+
+private:
+ ///////////////////////////////////////////////////////////////////////////
+ // Storage of Active Fiber
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ //
+ // Sets a thread-local reference to the current fiber object.
+ //
+ static void setThis( Fiber f ) nothrow @nogc
+ {
+ sm_this = f;
+ }
+
+ static Fiber sm_this;
+
+
+private:
+ ///////////////////////////////////////////////////////////////////////////
+ // Context Switching
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ //
+ // Switches into the stack held by this fiber.
+ //
+ final void switchIn() nothrow @nogc
+ {
+ Thread tobj = Thread.getThis();
+ void** oldp = &tobj.m_curr.tstack;
+ void* newp = m_ctxt.tstack;
+
+ // NOTE: The order of operations here is very important. The current
+ // stack top must be stored before m_lock is set, and pushContext
+ // must not be called until after m_lock is set. This process
+ // is intended to prevent a race condition with the suspend
+ // mechanism used for garbage collection. If it is not followed,
+ // a badly timed collection could cause the GC to scan from the
+ // bottom of one stack to the top of another, or to miss scanning
+ // a stack that still contains valid data. The old stack pointer
+ // oldp will be set again before the context switch to guarantee
+ // that it points to exactly the correct stack location so the
+ // successive pop operations will succeed.
+ *oldp = getStackTop();
+ atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true);
+ tobj.pushContext( m_ctxt );
+
+ fiber_switchContext( oldp, newp );
+
+ // NOTE: As above, these operations must be performed in a strict order
+ // to prevent Bad Things from happening.
+ tobj.popContext();
+ atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false);
+ tobj.m_curr.tstack = tobj.m_curr.bstack;
+ }
+
+
+ //
+ // Switches out of the current stack and into the enclosing stack.
+ //
+ final void switchOut() nothrow @nogc
+ {
+ Thread tobj = Thread.getThis();
+ void** oldp = &m_ctxt.tstack;
+ void* newp = tobj.m_curr.within.tstack;
+
+ // NOTE: The order of operations here is very important. The current
+ // stack top must be stored before m_lock is set, and pushContext
+ // must not be called until after m_lock is set. This process
+ // is intended to prevent a race condition with the suspend
+ // mechanism used for garbage collection. If it is not followed,
+ // a badly timed collection could cause the GC to scan from the
+ // bottom of one stack to the top of another, or to miss scanning
+ // a stack that still contains valid data. The old stack pointer
+ // oldp will be set again before the context switch to guarantee
+ // that it points to exactly the correct stack location so the
+ // successive pop operations will succeed.
+ *oldp = getStackTop();
+ atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true);
+
+ fiber_switchContext( oldp, newp );
+
+ // NOTE: As above, these operations must be performed in a strict order
+ // to prevent Bad Things from happening.
+ // NOTE: If use of this fiber is multiplexed across threads, the thread
+ // executing here may be different from the one above, so get the
+ // current thread handle before unlocking, etc.
+ tobj = Thread.getThis();
+ atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false);
+ tobj.m_curr.tstack = tobj.m_curr.bstack;
+ }
+}
+
+///
+unittest {
+ int counter;
+
+ class DerivedFiber : Fiber
+ {
+ this()
+ {
+ super( &run );
+ }
+
+ private :
+ void run()
+ {
+ counter += 2;
+ }
+ }
+
+ void fiberFunc()
+ {
+ counter += 4;
+ Fiber.yield();
+ counter += 8;
+ }
+
+ // create instances of each type
+ Fiber derived = new DerivedFiber();
+ Fiber composed = new Fiber( &fiberFunc );
+
+ assert( counter == 0 );
+
+ derived.call();
+ assert( counter == 2, "Derived fiber increment." );
+
+ composed.call();
+ assert( counter == 6, "First composed fiber increment." );
+
+ counter += 16;
+ assert( counter == 22, "Calling context increment." );
+
+ composed.call();
+ assert( counter == 30, "Second composed fiber increment." );
+
+ // since each fiber has run to completion, each should have state TERM
+ assert( derived.state == Fiber.State.TERM );
+ assert( composed.state == Fiber.State.TERM );
+}
+
+version (unittest)
+{
+ class TestFiber : Fiber
+ {
+ this()
+ {
+ super(&run);
+ }
+
+ void run()
+ {
+ foreach (i; 0 .. 1000)
+ {
+ sum += i;
+ Fiber.yield();
+ }
+ }
+
+ enum expSum = 1000 * 999 / 2;
+ size_t sum;
+ }
+
+ void runTen()
+ {
+ TestFiber[10] fibs;
+ foreach (ref fib; fibs)
+ fib = new TestFiber();
+
+ bool cont;
+ do {
+ cont = false;
+ foreach (fib; fibs) {
+ if (fib.state == Fiber.State.HOLD)
+ {
+ fib.call();
+ cont |= fib.state != Fiber.State.TERM;
+ }
+ }
+ } while (cont);
+
+ foreach (fib; fibs)
+ {
+ assert(fib.sum == TestFiber.expSum);
+ }
+ }
+}
+
+
+// Single thread running separate fibers
+unittest
+{
+ runTen();
+}
+
+
+// Multiple threads running separate fibers
+unittest
+{
+ auto group = new ThreadGroup();
+ foreach (_; 0 .. 4)
+ {
+ group.create(&runTen);
+ }
+ group.joinAll();
+}
+
+
+// Multiple threads running shared fibers
+version (PPC) version = UnsafeFiberMigration;
+version (PPC64) version = UnsafeFiberMigration;
+version (OSX)
+{
+ version (X86) version = UnsafeFiberMigration;
+ version (X86_64) version = UnsafeFiberMigration;
+}
+
+version (UnsafeFiberMigration)
+{
+ // XBUG: core.thread fibers are supposed to be safe to migrate across
+ // threads, however, there is a problem: GCC always assumes that the
+ // address of thread-local variables don't change while on a given stack.
+ // In consequence, migrating fibers between threads currently is an unsafe
+ // thing to do, and will break on some targets (possibly PR26461).
+}
+else
+{
+ version = FiberMigrationUnittest;
+}
+
+version (FiberMigrationUnittest)
+unittest
+{
+ shared bool[10] locks;
+ TestFiber[10] fibs;
+
+ void runShared()
+ {
+ bool cont;
+ do {
+ cont = false;
+ foreach (idx; 0 .. 10)
+ {
+ if (cas(&locks[idx], false, true))
+ {
+ if (fibs[idx].state == Fiber.State.HOLD)
+ {
+ fibs[idx].call();
+ cont |= fibs[idx].state != Fiber.State.TERM;
+ }
+ locks[idx] = false;
+ }
+ else
+ {
+ cont = true;
+ }
+ }
+ } while (cont);
+ }
+
+ foreach (ref fib; fibs)
+ {
+ fib = new TestFiber();
+ }
+
+ auto group = new ThreadGroup();
+ foreach (_; 0 .. 4)
+ {
+ group.create(&runShared);
+ }
+ group.joinAll();
+
+ foreach (fib; fibs)
+ {
+ assert(fib.sum == TestFiber.expSum);
+ }
+}
+
+
+// Test exception handling inside fibers.
+unittest
+{
+ enum MSG = "Test message.";
+ string caughtMsg;
+ (new Fiber({
+ try
+ {
+ throw new Exception(MSG);
+ }
+ catch (Exception e)
+ {
+ caughtMsg = e.msg;
+ }
+ })).call();
+ assert(caughtMsg == MSG);
+}
+
+
+unittest
+{
+ int x = 0;
+
+ (new Fiber({
+ x++;
+ })).call();
+ assert( x == 1 );
+}
+
+nothrow unittest
+{
+ new Fiber({}).call!(Fiber.Rethrow.no)();
+}
+
+unittest
+{
+ new Fiber({}).call(Fiber.Rethrow.yes);
+ new Fiber({}).call(Fiber.Rethrow.no);
+}
+
+unittest
+{
+ enum MSG = "Test message.";
+
+ try
+ {
+ (new Fiber({
+ throw new Exception( MSG );
+ })).call();
+ assert( false, "Expected rethrown exception." );
+ }
+ catch ( Throwable t )
+ {
+ assert( t.msg == MSG );
+ }
+}
+
+// Test exception chaining when switching contexts in finally blocks.
+unittest
+{
+ static void throwAndYield(string msg) {
+ try {
+ throw new Exception(msg);
+ } finally {
+ Fiber.yield();
+ }
+ }
+
+ static void fiber(string name) {
+ try {
+ try {
+ throwAndYield(name ~ ".1");
+ } finally {
+ throwAndYield(name ~ ".2");
+ }
+ } catch (Exception e) {
+ assert(e.msg == name ~ ".1");
+ assert(e.next);
+ assert(e.next.msg == name ~ ".2");
+ assert(!e.next.next);
+ }
+ }
+
+ auto first = new Fiber(() => fiber("first"));
+ auto second = new Fiber(() => fiber("second"));
+ first.call();
+ second.call();
+ first.call();
+ second.call();
+ first.call();
+ second.call();
+ assert(first.state == Fiber.State.TERM);
+ assert(second.state == Fiber.State.TERM);
+}
+
+// Test Fiber resetting
+unittest
+{
+ static string method;
+
+ static void foo()
+ {
+ method = "foo";
+ }
+
+ void bar()
+ {
+ method = "bar";
+ }
+
+ static void expect(Fiber fib, string s)
+ {
+ assert(fib.state == Fiber.State.HOLD);
+ fib.call();
+ assert(fib.state == Fiber.State.TERM);
+ assert(method == s); method = null;
+ }
+ auto fib = new Fiber(&foo);
+ expect(fib, "foo");
+
+ fib.reset();
+ expect(fib, "foo");
+
+ fib.reset(&foo);
+ expect(fib, "foo");
+
+ fib.reset(&bar);
+ expect(fib, "bar");
+
+ fib.reset(function void(){method = "function";});
+ expect(fib, "function");
+
+ fib.reset(delegate void(){method = "delegate";});
+ expect(fib, "delegate");
+}
+
+// Test unsafe reset in hold state
+unittest
+{
+ auto fib = new Fiber(function {ubyte[2048] buf = void; Fiber.yield();}, 4096);
+ foreach (_; 0 .. 10)
+ {
+ fib.call();
+ assert(fib.state == Fiber.State.HOLD);
+ fib.reset();
+ }
+}
+
+// stress testing GC stack scanning
+unittest
+{
+ import core.memory;
+ import core.time : dur;
+
+ static void unreferencedThreadObject()
+ {
+ static void sleep() { Thread.sleep(dur!"msecs"(100)); }
+ auto thread = new Thread(&sleep).start();
+ }
+ unreferencedThreadObject();
+ GC.collect();
+
+ static class Foo
+ {
+ this(int value)
+ {
+ _value = value;
+ }
+
+ int bar()
+ {
+ return _value;
+ }
+
+ int _value;
+ }
+
+ static void collect()
+ {
+ auto foo = new Foo(2);
+ assert(foo.bar() == 2);
+ GC.collect();
+ Fiber.yield();
+ GC.collect();
+ assert(foo.bar() == 2);
+ }
+
+ auto fiber = new Fiber(&collect);
+
+ fiber.call();
+ GC.collect();
+ fiber.call();
+
+ // thread reference
+ auto foo = new Foo(2);
+
+ void collect2()
+ {
+ assert(foo.bar() == 2);
+ GC.collect();
+ Fiber.yield();
+ GC.collect();
+ assert(foo.bar() == 2);
+ }
+
+ fiber = new Fiber(&collect2);
+
+ fiber.call();
+ GC.collect();
+ fiber.call();
+
+ static void recurse(size_t cnt)
+ {
+ --cnt;
+ Fiber.yield();
+ if (cnt)
+ {
+ auto fib = new Fiber(() { recurse(cnt); });
+ fib.call();
+ GC.collect();
+ fib.call();
+ }
+ }
+ fiber = new Fiber(() { recurse(20); });
+ fiber.call();
+}
+
+
+version (AsmX86_64_Windows)
+{
+ // Test Windows x64 calling convention
+ unittest
+ {
+ void testNonvolatileRegister(alias REG)()
+ {
+ auto zeroRegister = new Fiber(() {
+ mixin("asm pure nothrow @nogc { naked; xor "~REG~", "~REG~"; ret; }");
+ });
+ long after;
+
+ mixin("asm pure nothrow @nogc { mov "~REG~", 0xFFFFFFFFFFFFFFFF; }");
+ zeroRegister.call();
+ mixin("asm pure nothrow @nogc { mov after, "~REG~"; }");
+
+ assert(after == -1);
+ }
+
+ void testNonvolatileRegisterSSE(alias REG)()
+ {
+ auto zeroRegister = new Fiber(() {
+ mixin("asm pure nothrow @nogc { naked; xorpd "~REG~", "~REG~"; ret; }");
+ });
+ long[2] before = [0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF], after;
+
+ mixin("asm pure nothrow @nogc { movdqu "~REG~", before; }");
+ zeroRegister.call();
+ mixin("asm pure nothrow @nogc { movdqu after, "~REG~"; }");
+
+ assert(before == after);
+ }
+
+ testNonvolatileRegister!("R12")();
+ testNonvolatileRegister!("R13")();
+ testNonvolatileRegister!("R14")();
+ testNonvolatileRegister!("R15")();
+ testNonvolatileRegister!("RDI")();
+ testNonvolatileRegister!("RSI")();
+ testNonvolatileRegister!("RBX")();
+
+ testNonvolatileRegisterSSE!("XMM6")();
+ testNonvolatileRegisterSSE!("XMM7")();
+ testNonvolatileRegisterSSE!("XMM8")();
+ testNonvolatileRegisterSSE!("XMM9")();
+ testNonvolatileRegisterSSE!("XMM10")();
+ testNonvolatileRegisterSSE!("XMM11")();
+ testNonvolatileRegisterSSE!("XMM12")();
+ testNonvolatileRegisterSSE!("XMM13")();
+ testNonvolatileRegisterSSE!("XMM14")();
+ testNonvolatileRegisterSSE!("XMM15")();
+ }
+}
+
+
+version (D_InlineAsm_X86_64)
+{
+ unittest
+ {
+ void testStackAlignment()
+ {
+ void* pRSP;
+ asm pure nothrow @nogc
+ {
+ mov pRSP, RSP;
+ }
+ assert((cast(size_t)pRSP & 0xF) == 0);
+ }
+
+ auto fib = new Fiber(&testStackAlignment);
+ fib.call();
+ }
+}
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
new file mode 100644
index 0000000..9fcd30e
--- /dev/null
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -0,0 +1,2907 @@
+/**
+ * The osthread module provides low-level, OS-dependent code
+ * for thread creation and management.
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2012.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
+ * Source: $(DRUNTIMESRC core/thread/osthread.d)
+ */
+
+/* NOTE: This file has been patched from the original DMD distribution to
+ * work with the GDC compiler.
+ */
+module core.thread.osthread;
+
+import core.thread.threadbase;
+import core.thread.context;
+import core.thread.types;
+import core.atomic;
+import core.memory : GC;
+import core.time;
+import core.exception : onOutOfMemoryError;
+import core.internal.traits : externDFunc;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Platform Detection and Memory Allocation
+///////////////////////////////////////////////////////////////////////////////
+
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
+version (Shared)
+ version (GNU)
+ version = GNUShared;
+
+version (D_InlineAsm_X86)
+{
+ version (Windows)
+ version = AsmX86_Windows;
+ else version (Posix)
+ version = AsmX86_Posix;
+}
+else version (D_InlineAsm_X86_64)
+{
+ version (Windows)
+ {
+ version = AsmX86_64_Windows;
+ }
+ else version (Posix)
+ {
+ version = AsmX86_64_Posix;
+ }
+}
+else version (X86)
+{
+ version (CET) {} else
+ {
+ version = AsmExternal;
+ }
+}
+else version (X86_64)
+{
+ version (CET) {} else
+ version (D_X32) {} else
+ {
+ version = AsmExternal;
+ }
+}
+else version (PPC)
+{
+ version (Posix)
+ {
+ version = AsmExternal;
+ }
+}
+else version (MIPS_O32)
+{
+ version (Posix)
+ {
+ version = AsmExternal;
+ }
+}
+else version (AArch64)
+{
+ version (Posix)
+ {
+ version = AsmExternal;
+ }
+}
+else version (ARM)
+{
+ version (Posix)
+ {
+ version = AsmExternal;
+ }
+}
+
+version (Posix)
+{
+ version (AsmX86_Windows) {} else
+ version (AsmX86_Posix) {} else
+ version (AsmX86_64_Windows) {} else
+ version (AsmX86_64_Posix) {} else
+ version (AsmExternal) {} else
+ {
+ // NOTE: The ucontext implementation requires architecture specific
+ // data definitions to operate so testing for it must be done
+ // by checking for the existence of ucontext_t rather than by
+ // a version identifier. Please note that this is considered
+ // an obsolescent feature according to the POSIX spec, so a
+ // custom solution is still preferred.
+ import core.sys.posix.ucontext;
+ }
+}
+
+version (Windows)
+{
+ import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below
+ import core.stdc.stdlib; // for malloc, atexit
+ import core.sys.windows.basetsd /+: HANDLE+/;
+ import core.sys.windows.threadaux /+: getThreadStackBottom, impersonate_thread, OpenThreadHandle+/;
+ import core.sys.windows.winbase /+: CloseHandle, CREATE_SUSPENDED, DuplicateHandle, GetCurrentThread,
+ GetCurrentThreadId, GetCurrentProcess, GetExitCodeThread, GetSystemInfo, GetThreadContext,
+ GetThreadPriority, INFINITE, ResumeThread, SetThreadPriority, Sleep, STILL_ACTIVE,
+ SuspendThread, SwitchToThread, SYSTEM_INFO, THREAD_PRIORITY_IDLE, THREAD_PRIORITY_NORMAL,
+ THREAD_PRIORITY_TIME_CRITICAL, WAIT_OBJECT_0, WaitForSingleObject+/;
+ import core.sys.windows.windef /+: TRUE+/;
+ import core.sys.windows.winnt /+: CONTEXT, CONTEXT_CONTROL, CONTEXT_INTEGER+/;
+
+ private extern (Windows) alias btex_fptr = uint function(void*);
+ private extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*) nothrow @nogc;
+}
+else version (Posix)
+{
+ import core.stdc.errno;
+ import core.sys.posix.semaphore;
+ import core.sys.posix.stdlib; // for malloc, valloc, free, atexit
+ import core.sys.posix.pthread;
+ import core.sys.posix.signal;
+ import core.sys.posix.time;
+
+ version (Darwin)
+ {
+ import core.sys.darwin.mach.thread_act;
+ import core.sys.darwin.pthread : pthread_mach_thread_np;
+ }
+}
+
+version (Solaris)
+{
+ import core.sys.solaris.sys.priocntl;
+ import core.sys.solaris.sys.types;
+ import core.sys.posix.sys.wait : idtype_t;
+}
+
+version (GNU)
+{
+ import gcc.builtins;
+}
+
+/**
+ * Hook for whatever EH implementation is used to save/restore some data
+ * per stack.
+ *
+ * Params:
+ * newContext = The return value of the prior call to this function
+ * where the stack was last swapped out, or null when a fiber stack
+ * is switched in for the first time.
+ */
+private extern(C) void* _d_eh_swapContext(void* newContext) nothrow @nogc;
+
+version (DigitalMars)
+{
+ version (Windows)
+ {
+ extern(D) void* swapContext(void* newContext) nothrow @nogc
+ {
+ return _d_eh_swapContext(newContext);
+ }
+ }
+ else
+ {
+ extern(C) void* _d_eh_swapContextDwarf(void* newContext) nothrow @nogc;
+
+ extern(D) void* swapContext(void* newContext) nothrow @nogc
+ {
+ /* Detect at runtime which scheme is being used.
+ * Eventually, determine it statically.
+ */
+ static int which = 0;
+ final switch (which)
+ {
+ case 0:
+ {
+ assert(newContext == null);
+ auto p = _d_eh_swapContext(newContext);
+ auto pdwarf = _d_eh_swapContextDwarf(newContext);
+ if (p)
+ {
+ which = 1;
+ return p;
+ }
+ else if (pdwarf)
+ {
+ which = 2;
+ return pdwarf;
+ }
+ return null;
+ }
+ case 1:
+ return _d_eh_swapContext(newContext);
+ case 2:
+ return _d_eh_swapContextDwarf(newContext);
+ }
+ }
+ }
+}
+else
+{
+ extern(D) void* swapContext(void* newContext) nothrow @nogc
+ {
+ return _d_eh_swapContext(newContext);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Thread
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * This class encapsulates all threading functionality for the D
+ * programming language. As thread manipulation is a required facility
+ * for garbage collection, all user threads should derive from this
+ * class, and instances of this class should never be explicitly deleted.
+ * A new thread may be created using either derivation or composition, as
+ * in the following example.
+ */
+class Thread : ThreadBase
+{
+ //
+ // Main process thread
+ //
+ version (FreeBSD)
+ {
+ // set when suspend failed and should be retried, see Issue 13416
+ private shared bool m_suspendagain;
+ }
+
+ //
+ // Standard thread data
+ //
+ version (Windows)
+ {
+ private HANDLE m_hndl;
+ }
+
+ version (Posix)
+ {
+ private shared bool m_isRunning;
+ }
+
+ version (Darwin)
+ {
+ private mach_port_t m_tmach;
+ }
+
+ version (Solaris)
+ {
+ private __gshared bool m_isRTClass;
+ }
+
+ //
+ // Standard types
+ //
+ version (Windows)
+ {
+ alias TLSKey = uint;
+ }
+ else version (Posix)
+ {
+ alias TLSKey = pthread_key_t;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Initialization
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Initializes a thread object which is associated with a static
+ * D function.
+ *
+ * Params:
+ * fn = The thread function.
+ * sz = The stack size for this thread.
+ *
+ * In:
+ * fn must not be null.
+ */
+ this( void function() fn, size_t sz = 0 ) @safe pure nothrow @nogc
+ {
+ super(fn, sz);
+ }
+
+
+ /**
+ * Initializes a thread object which is associated with a dynamic
+ * D function.
+ *
+ * Params:
+ * dg = The thread function.
+ * sz = The stack size for this thread.
+ *
+ * In:
+ * dg must not be null.
+ */
+ this( void delegate() dg, size_t sz = 0 ) @safe pure nothrow @nogc
+ {
+ super(dg, sz);
+ }
+
+ package this( size_t sz = 0 ) @safe pure nothrow @nogc
+ {
+ super(sz);
+ }
+
+ /**
+ * Cleans up any remaining resources used by this object.
+ */
+ ~this() nothrow @nogc
+ {
+ if (super.destructBeforeDtor())
+ return;
+
+ version (Windows)
+ {
+ m_addr = m_addr.init;
+ CloseHandle( m_hndl );
+ m_hndl = m_hndl.init;
+ }
+ else version (Posix)
+ {
+ if (m_addr != m_addr.init)
+ pthread_detach( m_addr );
+ m_addr = m_addr.init;
+ }
+ version (Darwin)
+ {
+ m_tmach = m_tmach.init;
+ }
+ }
+
+ //
+ // Thread entry point. Invokes the function or delegate passed on
+ // construction (if any).
+ //
+ private final void run()
+ {
+ super.run();
+ }
+
+ /**
+ * Provides a reference to the calling thread.
+ *
+ * Returns:
+ * The thread object representing the calling thread. The result of
+ * deleting this object is undefined. If the current thread is not
+ * attached to the runtime, a null reference is returned.
+ */
+ static Thread getThis() @safe nothrow @nogc
+ {
+ return ThreadBase.getThis().toThread;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Thread Context and GC Scanning Support
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ version (Windows)
+ {
+ version (X86)
+ {
+ uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax
+ }
+ else version (X86_64)
+ {
+ ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax
+ // r8,r9,r10,r11,r12,r13,r14,r15
+ }
+ else
+ {
+ static assert(false, "Architecture not supported." );
+ }
+ }
+ else version (Darwin)
+ {
+ version (X86)
+ {
+ uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax
+ }
+ else version (X86_64)
+ {
+ ulong[16] m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax
+ // r8,r9,r10,r11,r12,r13,r14,r15
+ }
+ else version (AArch64)
+ {
+ ulong[33] m_reg; // x0-x31, pc
+ }
+ else version (ARM)
+ {
+ uint[16] m_reg; // r0-r15
+ }
+ else version (PPC)
+ {
+ // Make the assumption that we only care about non-fp and non-vr regs.
+ // ??? : it seems plausible that a valid address can be copied into a VR.
+ uint[32] m_reg; // r0-31
+ }
+ else version (PPC64)
+ {
+ // As above.
+ ulong[32] m_reg; // r0-31
+ }
+ else
+ {
+ static assert(false, "Architecture not supported." );
+ }
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // General Actions
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Starts the thread and invokes the function or delegate passed upon
+ * construction.
+ *
+ * In:
+ * This routine may only be called once per thread instance.
+ *
+ * Throws:
+ * ThreadException if the thread fails to start.
+ */
+ final Thread start() nothrow
+ in
+ {
+ assert( !next && !prev );
+ }
+ do
+ {
+ auto wasThreaded = multiThreadedFlag;
+ multiThreadedFlag = true;
+ scope( failure )
+ {
+ if ( !wasThreaded )
+ multiThreadedFlag = false;
+ }
+
+ version (Windows) {} else
+ version (Posix)
+ {
+ size_t stksz = adjustStackSize( m_sz );
+
+ pthread_attr_t attr;
+
+ if ( pthread_attr_init( &attr ) )
+ onThreadError( "Error initializing thread attributes" );
+ if ( stksz && pthread_attr_setstacksize( &attr, stksz ) )
+ onThreadError( "Error initializing thread stack size" );
+ }
+
+ version (Windows)
+ {
+ // NOTE: If a thread is just executing DllMain()
+ // while another thread is started here, it holds an OS internal
+ // lock that serializes DllMain with CreateThread. As the code
+ // might request a synchronization on slock (e.g. in thread_findByAddr()),
+ // we cannot hold that lock while creating the thread without
+ // creating a deadlock
+ //
+ // Solution: Create the thread in suspended state and then
+ // add and resume it with slock acquired
+ assert(m_sz <= uint.max, "m_sz must be less than or equal to uint.max");
+ m_hndl = cast(HANDLE) _beginthreadex( null, cast(uint) m_sz, &thread_entryPoint, cast(void*) this, CREATE_SUSPENDED, &m_addr );
+ if ( cast(size_t) m_hndl == 0 )
+ onThreadError( "Error creating thread" );
+ }
+
+ slock.lock_nothrow();
+ scope(exit) slock.unlock_nothrow();
+ {
+ ++nAboutToStart;
+ pAboutToStart = cast(ThreadBase*)realloc(pAboutToStart, Thread.sizeof * nAboutToStart);
+ pAboutToStart[nAboutToStart - 1] = this;
+ version (Windows)
+ {
+ if ( ResumeThread( m_hndl ) == -1 )
+ onThreadError( "Error resuming thread" );
+ }
+ else version (Posix)
+ {
+ // NOTE: This is also set to true by thread_entryPoint, but set it
+ // here as well so the calling thread will see the isRunning
+ // state immediately.
+ atomicStore!(MemoryOrder.raw)(m_isRunning, true);
+ scope( failure ) atomicStore!(MemoryOrder.raw)(m_isRunning, false);
+
+ version (Shared)
+ {
+ version (GNU)
+ {
+ auto libs = externDFunc!("gcc.sections.pinLoadedLibraries",
+ void* function() @nogc nothrow)();
+ }
+ else
+ {
+ auto libs = externDFunc!("rt.sections_elf_shared.pinLoadedLibraries",
+ void* function() @nogc nothrow)();
+ }
+
+ auto ps = cast(void**).malloc(2 * size_t.sizeof);
+ if (ps is null) onOutOfMemoryError();
+ ps[0] = cast(void*)this;
+ ps[1] = cast(void*)libs;
+ if ( pthread_create( &m_addr, &attr, &thread_entryPoint, ps ) != 0 )
+ {
+ version (GNU)
+ {
+ externDFunc!("gcc.sections.unpinLoadedLibraries",
+ void function(void*) @nogc nothrow)(libs);
+ }
+ else
+ {
+ externDFunc!("rt.sections_elf_shared.unpinLoadedLibraries",
+ void function(void*) @nogc nothrow)(libs);
+ }
+ .free(ps);
+ onThreadError( "Error creating thread" );
+ }
+ }
+ else
+ {
+ if ( pthread_create( &m_addr, &attr, &thread_entryPoint, cast(void*) this ) != 0 )
+ onThreadError( "Error creating thread" );
+ }
+ if ( pthread_attr_destroy( &attr ) != 0 )
+ onThreadError( "Error destroying thread attributes" );
+ }
+ version (Darwin)
+ {
+ m_tmach = pthread_mach_thread_np( m_addr );
+ if ( m_tmach == m_tmach.init )
+ onThreadError( "Error creating thread" );
+ }
+
+ return this;
+ }
+ }
+
+ /**
+ * Waits for this thread to complete. If the thread terminated as the
+ * result of an unhandled exception, this exception will be rethrown.
+ *
+ * Params:
+ * rethrow = Rethrow any unhandled exception which may have caused this
+ * thread to terminate.
+ *
+ * Throws:
+ * ThreadException if the operation fails.
+ * Any exception not handled by the joined thread.
+ *
+ * Returns:
+ * Any exception not handled by this thread if rethrow = false, null
+ * otherwise.
+ */
+ override final Throwable join( bool rethrow = true )
+ {
+ version (Windows)
+ {
+ if ( m_addr != m_addr.init && WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
+ throw new ThreadException( "Unable to join thread" );
+ // NOTE: m_addr must be cleared before m_hndl is closed to avoid
+ // a race condition with isRunning. The operation is done
+ // with atomicStore to prevent compiler reordering.
+ atomicStore!(MemoryOrder.raw)(*cast(shared)&m_addr, m_addr.init);
+ CloseHandle( m_hndl );
+ m_hndl = m_hndl.init;
+ }
+ else version (Posix)
+ {
+ if ( m_addr != m_addr.init && pthread_join( m_addr, null ) != 0 )
+ throw new ThreadException( "Unable to join thread" );
+ // NOTE: pthread_join acts as a substitute for pthread_detach,
+ // which is normally called by the dtor. Setting m_addr
+ // to zero ensures that pthread_detach will not be called
+ // on object destruction.
+ m_addr = m_addr.init;
+ }
+ if ( m_unhandled )
+ {
+ if ( rethrow )
+ throw m_unhandled;
+ return m_unhandled;
+ }
+ return null;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Thread Priority Actions
+ ///////////////////////////////////////////////////////////////////////////
+
+ version (Windows)
+ {
+ @property static int PRIORITY_MIN() @nogc nothrow pure @safe
+ {
+ return THREAD_PRIORITY_IDLE;
+ }
+
+ @property static const(int) PRIORITY_MAX() @nogc nothrow pure @safe
+ {
+ return THREAD_PRIORITY_TIME_CRITICAL;
+ }
+
+ @property static int PRIORITY_DEFAULT() @nogc nothrow pure @safe
+ {
+ return THREAD_PRIORITY_NORMAL;
+ }
+ }
+ else
+ {
+ private struct Priority
+ {
+ int PRIORITY_MIN = int.min;
+ int PRIORITY_DEFAULT = int.min;
+ int PRIORITY_MAX = int.min;
+ }
+
+ /*
+ Lazily loads one of the members stored in a hidden global variable of
+ type `Priority`. Upon the first access of either member, the entire
+ `Priority` structure is initialized. Multiple initializations from
+ different threads calling this function are tolerated.
+
+ `which` must be one of `PRIORITY_MIN`, `PRIORITY_DEFAULT`,
+ `PRIORITY_MAX`.
+ */
+ private static shared Priority cache;
+ private static int loadGlobal(string which)()
+ {
+ auto local = atomicLoad(mixin("cache." ~ which));
+ if (local != local.min) return local;
+ // There will be benign races
+ cache = loadPriorities;
+ return atomicLoad(mixin("cache." ~ which));
+ }
+
+ /*
+ Loads all priorities and returns them as a `Priority` structure. This
+ function is thread-neutral.
+ */
+ private static Priority loadPriorities() @nogc nothrow @trusted
+ {
+ Priority result;
+ version (Solaris)
+ {
+ pcparms_t pcParms;
+ pcinfo_t pcInfo;
+
+ pcParms.pc_cid = PC_CLNULL;
+ if (priocntl(idtype_t.P_PID, P_MYID, PC_GETPARMS, &pcParms) == -1)
+ assert( 0, "Unable to get scheduling class" );
+
+ pcInfo.pc_cid = pcParms.pc_cid;
+ // PC_GETCLINFO ignores the first two args, use dummy values
+ if (priocntl(idtype_t.P_PID, 0, PC_GETCLINFO, &pcInfo) == -1)
+ assert( 0, "Unable to get scheduling class info" );
+
+ pri_t* clparms = cast(pri_t*)&pcParms.pc_clparms;
+ pri_t* clinfo = cast(pri_t*)&pcInfo.pc_clinfo;
+
+ result.PRIORITY_MAX = clparms[0];
+
+ if (pcInfo.pc_clname == "RT")
+ {
+ m_isRTClass = true;
+
+ // For RT class, just assume it can't be changed
+ result.PRIORITY_MIN = clparms[0];
+ result.PRIORITY_DEFAULT = clparms[0];
+ }
+ else
+ {
+ m_isRTClass = false;
+
+ // For all other scheduling classes, there are
+ // two key values -- uprilim and maxupri.
+ // maxupri is the maximum possible priority defined
+ // for the scheduling class, and valid priorities
+ // range are in [-maxupri, maxupri].
+ //
+ // However, uprilim is an upper limit that the
+ // current thread can set for the current scheduling
+ // class, which can be less than maxupri. As such,
+ // use this value for priorityMax since this is
+ // the effective maximum.
+
+ // maxupri
+ result.PRIORITY_MIN = -clinfo[0];
+ // by definition
+ result.PRIORITY_DEFAULT = 0;
+ }
+ }
+ else version (Posix)
+ {
+ int policy;
+ sched_param param;
+ pthread_getschedparam( pthread_self(), &policy, &param ) == 0
+ || assert(0, "Internal error in pthread_getschedparam");
+
+ result.PRIORITY_MIN = sched_get_priority_min( policy );
+ result.PRIORITY_MIN != -1
+ || assert(0, "Internal error in sched_get_priority_min");
+ result.PRIORITY_DEFAULT = param.sched_priority;
+ result.PRIORITY_MAX = sched_get_priority_max( policy );
+ result.PRIORITY_MAX != -1 ||
+ assert(0, "Internal error in sched_get_priority_max");
+ }
+ else
+ {
+ static assert(0, "Your code here.");
+ }
+ return result;
+ }
+
+ /**
+ * The minimum scheduling priority that may be set for a thread. On
+ * systems where multiple scheduling policies are defined, this value
+ * represents the minimum valid priority for the scheduling policy of
+ * the process.
+ */
+ @property static int PRIORITY_MIN() @nogc nothrow pure @trusted
+ {
+ return (cast(int function() @nogc nothrow pure @safe)
+ &loadGlobal!"PRIORITY_MIN")();
+ }
+
+ /**
+ * The maximum scheduling priority that may be set for a thread. On
+ * systems where multiple scheduling policies are defined, this value
+ * represents the maximum valid priority for the scheduling policy of
+ * the process.
+ */
+ @property static const(int) PRIORITY_MAX() @nogc nothrow pure @trusted
+ {
+ return (cast(int function() @nogc nothrow pure @safe)
+ &loadGlobal!"PRIORITY_MAX")();
+ }
+
+ /**
+ * The default scheduling priority that is set for a thread. On
+ * systems where multiple scheduling policies are defined, this value
+ * represents the default priority for the scheduling policy of
+ * the process.
+ */
+ @property static int PRIORITY_DEFAULT() @nogc nothrow pure @trusted
+ {
+ return (cast(int function() @nogc nothrow pure @safe)
+ &loadGlobal!"PRIORITY_DEFAULT")();
+ }
+ }
+
+ version (NetBSD)
+ {
+ //NetBSD does not support priority for default policy
+ // and it is not possible change policy without root access
+ int fakePriority = int.max;
+ }
+
+ /**
+ * Gets the scheduling priority for the associated thread.
+ *
+ * Note: Getting the priority of a thread that already terminated
+ * might return the default priority.
+ *
+ * Returns:
+ * The scheduling priority of this thread.
+ */
+ final @property int priority()
+ {
+ version (Windows)
+ {
+ return GetThreadPriority( m_hndl );
+ }
+ else version (NetBSD)
+ {
+ return fakePriority==int.max? PRIORITY_DEFAULT : fakePriority;
+ }
+ else version (Posix)
+ {
+ int policy;
+ sched_param param;
+
+ if (auto err = pthread_getschedparam(m_addr, &policy, &param))
+ {
+ // ignore error if thread is not running => Bugzilla 8960
+ if (!atomicLoad(m_isRunning)) return PRIORITY_DEFAULT;
+ throw new ThreadException("Unable to get thread priority");
+ }
+ return param.sched_priority;
+ }
+ }
+
+
+ /**
+ * Sets the scheduling priority for the associated thread.
+ *
+ * Note: Setting the priority of a thread that already terminated
+ * might have no effect.
+ *
+ * Params:
+ * val = The new scheduling priority of this thread.
+ */
+ final @property void priority( int val )
+ in
+ {
+ assert(val >= PRIORITY_MIN);
+ assert(val <= PRIORITY_MAX);
+ }
+ do
+ {
+ version (Windows)
+ {
+ if ( !SetThreadPriority( m_hndl, val ) )
+ throw new ThreadException( "Unable to set thread priority" );
+ }
+ else version (Solaris)
+ {
+ // the pthread_setschedprio(3c) and pthread_setschedparam functions
+ // are broken for the default (TS / time sharing) scheduling class.
+ // instead, we use priocntl(2) which gives us the desired behavior.
+
+ // We hardcode the min and max priorities to the current value
+ // so this is a no-op for RT threads.
+ if (m_isRTClass)
+ return;
+
+ pcparms_t pcparm;
+
+ pcparm.pc_cid = PC_CLNULL;
+ if (priocntl(idtype_t.P_LWPID, P_MYID, PC_GETPARMS, &pcparm) == -1)
+ throw new ThreadException( "Unable to get scheduling class" );
+
+ pri_t* clparms = cast(pri_t*)&pcparm.pc_clparms;
+
+ // clparms is filled in by the PC_GETPARMS call, only necessary
+ // to adjust the element that contains the thread priority
+ clparms[1] = cast(pri_t) val;
+
+ if (priocntl(idtype_t.P_LWPID, P_MYID, PC_SETPARMS, &pcparm) == -1)
+ throw new ThreadException( "Unable to set scheduling class" );
+ }
+ else version (NetBSD)
+ {
+ fakePriority = val;
+ }
+ else version (Posix)
+ {
+ static if (__traits(compiles, pthread_setschedprio))
+ {
+ if (auto err = pthread_setschedprio(m_addr, val))
+ {
+ // ignore error if thread is not running => Bugzilla 8960
+ if (!atomicLoad(m_isRunning)) return;
+ throw new ThreadException("Unable to set thread priority");
+ }
+ }
+ else
+ {
+ // NOTE: pthread_setschedprio is not implemented on Darwin, FreeBSD, OpenBSD,
+ // or DragonFlyBSD, so use the more complicated get/set sequence below.
+ int policy;
+ sched_param param;
+
+ if (auto err = pthread_getschedparam(m_addr, &policy, &param))
+ {
+ // ignore error if thread is not running => Bugzilla 8960
+ if (!atomicLoad(m_isRunning)) return;
+ throw new ThreadException("Unable to set thread priority");
+ }
+ param.sched_priority = val;
+ if (auto err = pthread_setschedparam(m_addr, policy, &param))
+ {
+ // ignore error if thread is not running => Bugzilla 8960
+ if (!atomicLoad(m_isRunning)) return;
+ throw new ThreadException("Unable to set thread priority");
+ }
+ }
+ }
+ }
+
+
+ unittest
+ {
+ auto thr = Thread.getThis();
+ immutable prio = thr.priority;
+ scope (exit) thr.priority = prio;
+
+ assert(prio == PRIORITY_DEFAULT);
+ assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX);
+ thr.priority = PRIORITY_MIN;
+ assert(thr.priority == PRIORITY_MIN);
+ thr.priority = PRIORITY_MAX;
+ assert(thr.priority == PRIORITY_MAX);
+ }
+
+ unittest // Bugzilla 8960
+ {
+ import core.sync.semaphore;
+
+ auto thr = new Thread({});
+ thr.start();
+ Thread.sleep(1.msecs); // wait a little so the thread likely has finished
+ thr.priority = PRIORITY_MAX; // setting priority doesn't cause error
+ auto prio = thr.priority; // getting priority doesn't cause error
+ assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX);
+ }
+
+ /**
+ * Tests whether this thread is running.
+ *
+ * Returns:
+ * true if the thread is running, false if not.
+ */
+ override final @property bool isRunning() nothrow @nogc
+ {
+ if (!super.isRunning())
+ return false;
+
+ version (Windows)
+ {
+ uint ecode = 0;
+ GetExitCodeThread( m_hndl, &ecode );
+ return ecode == STILL_ACTIVE;
+ }
+ else version (Posix)
+ {
+ return atomicLoad(m_isRunning);
+ }
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Actions on Calling Thread
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Suspends the calling thread for at least the supplied period. This may
+ * result in multiple OS calls if period is greater than the maximum sleep
+ * duration supported by the operating system.
+ *
+ * Params:
+ * val = The minimum duration the calling thread should be suspended.
+ *
+ * In:
+ * period must be non-negative.
+ *
+ * Example:
+ * ------------------------------------------------------------------------
+ *
+ * Thread.sleep( dur!("msecs")( 50 ) ); // sleep for 50 milliseconds
+ * Thread.sleep( dur!("seconds")( 5 ) ); // sleep for 5 seconds
+ *
+ * ------------------------------------------------------------------------
+ */
+ static void sleep( Duration val ) @nogc nothrow
+ in
+ {
+ assert( !val.isNegative );
+ }
+ do
+ {
+ version (Windows)
+ {
+ auto maxSleepMillis = dur!("msecs")( uint.max - 1 );
+
+ // avoid a non-zero time to be round down to 0
+ if ( val > dur!"msecs"( 0 ) && val < dur!"msecs"( 1 ) )
+ val = dur!"msecs"( 1 );
+
+ // NOTE: In instances where all other threads in the process have a
+ // lower priority than the current thread, the current thread
+ // will not yield with a sleep time of zero. However, unlike
+ // yield(), the user is not asking for a yield to occur but
+ // only for execution to suspend for the requested interval.
+ // Therefore, expected performance may not be met if a yield
+ // is forced upon the user.
+ while ( val > maxSleepMillis )
+ {
+ Sleep( cast(uint)
+ maxSleepMillis.total!"msecs" );
+ val -= maxSleepMillis;
+ }
+ Sleep( cast(uint) val.total!"msecs" );
+ }
+ else version (Posix)
+ {
+ timespec tin = void;
+ timespec tout = void;
+
+ val.split!("seconds", "nsecs")(tin.tv_sec, tin.tv_nsec);
+ if ( val.total!"seconds" > tin.tv_sec.max )
+ tin.tv_sec = tin.tv_sec.max;
+ while ( true )
+ {
+ if ( !nanosleep( &tin, &tout ) )
+ return;
+ if ( errno != EINTR )
+ assert(0, "Unable to sleep for the specified duration");
+ tin = tout;
+ }
+ }
+ }
+
+
+ /**
+ * Forces a context switch to occur away from the calling thread.
+ */
+ static void yield() @nogc nothrow
+ {
+ version (Windows)
+ SwitchToThread();
+ else version (Posix)
+ sched_yield();
+ }
+}
+
+private Thread toThread(ThreadBase t) @trusted nothrow @nogc pure
+{
+ return cast(Thread) cast(void*) t;
+}
+
+private extern(D) static void thread_yield() @nogc nothrow
+{
+ Thread.yield();
+}
+
+///
+unittest
+{
+ class DerivedThread : Thread
+ {
+ this()
+ {
+ super(&run);
+ }
+
+ private:
+ void run()
+ {
+ // Derived thread running.
+ }
+ }
+
+ void threadFunc()
+ {
+ // Composed thread running.
+ }
+
+ // create and start instances of each type
+ auto derived = new DerivedThread().start();
+ auto composed = new Thread(&threadFunc).start();
+ new Thread({
+ // Codes to run in the newly created thread.
+ }).start();
+}
+
+unittest
+{
+ int x = 0;
+
+ new Thread(
+ {
+ x++;
+ }).start().join();
+ assert( x == 1 );
+}
+
+
+unittest
+{
+ enum MSG = "Test message.";
+ string caughtMsg;
+
+ try
+ {
+ new Thread(
+ {
+ throw new Exception( MSG );
+ }).start().join();
+ assert( false, "Expected rethrown exception." );
+ }
+ catch ( Throwable t )
+ {
+ assert( t.msg == MSG );
+ }
+}
+
+
+unittest
+{
+ // use >PAGESIZE to avoid stack overflow (e.g. in an syscall)
+ auto thr = new Thread(function{}, 4096 + 1).start();
+ thr.join();
+}
+
+
+unittest
+{
+ import core.memory : GC;
+
+ auto t1 = new Thread({
+ foreach (_; 0 .. 20)
+ ThreadBase.getAll;
+ }).start;
+ auto t2 = new Thread({
+ foreach (_; 0 .. 20)
+ GC.collect;
+ }).start;
+ t1.join();
+ t2.join();
+}
+
+unittest
+{
+ import core.sync.semaphore;
+ auto sem = new Semaphore();
+
+ auto t = new Thread(
+ {
+ sem.notify();
+ Thread.sleep(100.msecs);
+ }).start();
+
+ sem.wait(); // thread cannot be detached while being started
+ thread_detachInstance(t);
+ foreach (t2; Thread)
+ assert(t !is t2);
+ t.join();
+}
+
+unittest
+{
+ // NOTE: This entire test is based on the assumption that no
+ // memory is allocated after the child thread is
+ // started. If an allocation happens, a collection could
+ // trigger, which would cause the synchronization below
+ // to cause a deadlock.
+ // NOTE: DO NOT USE LOCKS IN CRITICAL REGIONS IN NORMAL CODE.
+
+ import core.sync.semaphore;
+
+ auto sema = new Semaphore(),
+ semb = new Semaphore();
+
+ auto thr = new Thread(
+ {
+ thread_enterCriticalRegion();
+ assert(thread_inCriticalRegion());
+ sema.notify();
+
+ semb.wait();
+ assert(thread_inCriticalRegion());
+
+ thread_exitCriticalRegion();
+ assert(!thread_inCriticalRegion());
+ sema.notify();
+
+ semb.wait();
+ assert(!thread_inCriticalRegion());
+ });
+
+ thr.start();
+
+ sema.wait();
+ synchronized (ThreadBase.criticalRegionLock)
+ assert(thr.m_isInCriticalRegion);
+ semb.notify();
+
+ sema.wait();
+ synchronized (ThreadBase.criticalRegionLock)
+ assert(!thr.m_isInCriticalRegion);
+ semb.notify();
+
+ thr.join();
+}
+
+unittest
+{
+ import core.sync.semaphore;
+
+ shared bool inCriticalRegion;
+ auto sema = new Semaphore(),
+ semb = new Semaphore();
+
+ auto thr = new Thread(
+ {
+ thread_enterCriticalRegion();
+ inCriticalRegion = true;
+ sema.notify();
+ semb.wait();
+
+ Thread.sleep(dur!"msecs"(1));
+ inCriticalRegion = false;
+ thread_exitCriticalRegion();
+ });
+ thr.start();
+
+ sema.wait();
+ assert(inCriticalRegion);
+ semb.notify();
+
+ thread_suspendAll();
+ assert(!inCriticalRegion);
+ thread_resumeAll();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// GC Support Routines
+///////////////////////////////////////////////////////////////////////////////
+
+version (CoreDdoc)
+{
+ /**
+ * Instruct the thread module, when initialized, to use a different set of
+ * signals besides SIGUSR1 and SIGUSR2 for suspension and resumption of threads.
+ * This function should be called at most once, prior to thread_init().
+ * This function is Posix-only.
+ */
+ extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc
+ {
+ }
+}
+else version (Posix)
+{
+ extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc
+ in
+ {
+ assert(suspendSignalNo != 0);
+ assert(resumeSignalNo != 0);
+ }
+ out
+ {
+ assert(suspendSignalNumber != 0);
+ assert(resumeSignalNumber != 0);
+ }
+ do
+ {
+ suspendSignalNumber = suspendSignalNo;
+ resumeSignalNumber = resumeSignalNo;
+ }
+}
+
+version (Posix)
+{
+ private __gshared int suspendSignalNumber = SIGUSR1;
+ private __gshared int resumeSignalNumber = SIGUSR2;
+}
+
+private extern (D) ThreadBase attachThread(ThreadBase _thisThread) @nogc nothrow
+{
+ Thread thisThread = _thisThread.toThread();
+
+ StackContext* thisContext = &thisThread.m_main;
+ assert( thisContext == thisThread.m_curr );
+
+ version (Windows)
+ {
+ thisThread.m_addr = GetCurrentThreadId();
+ thisThread.m_hndl = GetCurrentThreadHandle();
+ thisContext.bstack = getStackBottom();
+ thisContext.tstack = thisContext.bstack;
+ }
+ else version (Posix)
+ {
+ thisThread.m_addr = pthread_self();
+ thisContext.bstack = getStackBottom();
+ thisContext.tstack = thisContext.bstack;
+
+ atomicStore!(MemoryOrder.raw)(thisThread.toThread.m_isRunning, true);
+ }
+ thisThread.m_isDaemon = true;
+ thisThread.tlsGCdataInit();
+ Thread.setThis( thisThread );
+
+ version (Darwin)
+ {
+ thisThread.m_tmach = pthread_mach_thread_np( thisThread.m_addr );
+ assert( thisThread.m_tmach != thisThread.m_tmach.init );
+ }
+
+ Thread.add( thisThread, false );
+ Thread.add( thisContext );
+ if ( Thread.sm_main !is null )
+ multiThreadedFlag = true;
+ return thisThread;
+}
+
+/**
+ * Registers the calling thread for use with the D Runtime. If this routine
+ * is called for a thread which is already registered, no action is performed.
+ *
+ * NOTE: This routine does not run thread-local static constructors when called.
+ * If full functionality as a D thread is desired, the following function
+ * must be called after thread_attachThis:
+ *
+ * extern (C) void rt_moduleTlsCtor();
+ */
+extern(C) Thread thread_attachThis()
+{
+ return thread_attachThis_tpl!Thread();
+}
+
+
+version (Windows)
+{
+ // NOTE: These calls are not safe on Posix systems that use signals to
+ // perform garbage collection. The suspendHandler uses getThis()
+ // to get the thread handle so getThis() must be a simple call.
+ // Mutexes can't safely be acquired inside signal handlers, and
+ // even if they could, the mutex needed (Thread.slock) is held by
+ // thread_suspendAll(). So in short, these routines will remain
+ // Windows-specific. If they are truly needed elsewhere, the
+ // suspendHandler will need a way to call a version of getThis()
+ // that only does the TLS lookup without the fancy fallback stuff.
+
+ /// ditto
+ extern (C) Thread thread_attachByAddr( ThreadID addr )
+ {
+ return thread_attachByAddrB( addr, getThreadStackBottom( addr ) );
+ }
+
+
+ /// ditto
+ extern (C) Thread thread_attachByAddrB( ThreadID addr, void* bstack )
+ {
+ GC.disable(); scope(exit) GC.enable();
+
+ if (auto t = thread_findByAddr(addr).toThread)
+ return t;
+
+ Thread thisThread = new Thread();
+ StackContext* thisContext = &thisThread.m_main;
+ assert( thisContext == thisThread.m_curr );
+
+ thisThread.m_addr = addr;
+ thisContext.bstack = bstack;
+ thisContext.tstack = thisContext.bstack;
+
+ thisThread.m_isDaemon = true;
+
+ if ( addr == GetCurrentThreadId() )
+ {
+ thisThread.m_hndl = GetCurrentThreadHandle();
+ thisThread.tlsGCdataInit();
+ Thread.setThis( thisThread );
+ }
+ else
+ {
+ thisThread.m_hndl = OpenThreadHandle( addr );
+ impersonate_thread(addr,
+ {
+ thisThread.tlsGCdataInit();
+ Thread.setThis( thisThread );
+ });
+ }
+
+ Thread.add( thisThread, false );
+ Thread.add( thisContext );
+ if ( Thread.sm_main !is null )
+ multiThreadedFlag = true;
+ return thisThread;
+ }
+}
+
+
+// Calls the given delegate, passing the current thread's stack pointer to it.
+package extern(D) void callWithStackShell(scope callWithStackShellDg fn) nothrow
+in (fn)
+{
+ // The purpose of the 'shell' is to ensure all the registers get
+ // put on the stack so they'll be scanned. We only need to push
+ // the callee-save registers.
+ void *sp = void;
+ version (GNU)
+ {
+ // The generic solution below using a call to __builtin_unwind_init ()
+ // followed by an assignment to sp has two issues:
+ // 1) On some archs it stores a huge amount of FP and Vector state which
+ // is not the subject of the scan - and, indeed might produce false
+ // hits.
+ // 2) Even on archs like X86, where there are no callee-saved FPRs/VRs there
+ // tend to be 'holes' in the frame allocations (to deal with alignment) which
+ // also will contain random data which could produce false positives.
+ // This solution stores only the integer callee-saved registers.
+ version (X86)
+ {
+ void*[3] regs = void;
+ asm pure nothrow @nogc
+ {
+ "movl %%ebx, %0" : "=m" (regs[0]);
+ "movl %%esi, %0" : "=m" (regs[1]);
+ "movl %%edi, %0" : "=m" (regs[2]);
+ }
+ sp = cast(void*)&regs[0];
+ }
+ else version (X86_64)
+ {
+ void*[5] regs = void;
+ asm pure nothrow @nogc
+ {
+ "movq %%rbx, %0" : "=m" (regs[0]);
+ "movq %%r12, %0" : "=m" (regs[1]);
+ "movq %%r13, %0" : "=m" (regs[2]);
+ "movq %%r14, %0" : "=m" (regs[3]);
+ "movq %%r15, %0" : "=m" (regs[4]);
+ }
+ sp = cast(void*)&regs[0];
+ }
+ else version (PPC)
+ {
+ void*[19] regs = void;
+ version (Darwin)
+ enum regname = "r";
+ else
+ enum regname = "";
+ static foreach (i; 0 .. regs.length)
+ {{
+ enum int j = 13 + i; // source register
+ asm pure nothrow @nogc
+ {
+ "stw "~regname~j.stringof~", %0" : "=m" (regs[i]);
+ }
+ }}
+ sp = cast(void*)&regs[0];
+ }
+ else version (PPC64)
+ {
+ void*[19] regs = void;
+ version (Darwin)
+ enum regname = "r";
+ else
+ enum regname = "";
+ static foreach (i; 0 .. regs.length)
+ {{
+ enum int j = 13 + i; // source register
+ asm pure nothrow @nogc
+ {
+ "std "~regname~j.stringof~", %0" : "=m" (regs[i]);
+ }
+ }}
+ sp = cast(void*)&regs[0];
+ }
+ else
+ {
+ __builtin_unwind_init();
+ sp = &sp;
+ }
+ }
+ else version (AsmX86_Posix)
+ {
+ size_t[3] regs = void;
+ asm pure nothrow @nogc
+ {
+ mov [regs + 0 * 4], EBX;
+ mov [regs + 1 * 4], ESI;
+ mov [regs + 2 * 4], EDI;
+
+ mov sp[EBP], ESP;
+ }
+ }
+ else version (AsmX86_Windows)
+ {
+ size_t[3] regs = void;
+ asm pure nothrow @nogc
+ {
+ mov [regs + 0 * 4], EBX;
+ mov [regs + 1 * 4], ESI;
+ mov [regs + 2 * 4], EDI;
+
+ mov sp[EBP], ESP;
+ }
+ }
+ else version (AsmX86_64_Posix)
+ {
+ size_t[5] regs = void;
+ asm pure nothrow @nogc
+ {
+ mov [regs + 0 * 8], RBX;
+ mov [regs + 1 * 8], R12;
+ mov [regs + 2 * 8], R13;
+ mov [regs + 3 * 8], R14;
+ mov [regs + 4 * 8], R15;
+
+ mov sp[RBP], RSP;
+ }
+ }
+ else version (AsmX86_64_Windows)
+ {
+ size_t[7] regs = void;
+ asm pure nothrow @nogc
+ {
+ mov [regs + 0 * 8], RBX;
+ mov [regs + 1 * 8], RSI;
+ mov [regs + 2 * 8], RDI;
+ mov [regs + 3 * 8], R12;
+ mov [regs + 4 * 8], R13;
+ mov [regs + 5 * 8], R14;
+ mov [regs + 6 * 8], R15;
+
+ mov sp[RBP], RSP;
+ }
+ }
+ else
+ {
+ static assert(false, "Architecture not supported.");
+ }
+
+ fn(sp);
+}
+
+version (Windows)
+private extern (D) void scanWindowsOnly(scope ScanAllThreadsTypeFn scan, ThreadBase _t) nothrow
+{
+ auto t = _t.toThread;
+
+ scan( ScanType.stack, t.m_reg.ptr, t.m_reg.ptr + t.m_reg.length );
+}
+
+
+/**
+ * Returns the process ID of the calling process, which is guaranteed to be
+ * unique on the system. This call is always successful.
+ *
+ * Example:
+ * ---
+ * writefln("Current process id: %s", getpid());
+ * ---
+ */
+version (Posix)
+{
+ import core.sys.posix.unistd;
+
+ alias getpid = core.sys.posix.unistd.getpid;
+}
+else version (Windows)
+{
+ alias getpid = core.sys.windows.winbase.GetCurrentProcessId;
+}
+
+extern (C) @nogc nothrow
+{
+ version (CRuntime_Glibc) version = PThread_Getattr_NP;
+ version (CRuntime_Bionic) version = PThread_Getattr_NP;
+ version (CRuntime_Musl) version = PThread_Getattr_NP;
+ version (CRuntime_UClibc) version = PThread_Getattr_NP;
+
+ version (FreeBSD) version = PThread_Attr_Get_NP;
+ version (NetBSD) version = PThread_Attr_Get_NP;
+ version (DragonFlyBSD) version = PThread_Attr_Get_NP;
+
+ version (PThread_Getattr_NP) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr);
+ version (PThread_Attr_Get_NP) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr);
+ version (Solaris) int thr_stksegment(stack_t* stk);
+ version (OpenBSD) int pthread_stackseg_np(pthread_t thread, stack_t* sinfo);
+}
+
+
+package extern(D) void* getStackTop() nothrow @nogc
+{
+ version (D_InlineAsm_X86)
+ asm pure nothrow @nogc { naked; mov EAX, ESP; ret; }
+ else version (D_InlineAsm_X86_64)
+ asm pure nothrow @nogc { naked; mov RAX, RSP; ret; }
+ else version (GNU)
+ return __builtin_frame_address(0);
+ else
+ static assert(false, "Architecture not supported.");
+}
+
+
+package extern(D) void* getStackBottom() nothrow @nogc
+{
+ version (Windows)
+ {
+ version (D_InlineAsm_X86)
+ asm pure nothrow @nogc { naked; mov EAX, FS:4; ret; }
+ else version (D_InlineAsm_X86_64)
+ asm pure nothrow @nogc
+ { naked;
+ mov RAX, 8;
+ mov RAX, GS:[RAX];
+ ret;
+ }
+ else version (GNU_InlineAsm)
+ {
+ void *bottom;
+
+ version (X86)
+ asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
+ else version (X86_64)
+ asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
+ else
+ static assert(false, "Platform not supported.");
+
+ return bottom;
+ }
+ else
+ static assert(false, "Architecture not supported.");
+ }
+ else version (Darwin)
+ {
+ import core.sys.darwin.pthread;
+ return pthread_get_stackaddr_np(pthread_self());
+ }
+ else version (PThread_Getattr_NP)
+ {
+ pthread_attr_t attr;
+ void* addr; size_t size;
+
+ pthread_attr_init(&attr);
+ pthread_getattr_np(pthread_self(), &attr);
+ pthread_attr_getstack(&attr, &addr, &size);
+ pthread_attr_destroy(&attr);
+ static if (isStackGrowingDown)
+ addr += size;
+ return addr;
+ }
+ else version (PThread_Attr_Get_NP)
+ {
+ pthread_attr_t attr;
+ void* addr; size_t size;
+
+ pthread_attr_init(&attr);
+ pthread_attr_get_np(pthread_self(), &attr);
+ pthread_attr_getstack(&attr, &addr, &size);
+ pthread_attr_destroy(&attr);
+ static if (isStackGrowingDown)
+ addr += size;
+ return addr;
+ }
+ else version (OpenBSD)
+ {
+ stack_t stk;
+
+ pthread_stackseg_np(pthread_self(), &stk);
+ return stk.ss_sp;
+ }
+ else version (Solaris)
+ {
+ stack_t stk;
+
+ thr_stksegment(&stk);
+ return stk.ss_sp;
+ }
+ else
+ static assert(false, "Platform not supported.");
+}
+
+/**
+ * Suspend the specified thread and load stack and register information for
+ * use by thread_scanAll. If the supplied thread is the calling thread,
+ * stack and register information will be loaded but the thread will not
+ * be suspended. If the suspend operation fails and the thread is not
+ * running then it will be removed from the global thread list, otherwise
+ * an exception will be thrown.
+ *
+ * Params:
+ * t = The thread to suspend.
+ *
+ * Throws:
+ * ThreadError if the suspend operation fails for a running thread.
+ * Returns:
+ * Whether the thread is now suspended (true) or terminated (false).
+ */
+private extern (D) bool suspend( Thread t ) nothrow @nogc
+{
+ Duration waittime = dur!"usecs"(10);
+ Lagain:
+ if (!t.isRunning)
+ {
+ Thread.remove(t);
+ return false;
+ }
+ else if (t.m_isInCriticalRegion)
+ {
+ Thread.criticalRegionLock.unlock_nothrow();
+ Thread.sleep(waittime);
+ if (waittime < dur!"msecs"(10)) waittime *= 2;
+ Thread.criticalRegionLock.lock_nothrow();
+ goto Lagain;
+ }
+
+ version (Windows)
+ {
+ if ( t.m_addr != GetCurrentThreadId() && SuspendThread( t.m_hndl ) == 0xFFFFFFFF )
+ {
+ if ( !t.isRunning )
+ {
+ Thread.remove( t );
+ return false;
+ }
+ onThreadError( "Unable to suspend thread" );
+ }
+
+ CONTEXT context = void;
+ context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
+
+ if ( !GetThreadContext( t.m_hndl, &context ) )
+ onThreadError( "Unable to load thread context" );
+ version (X86)
+ {
+ if ( !t.m_lock )
+ t.m_curr.tstack = cast(void*) context.Esp;
+ // eax,ebx,ecx,edx,edi,esi,ebp,esp
+ t.m_reg[0] = context.Eax;
+ t.m_reg[1] = context.Ebx;
+ t.m_reg[2] = context.Ecx;
+ t.m_reg[3] = context.Edx;
+ t.m_reg[4] = context.Edi;
+ t.m_reg[5] = context.Esi;
+ t.m_reg[6] = context.Ebp;
+ t.m_reg[7] = context.Esp;
+ }
+ else version (X86_64)
+ {
+ if ( !t.m_lock )
+ t.m_curr.tstack = cast(void*) context.Rsp;
+ // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp
+ t.m_reg[0] = context.Rax;
+ t.m_reg[1] = context.Rbx;
+ t.m_reg[2] = context.Rcx;
+ t.m_reg[3] = context.Rdx;
+ t.m_reg[4] = context.Rdi;
+ t.m_reg[5] = context.Rsi;
+ t.m_reg[6] = context.Rbp;
+ t.m_reg[7] = context.Rsp;
+ // r8,r9,r10,r11,r12,r13,r14,r15
+ t.m_reg[8] = context.R8;
+ t.m_reg[9] = context.R9;
+ t.m_reg[10] = context.R10;
+ t.m_reg[11] = context.R11;
+ t.m_reg[12] = context.R12;
+ t.m_reg[13] = context.R13;
+ t.m_reg[14] = context.R14;
+ t.m_reg[15] = context.R15;
+ }
+ else
+ {
+ static assert(false, "Architecture not supported." );
+ }
+ }
+ else version (Darwin)
+ {
+ if ( t.m_addr != pthread_self() && thread_suspend( t.m_tmach ) != KERN_SUCCESS )
+ {
+ if ( !t.isRunning )
+ {
+ Thread.remove( t );
+ return false;
+ }
+ onThreadError( "Unable to suspend thread" );
+ }
+
+ version (X86)
+ {
+ x86_thread_state32_t state = void;
+ mach_msg_type_number_t count = x86_THREAD_STATE32_COUNT;
+
+ if ( thread_get_state( t.m_tmach, x86_THREAD_STATE32, &state, &count ) != KERN_SUCCESS )
+ onThreadError( "Unable to load thread state" );
+ if ( !t.m_lock )
+ t.m_curr.tstack = cast(void*) state.esp;
+ // eax,ebx,ecx,edx,edi,esi,ebp,esp
+ t.m_reg[0] = state.eax;
+ t.m_reg[1] = state.ebx;
+ t.m_reg[2] = state.ecx;
+ t.m_reg[3] = state.edx;
+ t.m_reg[4] = state.edi;
+ t.m_reg[5] = state.esi;
+ t.m_reg[6] = state.ebp;
+ t.m_reg[7] = state.esp;
+ }
+ else version (X86_64)
+ {
+ x86_thread_state64_t state = void;
+ mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
+
+ if ( thread_get_state( t.m_tmach, x86_THREAD_STATE64, &state, &count ) != KERN_SUCCESS )
+ onThreadError( "Unable to load thread state" );
+ if ( !t.m_lock )
+ t.m_curr.tstack = cast(void*) state.rsp;
+ // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp
+ t.m_reg[0] = state.rax;
+ t.m_reg[1] = state.rbx;
+ t.m_reg[2] = state.rcx;
+ t.m_reg[3] = state.rdx;
+ t.m_reg[4] = state.rdi;
+ t.m_reg[5] = state.rsi;
+ t.m_reg[6] = state.rbp;
+ t.m_reg[7] = state.rsp;
+ // r8,r9,r10,r11,r12,r13,r14,r15
+ t.m_reg[8] = state.r8;
+ t.m_reg[9] = state.r9;
+ t.m_reg[10] = state.r10;
+ t.m_reg[11] = state.r11;
+ t.m_reg[12] = state.r12;
+ t.m_reg[13] = state.r13;
+ t.m_reg[14] = state.r14;
+ t.m_reg[15] = state.r15;
+ }
+ else version (AArch64)
+ {
+ arm_thread_state64_t state = void;
+ mach_msg_type_number_t count = ARM_THREAD_STATE64_COUNT;
+
+ if (thread_get_state(t.m_tmach, ARM_THREAD_STATE64, &state, &count) != KERN_SUCCESS)
+ onThreadError("Unable to load thread state");
+ // TODO: ThreadException here recurses forever! Does it
+ //still using onThreadError?
+ //printf("state count %d (expect %d)\n", count ,ARM_THREAD_STATE64_COUNT);
+ if (!t.m_lock)
+ t.m_curr.tstack = cast(void*) state.sp;
+
+ t.m_reg[0..29] = state.x; // x0-x28
+ t.m_reg[29] = state.fp; // x29
+ t.m_reg[30] = state.lr; // x30
+ t.m_reg[31] = state.sp; // x31
+ t.m_reg[32] = state.pc;
+ }
+ else version (ARM)
+ {
+ arm_thread_state32_t state = void;
+ mach_msg_type_number_t count = ARM_THREAD_STATE32_COUNT;
+
+ // Thought this would be ARM_THREAD_STATE32, but that fails.
+ // Mystery
+ if (thread_get_state(t.m_tmach, ARM_THREAD_STATE, &state, &count) != KERN_SUCCESS)
+ onThreadError("Unable to load thread state");
+ // TODO: in past, ThreadException here recurses forever! Does it
+ //still using onThreadError?
+ //printf("state count %d (expect %d)\n", count ,ARM_THREAD_STATE32_COUNT);
+ if (!t.m_lock)
+ t.m_curr.tstack = cast(void*) state.sp;
+
+ t.m_reg[0..13] = state.r; // r0 - r13
+ t.m_reg[13] = state.sp;
+ t.m_reg[14] = state.lr;
+ t.m_reg[15] = state.pc;
+ }
+ else version (PPC)
+ {
+ ppc_thread_state_t state = void;
+ mach_msg_type_number_t count = PPC_THREAD_STATE_COUNT;
+
+ if (thread_get_state(t.m_tmach, PPC_THREAD_STATE, &state, &count) != KERN_SUCCESS)
+ onThreadError("Unable to load thread state");
+ if (!t.m_lock)
+ t.m_curr.tstack = cast(void*) state.r[1];
+ t.m_reg[] = state.r[];
+ }
+ else version (PPC64)
+ {
+ ppc_thread_state64_t state = void;
+ mach_msg_type_number_t count = PPC_THREAD_STATE64_COUNT;
+
+ if (thread_get_state(t.m_tmach, PPC_THREAD_STATE64, &state, &count) != KERN_SUCCESS)
+ onThreadError("Unable to load thread state");
+ if (!t.m_lock)
+ t.m_curr.tstack = cast(void*) state.r[1];
+ t.m_reg[] = state.r[];
+ }
+ else
+ {
+ static assert(false, "Architecture not supported." );
+ }
+ }
+ else version (Posix)
+ {
+ if ( t.m_addr != pthread_self() )
+ {
+ if ( pthread_kill( t.m_addr, suspendSignalNumber ) != 0 )
+ {
+ if ( !t.isRunning )
+ {
+ Thread.remove( t );
+ return false;
+ }
+ onThreadError( "Unable to suspend thread" );
+ }
+ }
+ else if ( !t.m_lock )
+ {
+ t.m_curr.tstack = getStackTop();
+ }
+ }
+ return true;
+}
+
+/**
+ * Suspend all threads but the calling thread for "stop the world" garbage
+ * collection runs. This function may be called multiple times, and must
+ * be followed by a matching number of calls to thread_resumeAll before
+ * processing is resumed.
+ *
+ * Throws:
+ * ThreadError if the suspend operation fails for a running thread.
+ */
+extern (C) void thread_suspendAll() nothrow
+{
+ // NOTE: We've got an odd chicken & egg problem here, because while the GC
+ // is required to call thread_init before calling any other thread
+ // routines, thread_init may allocate memory which could in turn
+ // trigger a collection. Thus, thread_suspendAll, thread_scanAll,
+ // and thread_resumeAll must be callable before thread_init
+ // completes, with the assumption that no other GC memory has yet
+ // been allocated by the system, and thus there is no risk of losing
+ // data if the global thread list is empty. The check of
+ // Thread.sm_tbeg below is done to ensure thread_init has completed,
+ // and therefore that calling Thread.getThis will not result in an
+ // error. For the short time when Thread.sm_tbeg is null, there is
+ // no reason not to simply call the multithreaded code below, with
+ // the expectation that the foreach loop will never be entered.
+ if ( !multiThreadedFlag && Thread.sm_tbeg )
+ {
+ if ( ++suspendDepth == 1 )
+ suspend( Thread.getThis() );
+
+ return;
+ }
+
+ Thread.slock.lock_nothrow();
+ {
+ if ( ++suspendDepth > 1 )
+ return;
+
+ Thread.criticalRegionLock.lock_nothrow();
+ scope (exit) Thread.criticalRegionLock.unlock_nothrow();
+ size_t cnt;
+ Thread t = ThreadBase.sm_tbeg.toThread;
+ while (t)
+ {
+ auto tn = t.next.toThread;
+ if (suspend(t))
+ ++cnt;
+ t = tn;
+ }
+
+ version (Darwin)
+ {}
+ else version (Posix)
+ {
+ // subtract own thread
+ assert(cnt >= 1);
+ --cnt;
+ Lagain:
+ // wait for semaphore notifications
+ for (; cnt; --cnt)
+ {
+ while (sem_wait(&suspendCount) != 0)
+ {
+ if (errno != EINTR)
+ onThreadError("Unable to wait for semaphore");
+ errno = 0;
+ }
+ }
+ version (FreeBSD)
+ {
+ // avoid deadlocks, see Issue 13416
+ t = ThreadBase.sm_tbeg.toThread;
+ while (t)
+ {
+ auto tn = t.next;
+ if (t.m_suspendagain && suspend(t))
+ ++cnt;
+ t = tn.toThread;
+ }
+ if (cnt)
+ goto Lagain;
+ }
+ }
+ }
+}
+
+/**
+ * Resume the specified thread and unload stack and register information.
+ * If the supplied thread is the calling thread, stack and register
+ * information will be unloaded but the thread will not be resumed. If
+ * the resume operation fails and the thread is not running then it will
+ * be removed from the global thread list, otherwise an exception will be
+ * thrown.
+ *
+ * Params:
+ * t = The thread to resume.
+ *
+ * Throws:
+ * ThreadError if the resume fails for a running thread.
+ */
+private extern (D) void resume(ThreadBase _t) nothrow @nogc
+{
+ Thread t = _t.toThread;
+
+ version (Windows)
+ {
+ if ( t.m_addr != GetCurrentThreadId() && ResumeThread( t.m_hndl ) == 0xFFFFFFFF )
+ {
+ if ( !t.isRunning )
+ {
+ Thread.remove( t );
+ return;
+ }
+ onThreadError( "Unable to resume thread" );
+ }
+
+ if ( !t.m_lock )
+ t.m_curr.tstack = t.m_curr.bstack;
+ t.m_reg[0 .. $] = 0;
+ }
+ else version (Darwin)
+ {
+ if ( t.m_addr != pthread_self() && thread_resume( t.m_tmach ) != KERN_SUCCESS )
+ {
+ if ( !t.isRunning )
+ {
+ Thread.remove( t );
+ return;
+ }
+ onThreadError( "Unable to resume thread" );
+ }
+
+ if ( !t.m_lock )
+ t.m_curr.tstack = t.m_curr.bstack;
+ t.m_reg[0 .. $] = 0;
+ }
+ else version (Posix)
+ {
+ if ( t.m_addr != pthread_self() )
+ {
+ if ( pthread_kill( t.m_addr, resumeSignalNumber ) != 0 )
+ {
+ if ( !t.isRunning )
+ {
+ Thread.remove( t );
+ return;
+ }
+ onThreadError( "Unable to resume thread" );
+ }
+ }
+ else if ( !t.m_lock )
+ {
+ t.m_curr.tstack = t.m_curr.bstack;
+ }
+ }
+}
+
+
+/**
+ * Initializes the thread module. This function must be called by the
+ * garbage collector on startup and before any other thread routines
+ * are called.
+ */
+extern (C) void thread_init() @nogc
+{
+ // NOTE: If thread_init itself performs any allocations then the thread
+ // routines reserved for garbage collector use may be called while
+ // thread_init is being processed. However, since no memory should
+ // exist to be scanned at this point, it is sufficient for these
+ // functions to detect the condition and return immediately.
+
+ initLowlevelThreads();
+ Thread.initLocks();
+
+ // The Android VM runtime intercepts SIGUSR1 and apparently doesn't allow
+ // its signal handler to run, so swap the two signals on Android, since
+ // thread_resumeHandler does nothing.
+ version (Android) thread_setGCSignals(SIGUSR2, SIGUSR1);
+
+ version (Darwin)
+ {
+ // thread id different in forked child process
+ static extern(C) void initChildAfterFork()
+ {
+ auto thisThread = Thread.getThis();
+ thisThread.m_addr = pthread_self();
+ assert( thisThread.m_addr != thisThread.m_addr.init );
+ thisThread.m_tmach = pthread_mach_thread_np( thisThread.m_addr );
+ assert( thisThread.m_tmach != thisThread.m_tmach.init );
+ }
+ pthread_atfork(null, null, &initChildAfterFork);
+ }
+ else version (Posix)
+ {
+ int status;
+ sigaction_t suspend = void;
+ sigaction_t resume = void;
+
+ // This is a quick way to zero-initialize the structs without using
+ // memset or creating a link dependency on their static initializer.
+ (cast(byte*) &suspend)[0 .. sigaction_t.sizeof] = 0;
+ (cast(byte*) &resume)[0 .. sigaction_t.sizeof] = 0;
+
+ // NOTE: SA_RESTART indicates that system calls should restart if they
+ // are interrupted by a signal, but this is not available on all
+ // Posix systems, even those that support multithreading.
+ static if ( __traits( compiles, SA_RESTART ) )
+ suspend.sa_flags = SA_RESTART;
+
+ suspend.sa_handler = &thread_suspendHandler;
+ // NOTE: We want to ignore all signals while in this handler, so fill
+ // sa_mask to indicate this.
+ status = sigfillset( &suspend.sa_mask );
+ assert( status == 0 );
+
+ // NOTE: Since resumeSignalNumber should only be issued for threads within the
+ // suspend handler, we don't want this signal to trigger a
+ // restart.
+ resume.sa_flags = 0;
+ resume.sa_handler = &thread_resumeHandler;
+ // NOTE: We want to ignore all signals while in this handler, so fill
+ // sa_mask to indicate this.
+ status = sigfillset( &resume.sa_mask );
+ assert( status == 0 );
+
+ status = sigaction( suspendSignalNumber, &suspend, null );
+ assert( status == 0 );
+
+ status = sigaction( resumeSignalNumber, &resume, null );
+ assert( status == 0 );
+
+ status = sem_init( &suspendCount, 0, 0 );
+ assert( status == 0 );
+ }
+ if (typeid(Thread).initializer.ptr)
+ _mainThreadStore[] = typeid(Thread).initializer[];
+ Thread.sm_main = attachThread((cast(Thread)_mainThreadStore.ptr).__ctor());
+}
+
+private alias MainThreadStore = void[__traits(classInstanceSize, Thread)];
+package __gshared align(Thread.alignof) MainThreadStore _mainThreadStore;
+
+/**
+ * Terminates the thread module. No other thread routine may be called
+ * afterwards.
+ */
+extern (C) void thread_term() @nogc
+{
+ thread_term_tpl!(Thread)(_mainThreadStore);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Thread Entry Point and Signal Handlers
+///////////////////////////////////////////////////////////////////////////////
+
+
+version (Windows)
+{
+ private
+ {
+ //
+ // Entry point for Windows threads
+ //
+ extern (Windows) uint thread_entryPoint( void* arg ) nothrow
+ {
+ Thread obj = cast(Thread) arg;
+ assert( obj );
+
+ obj.initDataStorage();
+
+ Thread.setThis(obj);
+ Thread.add(obj);
+ scope (exit)
+ {
+ Thread.remove(obj);
+ obj.destroyDataStorage();
+ }
+ Thread.add(&obj.m_main);
+
+ // NOTE: No GC allocations may occur until the stack pointers have
+ // been set and Thread.getThis returns a valid reference to
+ // this thread object (this latter condition is not strictly
+ // necessary on Windows but it should be followed for the
+ // sake of consistency).
+
+ // TODO: Consider putting an auto exception object here (using
+ // alloca) forOutOfMemoryError plus something to track
+ // whether an exception is in-flight?
+
+ void append( Throwable t )
+ {
+ if ( obj.m_unhandled is null )
+ obj.m_unhandled = t;
+ else
+ {
+ Throwable last = obj.m_unhandled;
+ while ( last.next !is null )
+ last = last.next;
+ last.next = t;
+ }
+ }
+
+ version (D_InlineAsm_X86)
+ {
+ asm nothrow @nogc { fninit; }
+ }
+
+ try
+ {
+ rt_moduleTlsCtor();
+ try
+ {
+ obj.run();
+ }
+ catch ( Throwable t )
+ {
+ append( t );
+ }
+ rt_moduleTlsDtor();
+ }
+ catch ( Throwable t )
+ {
+ append( t );
+ }
+ return 0;
+ }
+
+
+ HANDLE GetCurrentThreadHandle() nothrow @nogc
+ {
+ const uint DUPLICATE_SAME_ACCESS = 0x00000002;
+
+ HANDLE curr = GetCurrentThread(),
+ proc = GetCurrentProcess(),
+ hndl;
+
+ DuplicateHandle( proc, curr, proc, &hndl, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ return hndl;
+ }
+ }
+}
+else version (Posix)
+{
+ private
+ {
+ import core.stdc.errno;
+ import core.sys.posix.semaphore;
+ import core.sys.posix.stdlib; // for malloc, valloc, free, atexit
+ import core.sys.posix.pthread;
+ import core.sys.posix.signal;
+ import core.sys.posix.time;
+
+ version (Darwin)
+ {
+ import core.sys.darwin.mach.thread_act;
+ import core.sys.darwin.pthread : pthread_mach_thread_np;
+ }
+
+ //
+ // Entry point for POSIX threads
+ //
+ extern (C) void* thread_entryPoint( void* arg ) nothrow
+ {
+ version (Shared)
+ {
+ Thread obj = cast(Thread)(cast(void**)arg)[0];
+ auto loadedLibraries = (cast(void**)arg)[1];
+ .free(arg);
+ }
+ else
+ {
+ Thread obj = cast(Thread)arg;
+ }
+ assert( obj );
+
+ // loadedLibraries need to be inherited from parent thread
+ // before initilizing GC for TLS (rt_tlsgc_init)
+ version (GNUShared)
+ {
+ externDFunc!("gcc.sections.inheritLoadedLibraries",
+ void function(void*) @nogc nothrow)(loadedLibraries);
+ }
+ else version (Shared)
+ {
+ externDFunc!("rt.sections_elf_shared.inheritLoadedLibraries",
+ void function(void*) @nogc nothrow)(loadedLibraries);
+ }
+
+ obj.initDataStorage();
+
+ atomicStore!(MemoryOrder.raw)(obj.m_isRunning, true);
+ Thread.setThis(obj); // allocates lazy TLS (see Issue 11981)
+ Thread.add(obj); // can only receive signals from here on
+ scope (exit)
+ {
+ Thread.remove(obj);
+ atomicStore!(MemoryOrder.raw)(obj.m_isRunning, false);
+ obj.destroyDataStorage();
+ }
+ Thread.add(&obj.m_main);
+
+ static extern (C) void thread_cleanupHandler( void* arg ) nothrow @nogc
+ {
+ Thread obj = cast(Thread) arg;
+ assert( obj );
+
+ // NOTE: If the thread terminated abnormally, just set it as
+ // not running and let thread_suspendAll remove it from
+ // the thread list. This is safer and is consistent
+ // with the Windows thread code.
+ atomicStore!(MemoryOrder.raw)(obj.m_isRunning,false);
+ }
+
+ // NOTE: Using void to skip the initialization here relies on
+ // knowledge of how pthread_cleanup is implemented. It may
+ // not be appropriate for all platforms. However, it does
+ // avoid the need to link the pthread module. If any
+ // implementation actually requires default initialization
+ // then pthread_cleanup should be restructured to maintain
+ // the current lack of a link dependency.
+ static if ( __traits( compiles, pthread_cleanup ) )
+ {
+ pthread_cleanup cleanup = void;
+ cleanup.push( &thread_cleanupHandler, cast(void*) obj );
+ }
+ else static if ( __traits( compiles, pthread_cleanup_push ) )
+ {
+ pthread_cleanup_push( &thread_cleanupHandler, cast(void*) obj );
+ }
+ else
+ {
+ static assert( false, "Platform not supported." );
+ }
+
+ // NOTE: No GC allocations may occur until the stack pointers have
+ // been set and Thread.getThis returns a valid reference to
+ // this thread object (this latter condition is not strictly
+ // necessary on Windows but it should be followed for the
+ // sake of consistency).
+
+ // TODO: Consider putting an auto exception object here (using
+ // alloca) forOutOfMemoryError plus something to track
+ // whether an exception is in-flight?
+
+ void append( Throwable t )
+ {
+ if ( obj.m_unhandled is null )
+ obj.m_unhandled = t;
+ else
+ {
+ Throwable last = obj.m_unhandled;
+ while ( last.next !is null )
+ last = last.next;
+ last.next = t;
+ }
+ }
+ try
+ {
+ rt_moduleTlsCtor();
+ try
+ {
+ obj.run();
+ }
+ catch ( Throwable t )
+ {
+ append( t );
+ }
+ rt_moduleTlsDtor();
+ version (GNUShared)
+ {
+ externDFunc!("gcc.sections.cleanupLoadedLibraries",
+ void function() @nogc nothrow)();
+ }
+ else version (Shared)
+ {
+ externDFunc!("rt.sections_elf_shared.cleanupLoadedLibraries",
+ void function() @nogc nothrow)();
+ }
+ }
+ catch ( Throwable t )
+ {
+ append( t );
+ }
+
+ // NOTE: Normal cleanup is handled by scope(exit).
+
+ static if ( __traits( compiles, pthread_cleanup ) )
+ {
+ cleanup.pop( 0 );
+ }
+ else static if ( __traits( compiles, pthread_cleanup_push ) )
+ {
+ pthread_cleanup_pop( 0 );
+ }
+
+ return null;
+ }
+
+
+ //
+ // Used to track the number of suspended threads
+ //
+ __gshared sem_t suspendCount;
+
+
+ extern (C) void thread_suspendHandler( int sig ) nothrow
+ in
+ {
+ assert( sig == suspendSignalNumber );
+ }
+ do
+ {
+ void op(void* sp) nothrow
+ {
+ // NOTE: Since registers are being pushed and popped from the
+ // stack, any other stack data used by this function should
+ // be gone before the stack cleanup code is called below.
+ Thread obj = Thread.getThis();
+ assert(obj !is null);
+
+ if ( !obj.m_lock )
+ {
+ obj.m_curr.tstack = getStackTop();
+ }
+
+ sigset_t sigres = void;
+ int status;
+
+ status = sigfillset( &sigres );
+ assert( status == 0 );
+
+ status = sigdelset( &sigres, resumeSignalNumber );
+ assert( status == 0 );
+
+ version (FreeBSD) obj.m_suspendagain = false;
+ status = sem_post( &suspendCount );
+ assert( status == 0 );
+
+ sigsuspend( &sigres );
+
+ if ( !obj.m_lock )
+ {
+ obj.m_curr.tstack = obj.m_curr.bstack;
+ }
+ }
+
+ // avoid deadlocks on FreeBSD, see Issue 13416
+ version (FreeBSD)
+ {
+ auto obj = Thread.getThis();
+ if (THR_IN_CRITICAL(obj.m_addr))
+ {
+ obj.m_suspendagain = true;
+ if (sem_post(&suspendCount)) assert(0);
+ return;
+ }
+ }
+
+ callWithStackShell(&op);
+ }
+
+
+ extern (C) void thread_resumeHandler( int sig ) nothrow
+ in
+ {
+ assert( sig == resumeSignalNumber );
+ }
+ do
+ {
+
+ }
+
+ // HACK libthr internal (thr_private.h) macro, used to
+ // avoid deadlocks in signal handler, see Issue 13416
+ version (FreeBSD) bool THR_IN_CRITICAL(pthread_t p) nothrow @nogc
+ {
+ import core.sys.posix.config : c_long;
+ import core.sys.posix.sys.types : lwpid_t;
+
+ // If the begin of pthread would be changed in libthr (unlikely)
+ // we'll run into undefined behavior, compare with thr_private.h.
+ static struct pthread
+ {
+ c_long tid;
+ static struct umutex { lwpid_t owner; uint flags; uint[2] ceilings; uint[4] spare; }
+ umutex lock;
+ uint cycle;
+ int locklevel;
+ int critical_count;
+ // ...
+ }
+ auto priv = cast(pthread*)p;
+ return priv.locklevel > 0 || priv.critical_count > 0;
+ }
+ }
+}
+else
+{
+ // NOTE: This is the only place threading versions are checked. If a new
+ // version is added, the module code will need to be searched for
+ // places where version-specific code may be required. This can be
+ // easily accomlished by searching for 'Windows' or 'Posix'.
+ static assert( false, "Unknown threading implementation." );
+}
+
+//
+// exposed by compiler runtime
+//
+extern (C) void rt_moduleTlsCtor();
+extern (C) void rt_moduleTlsDtor();
+
+
+// regression test for Issue 13416
+version (FreeBSD) unittest
+{
+ static void loop()
+ {
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ auto thr = pthread_self();
+ foreach (i; 0 .. 50)
+ pthread_attr_get_np(thr, &attr);
+ pthread_attr_destroy(&attr);
+ }
+
+ auto thr = new Thread(&loop).start();
+ foreach (i; 0 .. 50)
+ {
+ thread_suspendAll();
+ thread_resumeAll();
+ }
+ thr.join();
+}
+
+version (DragonFlyBSD) unittest
+{
+ static void loop()
+ {
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ auto thr = pthread_self();
+ foreach (i; 0 .. 50)
+ pthread_attr_get_np(thr, &attr);
+ pthread_attr_destroy(&attr);
+ }
+
+ auto thr = new Thread(&loop).start();
+ foreach (i; 0 .. 50)
+ {
+ thread_suspendAll();
+ thread_resumeAll();
+ }
+ thr.join();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// lowlovel threading support
+///////////////////////////////////////////////////////////////////////////////
+
+private
+{
+ version (Windows):
+ // If the runtime is dynamically loaded as a DLL, there is a problem with
+ // threads still running when the DLL is supposed to be unloaded:
+ //
+ // - with the VC runtime starting with VS2015 (i.e. using the Universal CRT)
+ // a thread created with _beginthreadex increments the DLL reference count
+ // and decrements it when done, so that the DLL is no longer unloaded unless
+ // all the threads have terminated. With the DLL reference count held up
+ // by a thread that is only stopped by a signal from a static destructor or
+ // the termination of the runtime will cause the DLL to never be unloaded.
+ //
+ // - with the DigitalMars runtime and VC runtime up to VS2013, the thread
+ // continues to run, but crashes once the DLL is unloaded from memory as
+ // the code memory is no longer accessible. Stopping the threads is not possible
+ // from within the runtime termination as it is invoked from
+ // DllMain(DLL_PROCESS_DETACH) holding a lock that prevents threads from
+ // terminating.
+ //
+ // Solution: start a watchdog thread that keeps the DLL reference count above 0 and
+ // checks it periodically. If it is equal to 1 (plus the number of started threads), no
+ // external references to the DLL exist anymore, threads can be stopped
+ // and runtime termination and DLL unload can be invoked via FreeLibraryAndExitThread.
+ // Note: runtime termination is then performed by a different thread than at startup.
+ //
+ // Note: if the DLL is never unloaded, process termination kills all threads
+ // and signals their handles before unconditionally calling DllMain(DLL_PROCESS_DETACH).
+
+ import core.sys.windows.winbase : FreeLibraryAndExitThread, GetModuleHandleExW,
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
+ import core.sys.windows.windef : HMODULE;
+ import core.sys.windows.dll : dll_getRefCount;
+
+ version (CRuntime_Microsoft)
+ extern(C) extern __gshared ubyte msvcUsesUCRT; // from rt/msvc.d
+
+ /// set during termination of a DLL on Windows, i.e. while executing DllMain(DLL_PROCESS_DETACH)
+ public __gshared bool thread_DLLProcessDetaching;
+
+ __gshared HMODULE ll_dllModule;
+ __gshared ThreadID ll_dllMonitorThread;
+
+ int ll_countLowLevelThreadsWithDLLUnloadCallback() nothrow
+ {
+ lowlevelLock.lock_nothrow();
+ scope(exit) lowlevelLock.unlock_nothrow();
+
+ int cnt = 0;
+ foreach (i; 0 .. ll_nThreads)
+ if (ll_pThreads[i].cbDllUnload)
+ cnt++;
+ return cnt;
+ }
+
+ bool ll_dllHasExternalReferences() nothrow
+ {
+ version (CRuntime_DigitalMars)
+ enum internalReferences = 1; // only the watchdog thread
+ else
+ int internalReferences = msvcUsesUCRT ? 1 + ll_countLowLevelThreadsWithDLLUnloadCallback() : 1;
+
+ int refcnt = dll_getRefCount(ll_dllModule);
+ return refcnt > internalReferences;
+ }
+
+ private void monitorDLLRefCnt() nothrow
+ {
+ // this thread keeps the DLL alive until all external references are gone
+ while (ll_dllHasExternalReferences())
+ {
+ Thread.sleep(100.msecs);
+ }
+
+ // the current thread will be terminated below
+ ll_removeThread(GetCurrentThreadId());
+
+ for (;;)
+ {
+ ThreadID tid;
+ void delegate() nothrow cbDllUnload;
+ {
+ lowlevelLock.lock_nothrow();
+ scope(exit) lowlevelLock.unlock_nothrow();
+
+ foreach (i; 0 .. ll_nThreads)
+ if (ll_pThreads[i].cbDllUnload)
+ {
+ cbDllUnload = ll_pThreads[i].cbDllUnload;
+ tid = ll_pThreads[0].tid;
+ }
+ }
+ if (!cbDllUnload)
+ break;
+ cbDllUnload();
+ assert(!findLowLevelThread(tid));
+ }
+
+ FreeLibraryAndExitThread(ll_dllModule, 0);
+ }
+
+ int ll_getDLLRefCount() nothrow @nogc
+ {
+ if (!ll_dllModule &&
+ !GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ cast(const(wchar)*) &ll_getDLLRefCount, &ll_dllModule))
+ return -1;
+ return dll_getRefCount(ll_dllModule);
+ }
+
+ bool ll_startDLLUnloadThread() nothrow @nogc
+ {
+ int refcnt = ll_getDLLRefCount();
+ if (refcnt < 0)
+ return false; // not a dynamically loaded DLL
+
+ if (ll_dllMonitorThread !is ThreadID.init)
+ return true;
+
+ // if a thread is created from a DLL, the MS runtime (starting with VC2015) increments the DLL reference count
+ // to avoid the DLL being unloaded while the thread is still running. Mimick this behavior here for all
+ // runtimes not doing this
+ version (CRuntime_DigitalMars)
+ enum needRef = true;
+ else
+ bool needRef = !msvcUsesUCRT;
+
+ if (needRef)
+ {
+ HMODULE hmod;
+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, cast(const(wchar)*) &ll_getDLLRefCount, &hmod);
+ }
+
+ ll_dllMonitorThread = createLowLevelThread(() { monitorDLLRefCnt(); });
+ return ll_dllMonitorThread != ThreadID.init;
+ }
+}
+
+/**
+ * Create a thread not under control of the runtime, i.e. TLS module constructors are
+ * not run and the GC does not suspend it during a collection.
+ *
+ * Params:
+ * dg = delegate to execute in the created thread.
+ * stacksize = size of the stack of the created thread. The default of 0 will select the
+ * platform-specific default size.
+ * cbDllUnload = Windows only: if running in a dynamically loaded DLL, this delegate will be called
+ * if the DLL is supposed to be unloaded, but the thread is still running.
+ * The thread must be terminated via `joinLowLevelThread` by the callback.
+ *
+ * Returns: the platform specific thread ID of the new thread. If an error occurs, `ThreadID.init`
+ * is returned.
+ */
+ThreadID createLowLevelThread(void delegate() nothrow dg, uint stacksize = 0,
+ void delegate() nothrow cbDllUnload = null) nothrow @nogc
+{
+ void delegate() nothrow* context = cast(void delegate() nothrow*)malloc(dg.sizeof);
+ *context = dg;
+
+ ThreadID tid;
+ version (Windows)
+ {
+ // the thread won't start until after the DLL is unloaded
+ if (thread_DLLProcessDetaching)
+ return ThreadID.init;
+
+ static extern (Windows) uint thread_lowlevelEntry(void* ctx) nothrow
+ {
+ auto dg = *cast(void delegate() nothrow*)ctx;
+ free(ctx);
+
+ dg();
+ ll_removeThread(GetCurrentThreadId());
+ return 0;
+ }
+
+ // see Thread.start() for why thread is created in suspended state
+ HANDLE hThread = cast(HANDLE) _beginthreadex(null, stacksize, &thread_lowlevelEntry,
+ context, CREATE_SUSPENDED, &tid);
+ if (!hThread)
+ return ThreadID.init;
+ }
+
+ lowlevelLock.lock_nothrow();
+ scope(exit) lowlevelLock.unlock_nothrow();
+
+ ll_nThreads++;
+ ll_pThreads = cast(ll_ThreadData*)realloc(ll_pThreads, ll_ThreadData.sizeof * ll_nThreads);
+
+ version (Windows)
+ {
+ ll_pThreads[ll_nThreads - 1].tid = tid;
+ ll_pThreads[ll_nThreads - 1].cbDllUnload = cbDllUnload;
+ if (ResumeThread(hThread) == -1)
+ onThreadError("Error resuming thread");
+ CloseHandle(hThread);
+
+ if (cbDllUnload)
+ ll_startDLLUnloadThread();
+ }
+ else version (Posix)
+ {
+ static extern (C) void* thread_lowlevelEntry(void* ctx) nothrow
+ {
+ auto dg = *cast(void delegate() nothrow*)ctx;
+ free(ctx);
+
+ dg();
+ ll_removeThread(pthread_self());
+ return null;
+ }
+
+ size_t stksz = adjustStackSize(stacksize);
+
+ pthread_attr_t attr;
+
+ int rc;
+ if ((rc = pthread_attr_init(&attr)) != 0)
+ return ThreadID.init;
+ if (stksz && (rc = pthread_attr_setstacksize(&attr, stksz)) != 0)
+ return ThreadID.init;
+ if ((rc = pthread_create(&tid, &attr, &thread_lowlevelEntry, context)) != 0)
+ return ThreadID.init;
+ if ((rc = pthread_attr_destroy(&attr)) != 0)
+ return ThreadID.init;
+
+ ll_pThreads[ll_nThreads - 1].tid = tid;
+ }
+ return tid;
+}
+
+/**
+ * Wait for a thread created with `createLowLevelThread` to terminate.
+ *
+ * Note: In a Windows DLL, if this function is called via DllMain with
+ * argument DLL_PROCESS_DETACH, the thread is terminated forcefully
+ * without proper cleanup as a deadlock would happen otherwise.
+ *
+ * Params:
+ * tid = the thread ID returned by `createLowLevelThread`.
+ */
+void joinLowLevelThread(ThreadID tid) nothrow @nogc
+{
+ version (Windows)
+ {
+ HANDLE handle = OpenThreadHandle(tid);
+ if (!handle)
+ return;
+
+ if (thread_DLLProcessDetaching)
+ {
+ // When being called from DllMain/DLL_DETACH_PROCESS, threads cannot stop
+ // due to the loader lock being held by the current thread.
+ // On the other hand, the thread must not continue to run as it will crash
+ // if the DLL is unloaded. The best guess is to terminate it immediately.
+ TerminateThread(handle, 1);
+ WaitForSingleObject(handle, 10); // give it some time to terminate, but don't wait indefinitely
+ }
+ else
+ WaitForSingleObject(handle, INFINITE);
+ CloseHandle(handle);
+ }
+ else version (Posix)
+ {
+ if (pthread_join(tid, null) != 0)
+ onThreadError("Unable to join thread");
+ }
+}
+
+nothrow @nogc unittest
+{
+ struct TaskWithContect
+ {
+ shared int n = 0;
+ void run() nothrow
+ {
+ n.atomicOp!"+="(1);
+ }
+ }
+ TaskWithContect task;
+
+ ThreadID[8] tids;
+ for (int i = 0; i < tids.length; i++)
+ {
+ tids[i] = createLowLevelThread(&task.run);
+ assert(tids[i] != ThreadID.init);
+ }
+
+ for (int i = 0; i < tids.length; i++)
+ joinLowLevelThread(tids[i]);
+
+ assert(task.n == tids.length);
+}
+
+version (Posix)
+private size_t adjustStackSize(size_t sz) nothrow @nogc
+{
+ if (sz == 0)
+ return 0;
+
+ // stack size must be at least PTHREAD_STACK_MIN for most platforms.
+ if (PTHREAD_STACK_MIN > sz)
+ sz = PTHREAD_STACK_MIN;
+
+ version (CRuntime_Glibc)
+ {
+ // On glibc, TLS uses the top of the stack, so add its size to the requested size
+ version (GNU)
+ {
+ sz += externDFunc!("gcc.sections.elf.sizeOfTLS",
+ size_t function() @nogc nothrow)();
+ }
+ else
+ {
+ sz += externDFunc!("rt.sections_elf_shared.sizeOfTLS",
+ size_t function() @nogc nothrow)();
+ }
+ }
+
+ // stack size must be a multiple of PAGESIZE
+ sz = ((sz + PAGESIZE - 1) & ~(PAGESIZE - 1));
+
+ return sz;
+}
diff --git a/libphobos/libdruntime/core/thread/package.d b/libphobos/libdruntime/core/thread/package.d
new file mode 100644
index 0000000..71b0237
--- /dev/null
+++ b/libphobos/libdruntime/core/thread/package.d
@@ -0,0 +1,20 @@
+/**
+ * The thread module provides support for thread creation and management.
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2012.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
+ * Source: $(DRUNTIMESRC core/thread/package.d)
+ */
+
+module core.thread;
+
+public import core.time;
+public import core.thread.fiber;
+public import core.thread.osthread;
+public import core.thread.threadbase;
+public import core.thread.threadgroup;
+public import core.thread.types;
+public import core.thread.context;
diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d
new file mode 100644
index 0000000..0a8de10
--- /dev/null
+++ b/libphobos/libdruntime/core/thread/threadbase.d
@@ -0,0 +1,1386 @@
+/**
+ * The threadbase module provides OS-independent code
+ * for thread storage and management.
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2012.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
+ * Source: $(DRUNTIMESRC core/thread/osthread.d)
+ */
+
+/* NOTE: This file has been patched from the original DMD distribution to
+ * work with the GDC compiler.
+ */
+module core.thread.threadbase;
+
+import core.thread.context;
+import core.thread.types;
+import core.time;
+import core.sync.mutex;
+import core.stdc.stdlib : free, realloc;
+
+private
+{
+ import core.internal.traits : externDFunc;
+
+ // interface to rt.tlsgc
+ alias rt_tlsgc_init = externDFunc!("rt.tlsgc.init", void* function() nothrow @nogc);
+ alias rt_tlsgc_destroy = externDFunc!("rt.tlsgc.destroy", void function(void*) nothrow @nogc);
+
+ alias ScanDg = void delegate(void* pstart, void* pend) nothrow;
+ alias rt_tlsgc_scan =
+ externDFunc!("rt.tlsgc.scan", void function(void*, scope ScanDg) nothrow);
+
+ alias rt_tlsgc_processGCMarks =
+ externDFunc!("rt.tlsgc.processGCMarks", void function(void*, scope IsMarkedDg) nothrow);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Thread and Fiber Exceptions
+///////////////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Base class for thread exceptions.
+ */
+class ThreadException : Exception
+{
+ @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
+ {
+ super(msg, file, line, next);
+ }
+
+ @nogc @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)
+ {
+ super(msg, file, line, next);
+ }
+}
+
+
+/**
+* Base class for thread errors to be used for function inside GC when allocations are unavailable.
+*/
+class ThreadError : Error
+{
+ @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
+ {
+ super(msg, file, line, next);
+ }
+
+ @nogc @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)
+ {
+ super(msg, file, line, next);
+ }
+}
+
+private
+{
+ // Handling unaligned mutexes are not supported on all platforms, so we must
+ // ensure that the address of all shared data are appropriately aligned.
+ import core.internal.traits : classInstanceAlignment;
+
+ enum mutexAlign = classInstanceAlignment!Mutex;
+ enum mutexClassInstanceSize = __traits(classInstanceSize, Mutex);
+
+ alias swapContext = externDFunc!("core.thread.osthread.swapContext", void* function(void*) nothrow @nogc);
+
+ alias getStackBottom = externDFunc!("core.thread.osthread.getStackBottom", void* function() nothrow @nogc);
+ alias getStackTop = externDFunc!("core.thread.osthread.getStackTop", void* function() nothrow @nogc);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Thread
+///////////////////////////////////////////////////////////////////////////////
+
+
+class ThreadBase
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Initialization
+ ///////////////////////////////////////////////////////////////////////////
+
+ this(void function() fn, size_t sz = 0) @safe pure nothrow @nogc
+ in(fn)
+ {
+ this(sz);
+ m_call = fn;
+ }
+
+ this(void delegate() dg, size_t sz = 0) @safe pure nothrow @nogc
+ in(dg)
+ {
+ this(sz);
+ m_call = dg;
+ }
+
+ /**
+ * Cleans up any remaining resources used by this object.
+ */
+ package bool destructBeforeDtor() nothrow @nogc
+ {
+ destroyDataStorageIfAvail();
+
+ bool no_context = m_addr == m_addr.init;
+ bool not_registered = !next && !prev && (sm_tbeg !is this);
+
+ return (no_context || not_registered);
+ }
+
+ package void tlsGCdataInit() nothrow @nogc
+ {
+ m_tlsgcdata = rt_tlsgc_init();
+ }
+
+ package void initDataStorage() nothrow
+ {
+ assert(m_curr is &m_main);
+
+ m_main.bstack = getStackBottom();
+ m_main.tstack = m_main.bstack;
+ tlsGCdataInit();
+ }
+
+ package void destroyDataStorage() nothrow @nogc
+ {
+ rt_tlsgc_destroy(m_tlsgcdata);
+ m_tlsgcdata = null;
+ }
+
+ package void destroyDataStorageIfAvail() nothrow @nogc
+ {
+ if (m_tlsgcdata)
+ destroyDataStorage();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // General Actions
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Waits for this thread to complete. If the thread terminated as the
+ * result of an unhandled exception, this exception will be rethrown.
+ *
+ * Params:
+ * rethrow = Rethrow any unhandled exception which may have caused this
+ * thread to terminate.
+ *
+ * Throws:
+ * ThreadException if the operation fails.
+ * Any exception not handled by the joined thread.
+ *
+ * Returns:
+ * Any exception not handled by this thread if rethrow = false, null
+ * otherwise.
+ */
+ abstract Throwable join(bool rethrow = true);
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // General Properties
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Gets the OS identifier for this thread.
+ *
+ * Returns:
+ * If the thread hasn't been started yet, returns $(LREF ThreadID)$(D.init).
+ * Otherwise, returns the result of $(D GetCurrentThreadId) on Windows,
+ * and $(D pthread_self) on POSIX.
+ *
+ * The value is unique for the current process.
+ */
+ final @property ThreadID id() @safe @nogc
+ {
+ synchronized(this)
+ {
+ return m_addr;
+ }
+ }
+
+
+ /**
+ * Gets the user-readable label for this thread.
+ *
+ * Returns:
+ * The name of this thread.
+ */
+ final @property string name() @safe @nogc
+ {
+ synchronized(this)
+ {
+ return m_name;
+ }
+ }
+
+
+ /**
+ * Sets the user-readable label for this thread.
+ *
+ * Params:
+ * val = The new name of this thread.
+ */
+ final @property void name(string val) @safe @nogc
+ {
+ synchronized(this)
+ {
+ m_name = val;
+ }
+ }
+
+
+ /**
+ * Gets the daemon status for this thread. While the runtime will wait for
+ * all normal threads to complete before tearing down the process, daemon
+ * threads are effectively ignored and thus will not prevent the process
+ * from terminating. In effect, daemon threads will be terminated
+ * automatically by the OS when the process exits.
+ *
+ * Returns:
+ * true if this is a daemon thread.
+ */
+ final @property bool isDaemon() @safe @nogc
+ {
+ synchronized(this)
+ {
+ return m_isDaemon;
+ }
+ }
+
+
+ /**
+ * Sets the daemon status for this thread. While the runtime will wait for
+ * all normal threads to complete before tearing down the process, daemon
+ * threads are effectively ignored and thus will not prevent the process
+ * from terminating. In effect, daemon threads will be terminated
+ * automatically by the OS when the process exits.
+ *
+ * Params:
+ * val = The new daemon status for this thread.
+ */
+ final @property void isDaemon(bool val) @safe @nogc
+ {
+ synchronized(this)
+ {
+ m_isDaemon = val;
+ }
+ }
+
+ /**
+ * Tests whether this thread is the main thread, i.e. the thread
+ * that initialized the runtime
+ *
+ * Returns:
+ * true if the thread is the main thread
+ */
+ final @property bool isMainThread() nothrow @nogc
+ {
+ return this is sm_main;
+ }
+
+ /**
+ * Tests whether this thread is running.
+ *
+ * Returns:
+ * true if the thread is running, false if not.
+ */
+ @property bool isRunning() nothrow @nogc
+ {
+ if (m_addr == m_addr.init)
+ return false;
+
+ return true;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Thread Accessors
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Provides a reference to the calling thread.
+ *
+ * Returns:
+ * The thread object representing the calling thread. The result of
+ * deleting this object is undefined. If the current thread is not
+ * attached to the runtime, a null reference is returned.
+ */
+ static ThreadBase getThis() @safe nothrow @nogc
+ {
+ // NOTE: This function may not be called until thread_init has
+ // completed. See thread_suspendAll for more information
+ // on why this might occur.
+ version (GNU) pragma(inline, false);
+ return sm_this;
+ }
+
+
+ /**
+ * Provides a list of all threads currently being tracked by the system.
+ * Note that threads in the returned array might no longer run (see
+ * $(D ThreadBase.)$(LREF isRunning)).
+ *
+ * Returns:
+ * An array containing references to all threads currently being
+ * tracked by the system. The result of deleting any contained
+ * objects is undefined.
+ */
+ static ThreadBase[] getAll()
+ {
+ static void resize(ref ThreadBase[] buf, size_t nlen)
+ {
+ buf.length = nlen;
+ }
+ return getAllImpl!resize();
+ }
+
+
+ /**
+ * Operates on all threads currently being tracked by the system. The
+ * result of deleting any Thread object is undefined.
+ * Note that threads passed to the callback might no longer run (see
+ * $(D ThreadBase.)$(LREF isRunning)).
+ *
+ * Params:
+ * dg = The supplied code as a delegate.
+ *
+ * Returns:
+ * Zero if all elemented are visited, nonzero if not.
+ */
+ static int opApply(scope int delegate(ref ThreadBase) dg)
+ {
+ static void resize(ref ThreadBase[] buf, size_t nlen)
+ {
+ import core.exception: onOutOfMemoryError;
+
+ auto newBuf = cast(ThreadBase*)realloc(buf.ptr, nlen * size_t.sizeof);
+ if (newBuf is null) onOutOfMemoryError();
+ buf = newBuf[0 .. nlen];
+ }
+ auto buf = getAllImpl!resize;
+ scope(exit) if (buf.ptr) free(buf.ptr);
+
+ foreach (t; buf)
+ {
+ if (auto res = dg(t))
+ return res;
+ }
+ return 0;
+ }
+
+ private static ThreadBase[] getAllImpl(alias resize)()
+ {
+ import core.atomic;
+
+ ThreadBase[] buf;
+ while (true)
+ {
+ immutable len = atomicLoad!(MemoryOrder.raw)(*cast(shared)&sm_tlen);
+ resize(buf, len);
+ assert(buf.length == len);
+ synchronized (slock)
+ {
+ if (len == sm_tlen)
+ {
+ size_t pos;
+ for (ThreadBase t = sm_tbeg; t; t = t.next)
+ buf[pos++] = t;
+ return buf;
+ }
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Actions on Calling Thread
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Forces a context switch to occur away from the calling thread.
+ */
+ private static void yield() @nogc nothrow
+ {
+ thread_yield();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Stuff That Should Go Away
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ //
+ // Initializes a thread object which has no associated executable function.
+ // This is used for the main thread initialized in thread_init().
+ //
+ package this(size_t sz = 0) @safe pure nothrow @nogc
+ {
+ m_sz = sz;
+ m_curr = &m_main;
+ }
+
+ //
+ // Thread entry point. Invokes the function or delegate passed on
+ // construction (if any).
+ //
+ package final void run()
+ {
+ m_call();
+ }
+
+package:
+
+ //
+ // Local storage
+ //
+ static ThreadBase sm_this;
+
+
+ //
+ // Main process thread
+ //
+ __gshared ThreadBase sm_main;
+
+
+ //
+ // Standard thread data
+ //
+ ThreadID m_addr;
+ Callable m_call;
+ string m_name;
+ size_t m_sz;
+ bool m_isDaemon;
+ bool m_isInCriticalRegion;
+ Throwable m_unhandled;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Storage of Active Thread
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ //
+ // Sets a thread-local reference to the current thread object.
+ //
+ package static void setThis(ThreadBase t) nothrow @nogc
+ {
+ sm_this = t;
+ }
+
+package(core.thread):
+
+ StackContext m_main;
+ StackContext* m_curr;
+ bool m_lock;
+ private void* m_tlsgcdata;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Thread Context and GC Scanning Support
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ final void pushContext(StackContext* c) nothrow @nogc
+ in
+ {
+ assert(!c.within);
+ }
+ do
+ {
+ m_curr.ehContext = swapContext(c.ehContext);
+ c.within = m_curr;
+ m_curr = c;
+ }
+
+
+ final void popContext() nothrow @nogc
+ in
+ {
+ assert(m_curr && m_curr.within);
+ }
+ do
+ {
+ StackContext* c = m_curr;
+ m_curr = c.within;
+ c.ehContext = swapContext(m_curr.ehContext);
+ c.within = null;
+ }
+
+ private final StackContext* topContext() nothrow @nogc
+ in(m_curr)
+ {
+ return m_curr;
+ }
+
+
+package(core.thread):
+ ///////////////////////////////////////////////////////////////////////////
+ // GC Scanning Support
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ // NOTE: The GC scanning process works like so:
+ //
+ // 1. Suspend all threads.
+ // 2. Scan the stacks of all suspended threads for roots.
+ // 3. Resume all threads.
+ //
+ // Step 1 and 3 require a list of all threads in the system, while
+ // step 2 requires a list of all thread stacks (each represented by
+ // a Context struct). Traditionally, there was one stack per thread
+ // and the Context structs were not necessary. However, Fibers have
+ // changed things so that each thread has its own 'main' stack plus
+ // an arbitrary number of nested stacks (normally referenced via
+ // m_curr). Also, there may be 'free-floating' stacks in the system,
+ // which are Fibers that are not currently executing on any specific
+ // thread but are still being processed and still contain valid
+ // roots.
+ //
+ // To support all of this, the Context struct has been created to
+ // represent a stack range, and a global list of Context structs has
+ // been added to enable scanning of these stack ranges. The lifetime
+ // (and presence in the Context list) of a thread's 'main' stack will
+ // be equivalent to the thread's lifetime. So the Ccontext will be
+ // added to the list on thread entry, and removed from the list on
+ // thread exit (which is essentially the same as the presence of a
+ // Thread object in its own global list). The lifetime of a Fiber's
+ // context, however, will be tied to the lifetime of the Fiber object
+ // itself, and Fibers are expected to add/remove their Context struct
+ // on construction/deletion.
+
+
+ //
+ // All use of the global thread lists/array should synchronize on this lock.
+ //
+ // Careful as the GC acquires this lock after the GC lock to suspend all
+ // threads any GC usage with slock held can result in a deadlock through
+ // lock order inversion.
+ @property static Mutex slock() nothrow @nogc
+ {
+ return cast(Mutex)_slock.ptr;
+ }
+
+ @property static Mutex criticalRegionLock() nothrow @nogc
+ {
+ return cast(Mutex)_criticalRegionLock.ptr;
+ }
+
+ __gshared align(mutexAlign) void[mutexClassInstanceSize] _slock;
+ __gshared align(mutexAlign) void[mutexClassInstanceSize] _criticalRegionLock;
+
+ static void initLocks() @nogc
+ {
+ _slock[] = typeid(Mutex).initializer[];
+ (cast(Mutex)_slock.ptr).__ctor();
+
+ _criticalRegionLock[] = typeid(Mutex).initializer[];
+ (cast(Mutex)_criticalRegionLock.ptr).__ctor();
+ }
+
+ static void termLocks() @nogc
+ {
+ (cast(Mutex)_slock.ptr).__dtor();
+ (cast(Mutex)_criticalRegionLock.ptr).__dtor();
+ }
+
+ __gshared StackContext* sm_cbeg;
+
+ __gshared ThreadBase sm_tbeg;
+ __gshared size_t sm_tlen;
+
+ // can't use core.internal.util.array in public code
+ __gshared ThreadBase* pAboutToStart;
+ __gshared size_t nAboutToStart;
+
+ //
+ // Used for ordering threads in the global thread list.
+ //
+ ThreadBase prev;
+ ThreadBase next;
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Global Context List Operations
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ //
+ // Add a context to the global context list.
+ //
+ static void add(StackContext* c) nothrow @nogc
+ in
+ {
+ assert(c);
+ assert(!c.next && !c.prev);
+ }
+ do
+ {
+ slock.lock_nothrow();
+ scope(exit) slock.unlock_nothrow();
+ assert(!suspendDepth); // must be 0 b/c it's only set with slock held
+
+ if (sm_cbeg)
+ {
+ c.next = sm_cbeg;
+ sm_cbeg.prev = c;
+ }
+ sm_cbeg = c;
+ }
+
+ //
+ // Remove a context from the global context list.
+ //
+ // This assumes slock being acquired. This isn't done here to
+ // avoid double locking when called from remove(Thread)
+ static void remove(StackContext* c) nothrow @nogc
+ in
+ {
+ assert(c);
+ assert(c.next || c.prev);
+ }
+ do
+ {
+ if (c.prev)
+ c.prev.next = c.next;
+ if (c.next)
+ c.next.prev = c.prev;
+ if (sm_cbeg == c)
+ sm_cbeg = c.next;
+ // NOTE: Don't null out c.next or c.prev because opApply currently
+ // follows c.next after removing a node. This could be easily
+ // addressed by simply returning the next node from this
+ // function, however, a context should never be re-added to the
+ // list anyway and having next and prev be non-null is a good way
+ // to ensure that.
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Global Thread List Operations
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ //
+ // Add a thread to the global thread list.
+ //
+ static void add(ThreadBase t, bool rmAboutToStart = true) nothrow @nogc
+ in
+ {
+ assert(t);
+ assert(!t.next && !t.prev);
+ }
+ do
+ {
+ slock.lock_nothrow();
+ scope(exit) slock.unlock_nothrow();
+ assert(t.isRunning); // check this with slock to ensure pthread_create already returned
+ assert(!suspendDepth); // must be 0 b/c it's only set with slock held
+
+ if (rmAboutToStart)
+ {
+ size_t idx = -1;
+ foreach (i, thr; pAboutToStart[0 .. nAboutToStart])
+ {
+ if (thr is t)
+ {
+ idx = i;
+ break;
+ }
+ }
+ assert(idx != -1);
+ import core.stdc.string : memmove;
+ memmove(pAboutToStart + idx, pAboutToStart + idx + 1, size_t.sizeof * (nAboutToStart - idx - 1));
+ pAboutToStart =
+ cast(ThreadBase*)realloc(pAboutToStart, size_t.sizeof * --nAboutToStart);
+ }
+
+ if (sm_tbeg)
+ {
+ t.next = sm_tbeg;
+ sm_tbeg.prev = t;
+ }
+ sm_tbeg = t;
+ ++sm_tlen;
+ }
+
+
+ //
+ // Remove a thread from the global thread list.
+ //
+ static void remove(ThreadBase t) nothrow @nogc
+ in
+ {
+ assert(t);
+ }
+ do
+ {
+ // Thread was already removed earlier, might happen b/c of thread_detachInstance
+ if (!t.next && !t.prev && (sm_tbeg !is t))
+ return;
+
+ slock.lock_nothrow();
+ {
+ // NOTE: When a thread is removed from the global thread list its
+ // main context is invalid and should be removed as well.
+ // It is possible that t.m_curr could reference more
+ // than just the main context if the thread exited abnormally
+ // (if it was terminated), but we must assume that the user
+ // retains a reference to them and that they may be re-used
+ // elsewhere. Therefore, it is the responsibility of any
+ // object that creates contexts to clean them up properly
+ // when it is done with them.
+ remove(&t.m_main);
+
+ if (t.prev)
+ t.prev.next = t.next;
+ if (t.next)
+ t.next.prev = t.prev;
+ if (sm_tbeg is t)
+ sm_tbeg = t.next;
+ t.prev = t.next = null;
+ --sm_tlen;
+ }
+ // NOTE: Don't null out t.next or t.prev because opApply currently
+ // follows t.next after removing a node. This could be easily
+ // addressed by simply returning the next node from this
+ // function, however, a thread should never be re-added to the
+ // list anyway and having next and prev be non-null is a good way
+ // to ensure that.
+ slock.unlock_nothrow();
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// GC Support Routines
+///////////////////////////////////////////////////////////////////////////////
+
+private alias attachThread = externDFunc!("core.thread.osthread.attachThread", ThreadBase function(ThreadBase) @nogc nothrow);
+
+extern (C) void _d_monitordelete_nogc(Object h) @nogc;
+
+/**
+ * Terminates the thread module. No other thread routine may be called
+ * afterwards.
+ */
+package void thread_term_tpl(ThreadT, MainThreadStore)(ref MainThreadStore _mainThreadStore) @nogc
+{
+ assert(_mainThreadStore.ptr is cast(void*) ThreadBase.sm_main);
+
+ // destruct manually as object.destroy is not @nogc
+ (cast(ThreadT) cast(void*) ThreadBase.sm_main).__dtor();
+ _d_monitordelete_nogc(ThreadBase.sm_main);
+ if (typeid(ThreadT).initializer.ptr)
+ _mainThreadStore[] = typeid(ThreadT).initializer[];
+ else
+ (cast(ubyte[])_mainThreadStore)[] = 0;
+ ThreadBase.sm_main = null;
+
+ assert(ThreadBase.sm_tbeg && ThreadBase.sm_tlen == 1);
+ assert(!ThreadBase.nAboutToStart);
+ if (ThreadBase.pAboutToStart) // in case realloc(p, 0) doesn't return null
+ {
+ free(ThreadBase.pAboutToStart);
+ ThreadBase.pAboutToStart = null;
+ }
+ ThreadBase.termLocks();
+ termLowlevelThreads();
+}
+
+
+/**
+ *
+ */
+extern (C) bool thread_isMainThread() nothrow @nogc
+{
+ return ThreadBase.getThis() is ThreadBase.sm_main;
+}
+
+
+/**
+ * Registers the calling thread for use with the D Runtime. If this routine
+ * is called for a thread which is already registered, no action is performed.
+ *
+ * NOTE: This routine does not run thread-local static constructors when called.
+ * If full functionality as a D thread is desired, the following function
+ * must be called after thread_attachThis:
+ *
+ * extern (C) void rt_moduleTlsCtor();
+ */
+package ThreadT thread_attachThis_tpl(ThreadT)()
+{
+ if (auto t = ThreadT.getThis())
+ return t;
+
+ return cast(ThreadT) attachThread(new ThreadT());
+}
+
+
+/**
+ * Deregisters the calling thread from use with the runtime. If this routine
+ * is called for a thread which is not registered, the result is undefined.
+ *
+ * NOTE: This routine does not run thread-local static destructors when called.
+ * If full functionality as a D thread is desired, the following function
+ * must be called after thread_detachThis, particularly if the thread is
+ * being detached at some indeterminate time before program termination:
+ *
+ * $(D extern(C) void rt_moduleTlsDtor();)
+ */
+extern (C) void thread_detachThis() nothrow @nogc
+{
+ if (auto t = ThreadBase.getThis())
+ ThreadBase.remove(t);
+}
+
+
+/**
+ * Deregisters the given thread from use with the runtime. If this routine
+ * is called for a thread which is not registered, the result is undefined.
+ *
+ * NOTE: This routine does not run thread-local static destructors when called.
+ * If full functionality as a D thread is desired, the following function
+ * must be called by the detached thread, particularly if the thread is
+ * being detached at some indeterminate time before program termination:
+ *
+ * $(D extern(C) void rt_moduleTlsDtor();)
+ */
+extern (C) void thread_detachByAddr(ThreadID addr)
+{
+ if (auto t = thread_findByAddr(addr))
+ ThreadBase.remove(t);
+}
+
+
+/// ditto
+extern (C) void thread_detachInstance(ThreadBase t) nothrow @nogc
+{
+ ThreadBase.remove(t);
+}
+
+
+/**
+ * Search the list of all threads for a thread with the given thread identifier.
+ *
+ * Params:
+ * addr = The thread identifier to search for.
+ * Returns:
+ * The thread object associated with the thread identifier, null if not found.
+ */
+static ThreadBase thread_findByAddr(ThreadID addr)
+{
+ ThreadBase.slock.lock_nothrow();
+ scope(exit) ThreadBase.slock.unlock_nothrow();
+
+ // also return just spawned thread so that
+ // DLL_THREAD_ATTACH knows it's a D thread
+ foreach (t; ThreadBase.pAboutToStart[0 .. ThreadBase.nAboutToStart])
+ if (t.m_addr == addr)
+ return t;
+
+ foreach (t; ThreadBase)
+ if (t.m_addr == addr)
+ return t;
+
+ return null;
+}
+
+
+/**
+ * Sets the current thread to a specific reference. Only to be used
+ * when dealing with externally-created threads (in e.g. C code).
+ * The primary use of this function is when ThreadBase.getThis() must
+ * return a sensible value in, for example, TLS destructors. In
+ * other words, don't touch this unless you know what you're doing.
+ *
+ * Params:
+ * t = A reference to the current thread. May be null.
+ */
+extern (C) void thread_setThis(ThreadBase t) nothrow @nogc
+{
+ ThreadBase.setThis(t);
+}
+
+
+/**
+ * Joins all non-daemon threads that are currently running. This is done by
+ * performing successive scans through the thread list until a scan consists
+ * of only daemon threads.
+ */
+extern (C) void thread_joinAll()
+{
+ Lagain:
+ ThreadBase.slock.lock_nothrow();
+ // wait for just spawned threads
+ if (ThreadBase.nAboutToStart)
+ {
+ ThreadBase.slock.unlock_nothrow();
+ ThreadBase.yield();
+ goto Lagain;
+ }
+
+ // join all non-daemon threads, the main thread is also a daemon
+ auto t = ThreadBase.sm_tbeg;
+ while (t)
+ {
+ if (!t.isRunning)
+ {
+ auto tn = t.next;
+ ThreadBase.remove(t);
+ t = tn;
+ }
+ else if (t.isDaemon)
+ {
+ t = t.next;
+ }
+ else
+ {
+ ThreadBase.slock.unlock_nothrow();
+ t.join(); // might rethrow
+ goto Lagain; // must restart iteration b/c of unlock
+ }
+ }
+ ThreadBase.slock.unlock_nothrow();
+}
+
+
+/**
+ * Performs intermediate shutdown of the thread module.
+ */
+shared static ~this()
+{
+ // NOTE: The functionality related to garbage collection must be minimally
+ // operable after this dtor completes. Therefore, only minimal
+ // cleanup may occur.
+ auto t = ThreadBase.sm_tbeg;
+ while (t)
+ {
+ auto tn = t.next;
+ if (!t.isRunning)
+ ThreadBase.remove(t);
+ t = tn;
+ }
+}
+
+// Used for needLock below.
+package __gshared bool multiThreadedFlag = false;
+
+// Used for suspendAll/resumeAll below.
+package __gshared uint suspendDepth = 0;
+
+private alias resume = externDFunc!("core.thread.osthread.resume", void function(ThreadBase) nothrow @nogc);
+
+/**
+ * Resume all threads but the calling thread for "stop the world" garbage
+ * collection runs. This function must be called once for each preceding
+ * call to thread_suspendAll before the threads are actually resumed.
+ *
+ * In:
+ * This routine must be preceded by a call to thread_suspendAll.
+ *
+ * Throws:
+ * ThreadError if the resume operation fails for a running thread.
+ */
+extern (C) void thread_resumeAll() nothrow
+in
+{
+ assert(suspendDepth > 0);
+}
+do
+{
+ // NOTE: See thread_suspendAll for the logic behind this.
+ if (!multiThreadedFlag && ThreadBase.sm_tbeg)
+ {
+ if (--suspendDepth == 0)
+ resume(ThreadBase.getThis());
+ return;
+ }
+
+ scope(exit) ThreadBase.slock.unlock_nothrow();
+ {
+ if (--suspendDepth > 0)
+ return;
+
+ for (ThreadBase t = ThreadBase.sm_tbeg; t; t = t.next)
+ {
+ // NOTE: We do not need to care about critical regions at all
+ // here. thread_suspendAll takes care of everything.
+ resume(t);
+ }
+ }
+}
+
+/**
+ * Indicates the kind of scan being performed by $(D thread_scanAllType).
+ */
+enum ScanType
+{
+ stack, /// The stack and/or registers are being scanned.
+ tls, /// TLS data is being scanned.
+}
+
+alias ScanAllThreadsFn = void delegate(void*, void*) nothrow; /// The scanning function.
+alias ScanAllThreadsTypeFn = void delegate(ScanType, void*, void*) nothrow; /// ditto
+
+/**
+ * The main entry point for garbage collection. The supplied delegate
+ * will be passed ranges representing both stack and register values.
+ *
+ * Params:
+ * scan = The scanner function. It should scan from p1 through p2 - 1.
+ *
+ * In:
+ * This routine must be preceded by a call to thread_suspendAll.
+ */
+extern (C) void thread_scanAllType(scope ScanAllThreadsTypeFn scan) nothrow
+in
+{
+ assert(suspendDepth > 0);
+}
+do
+{
+ callWithStackShell(sp => scanAllTypeImpl(scan, sp));
+}
+
+package alias callWithStackShellDg = void delegate(void* sp) nothrow;
+private alias callWithStackShell = externDFunc!("core.thread.osthread.callWithStackShell", void function(scope callWithStackShellDg) nothrow);
+
+private void scanAllTypeImpl(scope ScanAllThreadsTypeFn scan, void* curStackTop) nothrow
+{
+ ThreadBase thisThread = null;
+ void* oldStackTop = null;
+
+ if (ThreadBase.sm_tbeg)
+ {
+ thisThread = ThreadBase.getThis();
+ if (!thisThread.m_lock)
+ {
+ oldStackTop = thisThread.m_curr.tstack;
+ thisThread.m_curr.tstack = curStackTop;
+ }
+ }
+
+ scope(exit)
+ {
+ if (ThreadBase.sm_tbeg)
+ {
+ if (!thisThread.m_lock)
+ {
+ thisThread.m_curr.tstack = oldStackTop;
+ }
+ }
+ }
+
+ // NOTE: Synchronizing on ThreadBase.slock is not needed because this
+ // function may only be called after all other threads have
+ // been suspended from within the same lock.
+ if (ThreadBase.nAboutToStart)
+ scan(ScanType.stack, ThreadBase.pAboutToStart, ThreadBase.pAboutToStart + ThreadBase.nAboutToStart);
+
+ for (StackContext* c = ThreadBase.sm_cbeg; c; c = c.next)
+ {
+ static if (isStackGrowingDown)
+ {
+ assert(c.tstack <= c.bstack, "stack bottom can't be less than top");
+
+ // NOTE: We can't index past the bottom of the stack
+ // so don't do the "+1" if isStackGrowingDown.
+ if (c.tstack && c.tstack < c.bstack)
+ scan(ScanType.stack, c.tstack, c.bstack);
+ }
+ else
+ {
+ assert(c.bstack <= c.tstack, "stack top can't be less than bottom");
+
+ if (c.bstack && c.bstack < c.tstack)
+ scan(ScanType.stack, c.bstack, c.tstack + 1);
+ }
+ }
+
+ for (ThreadBase t = ThreadBase.sm_tbeg; t; t = t.next)
+ {
+ version (Windows)
+ {
+ // Ideally, we'd pass ScanType.regs or something like that, but this
+ // would make portability annoying because it only makes sense on Windows.
+ scanWindowsOnly(scan, t);
+ }
+
+ if (t.m_tlsgcdata !is null)
+ rt_tlsgc_scan(t.m_tlsgcdata, (p1, p2) => scan(ScanType.tls, p1, p2));
+ }
+}
+
+version (Windows)
+{
+ // Currently scanWindowsOnly can't be handled properly by externDFunc
+ // https://github.com/dlang/druntime/pull/3135#issuecomment-643673218
+ pragma(mangle, "_D4core6thread8osthread15scanWindowsOnlyFNbMDFNbEQBvQBt10threadbase8ScanTypePvQcZvCQDdQDbQBi10ThreadBaseZv")
+ private extern (D) void scanWindowsOnly(scope ScanAllThreadsTypeFn scan, ThreadBase) nothrow;
+}
+
+/**
+ * The main entry point for garbage collection. The supplied delegate
+ * will be passed ranges representing both stack and register values.
+ *
+ * Params:
+ * scan = The scanner function. It should scan from p1 through p2 - 1.
+ *
+ * In:
+ * This routine must be preceded by a call to thread_suspendAll.
+ */
+extern (C) void thread_scanAll(scope ScanAllThreadsFn scan) nothrow
+{
+ thread_scanAllType((type, p1, p2) => scan(p1, p2));
+}
+
+private alias thread_yield = externDFunc!("core.thread.osthread.thread_yield", void function() @nogc nothrow);
+
+/**
+ * Signals that the code following this call is a critical region. Any code in
+ * this region must finish running before the calling thread can be suspended
+ * by a call to thread_suspendAll.
+ *
+ * This function is, in particular, meant to help maintain garbage collector
+ * invariants when a lock is not used.
+ *
+ * A critical region is exited with thread_exitCriticalRegion.
+ *
+ * $(RED Warning):
+ * Using critical regions is extremely error-prone. For instance, using locks
+ * inside a critical region can easily result in a deadlock when another thread
+ * holding the lock already got suspended.
+ *
+ * The term and concept of a 'critical region' comes from
+ * $(LINK2 https://github.com/mono/mono/blob/521f4a198e442573c400835ef19bbb36b60b0ebb/mono/metadata/sgen-gc.h#L925, Mono's SGen garbage collector).
+ *
+ * In:
+ * The calling thread must be attached to the runtime.
+ */
+extern (C) void thread_enterCriticalRegion() @nogc
+in
+{
+ assert(ThreadBase.getThis());
+}
+do
+{
+ synchronized (ThreadBase.criticalRegionLock)
+ ThreadBase.getThis().m_isInCriticalRegion = true;
+}
+
+
+/**
+ * Signals that the calling thread is no longer in a critical region. Following
+ * a call to this function, the thread can once again be suspended.
+ *
+ * In:
+ * The calling thread must be attached to the runtime.
+ */
+extern (C) void thread_exitCriticalRegion() @nogc
+in
+{
+ assert(ThreadBase.getThis());
+}
+do
+{
+ synchronized (ThreadBase.criticalRegionLock)
+ ThreadBase.getThis().m_isInCriticalRegion = false;
+}
+
+
+/**
+ * Returns true if the current thread is in a critical region; otherwise, false.
+ *
+ * In:
+ * The calling thread must be attached to the runtime.
+ */
+extern (C) bool thread_inCriticalRegion() @nogc
+in
+{
+ assert(ThreadBase.getThis());
+}
+do
+{
+ synchronized (ThreadBase.criticalRegionLock)
+ return ThreadBase.getThis().m_isInCriticalRegion;
+}
+
+
+/**
+* A callback for thread errors in D during collections. Since an allocation is not possible
+* a preallocated ThreadError will be used as the Error instance
+*
+* Returns:
+* never returns
+* Throws:
+* ThreadError.
+*/
+package void onThreadError(string msg) nothrow @nogc
+{
+ __gshared ThreadError error = new ThreadError(null);
+ error.msg = msg;
+ error.next = null;
+ import core.exception : SuppressTraceInfo;
+ error.info = SuppressTraceInfo.instance;
+ throw error;
+}
+
+unittest
+{
+ assert(!thread_inCriticalRegion());
+
+ {
+ thread_enterCriticalRegion();
+
+ scope (exit)
+ thread_exitCriticalRegion();
+
+ assert(thread_inCriticalRegion());
+ }
+
+ assert(!thread_inCriticalRegion());
+}
+
+
+/**
+ * Indicates whether an address has been marked by the GC.
+ */
+enum IsMarked : int
+{
+ no, /// Address is not marked.
+ yes, /// Address is marked.
+ unknown, /// Address is not managed by the GC.
+}
+
+alias IsMarkedDg = int delegate(void* addr) nothrow; /// The isMarked callback function.
+
+/**
+ * This routine allows the runtime to process any special per-thread handling
+ * for the GC. This is needed for taking into account any memory that is
+ * referenced by non-scanned pointers but is about to be freed. That currently
+ * means the array append cache.
+ *
+ * Params:
+ * isMarked = The function used to check if $(D addr) is marked.
+ *
+ * In:
+ * This routine must be called just prior to resuming all threads.
+ */
+extern(C) void thread_processGCMarks(scope IsMarkedDg isMarked) nothrow
+{
+ for (ThreadBase t = ThreadBase.sm_tbeg; t; t = t.next)
+ {
+ /* Can be null if collection was triggered between adding a
+ * thread and calling rt_tlsgc_init.
+ */
+ if (t.m_tlsgcdata !is null)
+ rt_tlsgc_processGCMarks(t.m_tlsgcdata, isMarked);
+ }
+}
+
+
+/**
+ * Returns the stack top of the currently active stack within the calling
+ * thread.
+ *
+ * In:
+ * The calling thread must be attached to the runtime.
+ *
+ * Returns:
+ * The address of the stack top.
+ */
+extern (C) void* thread_stackTop() nothrow @nogc
+in
+{
+ // Not strictly required, but it gives us more flexibility.
+ assert(ThreadBase.getThis());
+}
+do
+{
+ return getStackTop();
+}
+
+
+/**
+ * Returns the stack bottom of the currently active stack within the calling
+ * thread.
+ *
+ * In:
+ * The calling thread must be attached to the runtime.
+ *
+ * Returns:
+ * The address of the stack bottom.
+ */
+extern (C) void* thread_stackBottom() nothrow @nogc
+in (ThreadBase.getThis())
+{
+ return ThreadBase.getThis().topContext().bstack;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// lowlovel threading support
+///////////////////////////////////////////////////////////////////////////////
+package
+{
+ __gshared size_t ll_nThreads;
+ __gshared ll_ThreadData* ll_pThreads;
+
+ __gshared align(mutexAlign) void[mutexClassInstanceSize] ll_lock;
+
+ @property Mutex lowlevelLock() nothrow @nogc
+ {
+ return cast(Mutex)ll_lock.ptr;
+ }
+
+ void initLowlevelThreads() @nogc
+ {
+ ll_lock[] = typeid(Mutex).initializer[];
+ lowlevelLock.__ctor();
+ }
+
+ void termLowlevelThreads() @nogc
+ {
+ lowlevelLock.__dtor();
+ }
+
+ void ll_removeThread(ThreadID tid) nothrow @nogc
+ {
+ lowlevelLock.lock_nothrow();
+ scope(exit) lowlevelLock.unlock_nothrow();
+
+ foreach (i; 0 .. ll_nThreads)
+ {
+ if (tid is ll_pThreads[i].tid)
+ {
+ import core.stdc.string : memmove;
+ memmove(ll_pThreads + i, ll_pThreads + i + 1, ll_ThreadData.sizeof * (ll_nThreads - i - 1));
+ --ll_nThreads;
+ // no need to minimize, next add will do
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * Check whether a thread was created by `createLowLevelThread`.
+ *
+ * Params:
+ * tid = the platform specific thread ID.
+ *
+ * Returns: `true` if the thread was created by `createLowLevelThread` and is still running.
+ */
+bool findLowLevelThread(ThreadID tid) nothrow @nogc
+{
+ lowlevelLock.lock_nothrow();
+ scope(exit) lowlevelLock.unlock_nothrow();
+
+ foreach (i; 0 .. ll_nThreads)
+ if (tid is ll_pThreads[i].tid)
+ return true;
+ return false;
+}
diff --git a/libphobos/libdruntime/core/thread/threadgroup.d b/libphobos/libdruntime/core/thread/threadgroup.d
new file mode 100644
index 0000000..d00ce05
--- /dev/null
+++ b/libphobos/libdruntime/core/thread/threadgroup.d
@@ -0,0 +1,162 @@
+/**
+ * The osthread module provides types used in threads modules.
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2012.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
+ * Source: $(DRUNTIMESRC core/thread/osthread.d)
+ */
+
+module core.thread.threadgroup;
+
+import core.thread.osthread;
+
+
+/**
+ * This class is intended to simplify certain common programming techniques.
+ */
+class ThreadGroup
+{
+ /**
+ * Creates and starts a new Thread object that executes fn and adds it to
+ * the list of tracked threads.
+ *
+ * Params:
+ * fn = The thread function.
+ *
+ * Returns:
+ * A reference to the newly created thread.
+ */
+ final Thread create(void function() fn)
+ {
+ Thread t = new Thread(fn).start();
+
+ synchronized(this)
+ {
+ m_all[t] = t;
+ }
+ return t;
+ }
+
+
+ /**
+ * Creates and starts a new Thread object that executes dg and adds it to
+ * the list of tracked threads.
+ *
+ * Params:
+ * dg = The thread function.
+ *
+ * Returns:
+ * A reference to the newly created thread.
+ */
+ final Thread create(void delegate() dg)
+ {
+ Thread t = new Thread(dg).start();
+
+ synchronized(this)
+ {
+ m_all[t] = t;
+ }
+ return t;
+ }
+
+
+ /**
+ * Add t to the list of tracked threads if it is not already being tracked.
+ *
+ * Params:
+ * t = The thread to add.
+ *
+ * In:
+ * t must not be null.
+ */
+ final void add(Thread t)
+ in
+ {
+ assert(t);
+ }
+ do
+ {
+ synchronized(this)
+ {
+ m_all[t] = t;
+ }
+ }
+
+
+ /**
+ * Removes t from the list of tracked threads. No operation will be
+ * performed if t is not currently being tracked by this object.
+ *
+ * Params:
+ * t = The thread to remove.
+ *
+ * In:
+ * t must not be null.
+ */
+ final void remove(Thread t)
+ in
+ {
+ assert(t);
+ }
+ do
+ {
+ synchronized(this)
+ {
+ m_all.remove(t);
+ }
+ }
+
+
+ /**
+ * Operates on all threads currently tracked by this object.
+ */
+ final int opApply(scope int delegate(ref Thread) dg)
+ {
+ synchronized(this)
+ {
+ int ret = 0;
+
+ // NOTE: This loop relies on the knowledge that m_all uses the
+ // Thread object for both the key and the mapped value.
+ foreach (Thread t; m_all.keys)
+ {
+ ret = dg(t);
+ if (ret)
+ break;
+ }
+ return ret;
+ }
+ }
+
+
+ /**
+ * Iteratively joins all tracked threads. This function will block add,
+ * remove, and opApply until it completes.
+ *
+ * Params:
+ * rethrow = Rethrow any unhandled exception which may have caused the
+ * current thread to terminate.
+ *
+ * Throws:
+ * Any exception not handled by the joined threads.
+ */
+ final void joinAll(bool rethrow = true)
+ {
+ synchronized(this)
+ {
+ // NOTE: This loop relies on the knowledge that m_all uses the
+ // Thread object for both the key and the mapped value.
+ foreach (Thread t; m_all.keys)
+ {
+ t.join(rethrow);
+ }
+ }
+ }
+
+
+private:
+ Thread[Thread] m_all;
+}
diff --git a/libphobos/libdruntime/core/thread/types.d b/libphobos/libdruntime/core/thread/types.d
new file mode 100644
index 0000000..e50399a
--- /dev/null
+++ b/libphobos/libdruntime/core/thread/types.d
@@ -0,0 +1,77 @@
+/**
+ * This module provides types and constants used in thread package.
+ *
+ * Copyright: Copyright Sean Kelly 2005 - 2012.
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
+ * Source: $(DRUNTIMESRC core/thread/osthread.d)
+ */
+
+module core.thread.types;
+
+/**
+ * Represents the ID of a thread, as returned by $(D Thread.)$(LREF id).
+ * The exact type varies from platform to platform.
+ */
+version (Windows)
+ alias ThreadID = uint;
+else
+version (Posix)
+{
+ import core.sys.posix.pthread;
+
+ alias ThreadID = pthread_t;
+}
+
+struct ll_ThreadData
+{
+ ThreadID tid;
+ version (Windows)
+ void delegate() nothrow cbDllUnload;
+}
+
+version (GNU)
+{
+ version (GNU_StackGrowsDown)
+ enum isStackGrowingDown = true;
+ else
+ enum isStackGrowingDown = false;
+}
+else
+{
+ // this should be true for most architectures
+ enum isStackGrowingDown = true;
+}
+
+package
+{
+ static immutable size_t PAGESIZE;
+ version (Posix) static immutable size_t PTHREAD_STACK_MIN;
+}
+
+shared static this()
+{
+ version (Windows)
+ {
+ import core.sys.windows.winbase;
+
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+
+ PAGESIZE = info.dwPageSize;
+ assert(PAGESIZE < int.max);
+ }
+ else version (Posix)
+ {
+ import core.sys.posix.unistd;
+
+ PAGESIZE = cast(size_t)sysconf(_SC_PAGESIZE);
+ PTHREAD_STACK_MIN = cast(size_t)sysconf(_SC_THREAD_STACK_MIN);
+ }
+ else
+ {
+ static assert(0, "unimplemented");
+ }
+}
diff --git a/libphobos/libdruntime/core/vararg.d b/libphobos/libdruntime/core/vararg.d
index a02ffea..935b2bd 100644
--- a/libphobos/libdruntime/core/vararg.d
+++ b/libphobos/libdruntime/core/vararg.d
@@ -17,3 +17,125 @@
module core.vararg;
public import core.stdc.stdarg;
+
+
+version (GNU) { /* TypeInfo-based va_arg overload unsupported */ }
+else:
+
+version (ARM) version = ARM_Any;
+version (AArch64) version = ARM_Any;
+version (MIPS32) version = MIPS_Any;
+version (MIPS64) version = MIPS_Any;
+version (PPC) version = PPC_Any;
+version (PPC64) version = PPC_Any;
+
+version (ARM_Any)
+{
+ // Darwin uses a simpler varargs implementation
+ version (OSX) {}
+ else version (iOS) {}
+ else version (TVOS) {}
+ else version (WatchOS) {}
+ else:
+
+ version (ARM) version = AAPCS32;
+ version (AArch64) version = AAPCS64;
+}
+
+
+///
+alias va_arg = core.stdc.stdarg.va_arg;
+
+
+/**
+ * Retrieve and store through parmn the next value that is of TypeInfo ti.
+ * Used when the static type is not known.
+ */
+void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
+{
+ version (X86)
+ {
+ // Wait until everyone updates to get TypeInfo.talign
+ //auto talign = ti.talign;
+ //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1);
+ auto p = ap;
+ auto tsize = ti.tsize;
+ ap = cast(va_list) (p + tsize.alignUp);
+ parmn[0..tsize] = p[0..tsize];
+ }
+ else version (Win64)
+ {
+ version (LDC) enum isLDC = true;
+ else enum isLDC = false;
+
+ // Wait until everyone updates to get TypeInfo.talign
+ //auto talign = ti.talign;
+ //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1);
+ auto p = ap;
+ auto tsize = ti.tsize;
+ void* q;
+ if (isLDC && tsize == 16 && cast(TypeInfo_Array) ti)
+ {
+ q = p;
+ ap = cast(va_list) (p + tsize);
+ }
+ else
+ {
+ q = (tsize > size_t.sizeof || (tsize & (tsize - 1)) != 0) ? *cast(void**) p : p;
+ ap = cast(va_list) (p + size_t.sizeof);
+ }
+ parmn[0..tsize] = q[0..tsize];
+ }
+ else version (X86_64)
+ {
+ static import core.internal.vararg.sysv_x64;
+ core.internal.vararg.sysv_x64.va_arg(ap, ti, parmn);
+ }
+ else version (AAPCS32)
+ {
+ const tsize = ti.tsize;
+ if (ti.talign >= 8)
+ ap.__ap = ap.__ap.alignUp!8;
+ auto p = ap.__ap;
+ version (BigEndian)
+ p = adjustForBigEndian(p, tsize);
+ ap.__ap += tsize.alignUp;
+ parmn[0..tsize] = p[0..tsize];
+ }
+ else version (AAPCS64)
+ {
+ static import core.internal.vararg.aarch64;
+ core.internal.vararg.aarch64.va_arg(ap, ti, parmn);
+ }
+ else version (ARM_Any)
+ {
+ const tsize = ti.tsize;
+ auto p = cast(void*) ap;
+ version (BigEndian)
+ p = adjustForBigEndian(p, tsize);
+ ap += tsize.alignUp;
+ parmn[0..tsize] = p[0..tsize];
+ }
+ else version (PPC_Any)
+ {
+ if (ti.talign >= 8)
+ ap = ap.alignUp!8;
+ const tsize = ti.tsize;
+ auto p = cast(void*) ap;
+ version (BigEndian)
+ p = adjustForBigEndian(p, tsize);
+ ap += tsize.alignUp;
+ parmn[0..tsize] = p[0..tsize];
+ }
+ else version (MIPS_Any)
+ {
+ const tsize = ti.tsize;
+ auto p = cast(void*) ap;
+ version (BigEndian)
+ p = adjustForBigEndian(p, tsize);
+ ap += tsize.alignUp;
+ parmn[0..tsize] = p[0..tsize];
+ }
+ else
+ static assert(0, "Unsupported platform");
+}
diff --git a/libphobos/libdruntime/core/volatile.d b/libphobos/libdruntime/core/volatile.d
new file mode 100644
index 0000000..1703450
--- /dev/null
+++ b/libphobos/libdruntime/core/volatile.d
@@ -0,0 +1,67 @@
+/**
+ * This module declares intrinsics for volatile operations.
+ *
+ * Copyright: Copyright © 2019, The D Language Foundation
+ * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Authors: Walter Bright, Ernesto Castellotti
+ * Source: $(DRUNTIMESRC core/volatile.d)
+ */
+
+module core.volatile;
+
+nothrow:
+@safe:
+@nogc:
+
+/*************************************
+ * Read/write value from/to the memory location indicated by ptr.
+ *
+ * These functions are recognized by the compiler, and calls to them are guaranteed
+ * to not be removed (as dead assignment elimination or presumed to have no effect)
+ * or reordered in the same thread.
+ *
+ * These reordering guarantees are only made with regards to other
+ * operations done through these functions; the compiler is free to reorder regular
+ * loads/stores with regards to loads/stores done through these functions.
+ *
+ * This is useful when dealing with memory-mapped I/O (MMIO) where a store can
+ * have an effect other than just writing a value, or where sequential loads
+ * with no intervening stores can retrieve
+ * different values from the same location due to external stores to the location.
+ *
+ * These functions will, when possible, do the load/store as a single operation. In
+ * general, this is possible when the size of the operation is less than or equal to
+ * $(D (void*).sizeof), although some targets may support larger operations. If the
+ * load/store cannot be done as a single operation, multiple smaller operations will be used.
+ *
+ * These are not to be conflated with atomic operations. They do not guarantee any
+ * atomicity. This may be provided by coincidence as a result of the instructions
+ * used on the target, but this should not be relied on for portable programs.
+ * Further, no memory fences are implied by these functions.
+ * They should not be used for communication between threads.
+ * They may be used to guarantee a write or read cycle occurs at a specified address.
+ */
+
+ubyte volatileLoad(ubyte * ptr);
+ushort volatileLoad(ushort* ptr); /// ditto
+uint volatileLoad(uint * ptr); /// ditto
+ulong volatileLoad(ulong * ptr); /// ditto
+
+void volatileStore(ubyte * ptr, ubyte value); /// ditto
+void volatileStore(ushort* ptr, ushort value); /// ditto
+void volatileStore(uint * ptr, uint value); /// ditto
+void volatileStore(ulong * ptr, ulong value); /// ditto
+
+@system unittest
+{
+ alias TT(T...) = T;
+
+ foreach (T; TT!(ubyte, ushort, uint, ulong))
+ {
+ T u;
+ T* p = &u;
+ volatileStore(p, 1);
+ T r = volatileLoad(p);
+ assert(r == u);
+ }
+}
diff --git a/libphobos/libdruntime/gc/impl/conservative/gc.d b/libphobos/libdruntime/gc/impl/conservative/gc.d
index b7bb9b0..300a32a 100644
--- a/libphobos/libdruntime/gc/impl/conservative/gc.d
+++ b/libphobos/libdruntime/gc/impl/conservative/gc.d
@@ -76,7 +76,7 @@ debug(PRINTF_TO_FILE)
gcStartTick = MonoTime.currTime;
immutable timeElapsed = MonoTime.currTime - gcStartTick;
immutable secondsAsDouble = timeElapsed.total!"hnsecs" / cast(double)convert!("seconds", "hnsecs")(1);
- len = fprintf(gcx_fh, "%10.6lf: ", secondsAsDouble);
+ len = fprintf(gcx_fh, "%10.6f: ", secondsAsDouble);
}
len += fprintf(gcx_fh, fmt, args);
fflush(gcx_fh);
@@ -159,7 +159,7 @@ debug (LOGGING)
printf(" p = %p, size = %zd, parent = %p ", p, size, parent);
if (file)
{
- printf("%s(%u)", file, line);
+ printf("%s(%u)", file, cast(uint)line);
}
printf("\n");
}
diff --git a/libphobos/libdruntime/gcc/attribute.d b/libphobos/libdruntime/gcc/attribute.d
index 4acb571..d1ff5c7 100644
--- a/libphobos/libdruntime/gcc/attribute.d
+++ b/libphobos/libdruntime/gcc/attribute.d
@@ -1,5 +1,5 @@
// GNU D Compiler attribute support declarations.
-// Copyright (C) 2013-2020 Free Software Foundation, Inc.
+// Copyright (C) 2013-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
@@ -20,14 +20,7 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
+deprecated("Import gcc.attributes instead")
module gcc.attribute;
-private struct Attribute(A...)
-{
- A args;
-}
-
-auto attribute(A...)(A args) if (A.length > 0 && is(A[0] == string))
-{
- return Attribute!A(args);
-}
+public import gcc.attributes;
diff --git a/libphobos/libdruntime/gcc/attributes.d b/libphobos/libdruntime/gcc/attributes.d
new file mode 100644
index 0000000..58a4023
--- /dev/null
+++ b/libphobos/libdruntime/gcc/attributes.d
@@ -0,0 +1,605 @@
+// GNU D Compiler attribute support declarations.
+// Copyright (C) 2021 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.attributes;
+
+// Private helper templates.
+private struct Attribute(A...)
+{
+ A arguments;
+}
+
+private enum bool isStringValue(alias T) = is(typeof(T) == string);
+
+private enum bool isStringOrIntValue(alias T)
+ = is(typeof(T) == string) || is(typeof(T) == int);
+
+private template allSatisfy(alias F, T...)
+{
+ static if (T.length == 0)
+ enum allSatisfy = true;
+ else static if (T.length == 1)
+ enum allSatisfy = F!(T[0]);
+ else
+ {
+ enum allSatisfy = allSatisfy!(F, T[ 0 .. $/2])
+ && allSatisfy!(F, T[$/2 .. $ ]);
+ }
+}
+
+/**
+ * Generic entrypoint for applying GCC attributes to a function or type.
+ * There is no type checking done, as well as no deprecation path for
+ * attributes removed from the compiler. So the recommendation is to use any
+ , of the other UDAs available unless it is a target-specific attribute.
+ *
+ * Function attributes introduced by the @attribute UDA are used in the
+ * declaration of a function, followed by an attribute name string and
+ * any arguments separated by commas enclosed in parentheses.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @attribute("regparm", 1) int func(int size);
+ * ---
+ */
+@system
+auto attribute(A...)(A arguments)
+ if (A.length > 0 && is(A[0] == string))
+{
+ return Attribute!A(arguments);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Supported common attributes exposed by GDC.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * The `@alloc_size` attribute may be applied to a function that returns a
+ * pointer and takes at least one argument of an integer or enumerated type.
+ * It indicates that the returned pointer points to memory whose size is given
+ * by the function argument at `sizeArgIdx`, or by the product of the arguments
+ * at `sizeArgIdx` and `numArgIdx`. Meaningful sizes are positive values less
+ * than `ptrdiff_t.max`. Unless `zeroBasedNumbering` is true, argument
+ * numbering starts at one for ordinary functions, and at two for non-static
+ * member functions.
+ *
+ * If `numArgIdx` is less than `0`, it is taken to mean there is no argument
+ * specifying the element count.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @alloc_size(1) extern(C) void* malloc(size_t size);
+ * @alloc_size(3,2) extern(C) void* reallocarray(void *ptr, size_t nmemb,
+ * size_t size);
+ * @alloc_size(1,2) void* my_calloc(size_t element_size, size_t count,
+ * bool irrelevant);
+ * ---
+ */
+auto alloc_size(int sizeArgIdx)
+{
+ return attribute("alloc_size", sizeArgIdx);
+}
+
+/// ditto
+auto alloc_size(int sizeArgIdx, int numArgIdx)
+{
+ return attribute("alloc_size", sizeArgIdx, numArgIdx);
+}
+
+/// ditto
+auto alloc_size(int sizeArgIdx, int numArgIdx, bool zeroBasedNumbering)
+{
+ return attribute("alloc_size", sizeArgIdx, numArgIdx, zeroBasedNumbering);
+}
+
+auto alloc_size(A...)(A arguments)
+{
+ assert(false, "alloc_size attribute argument value is not an integer constant");
+}
+
+/**
+ * The `@always_inline` attribute inlines the function independent of any
+ * restrictions that otherwise apply to inlining. Failure to inline such a
+ * function is diagnosed as an error.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @always_inline int func();
+ * ---
+ */
+enum always_inline = attribute("always_inline");
+
+/**
+ * The `@cold` attribute on functions is used to inform the compiler that the
+ * function is unlikely to be executed. The function is optimized for size
+ * rather than speed and on many targets it is placed into a special subsection
+ * of the text section so all cold functions appear close together, improving
+ * code locality of non-cold parts of program. The paths leading to calls of
+ * cold functions within code are considered to be cold too.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @cold int func();
+ * ---
+ */
+enum cold = attribute("cold");
+
+/**
+ * The `@flatten` attribute is used to inform the compiler that every call
+ * inside this function should be inlined, if possible. Functions declared with
+ * attribute `@noinline` and similar are not inlined.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @flatten int func();
+ * ---
+ */
+enum flatten = attribute("flatten");
+
+/**
+ * The `@no_icf` attribute prevents a functions from being merged with another
+ * semantically equivalent function.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @no_icf int func();
+ * ---
+ */
+enum no_icf = attribute("no_icf");
+
+/**
+ * The `@noclone` attribute prevents a function from being considered for
+ * cloning - a mechanism that produces specialized copies of functions and
+ * which is (currently) performed by interprocedural constant propagation.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @noclone int func();
+ * ---
+ */
+enum noclone = attribute("noclone");
+
+/**
+ * The `@noinline` attribute prevents a function from being considered for
+ * inlining. If the function does not have side effects, there are
+ * optimizations other than inlining that cause function calls to be optimized
+ * away, although the function call is live. To keep such calls from being
+ * optimized away, put `asm { ""; }` in the called function, to serve as a
+ * special side effect.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @noinline int func();
+ * ---
+ */
+enum noinline = attribute("noinline");
+
+/**
+ * The `@noipa` attribute disables interprocedural optimizations between the
+ * function with this attribute and its callers, as if the body of the function
+ * is not available when optimizing callers and the callers are unavailable when
+ * optimizing the body. This attribute implies `@noinline`, `@noclone`, and
+ * `@no_icf` attributes. However, this attribute is not equivalent to a
+ * combination of other attributes, because its purpose is to suppress existing
+ * and future optimizations employing interprocedural analysis, including those
+ * that do not have an attribute suitable for disabling them individually.
+ *
+ * This attribute is supported mainly for the purpose of testing the compiler.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @noipa int func();
+ * ---
+ */
+enum noipa = attribute("noipa");
+
+/**
+ * The `@optimize` attribute is used to specify that a function is to be
+ * compiled with different optimization options than specified on the command
+ * line. Valid `arguments` are constant non-negative integers and strings.
+ * Multiple arguments can be provided, separated by commas to specify multiple
+ * options. Each numeric argument specifies an optimization level. Each string
+ * argument that begins with the letter O refers to an optimization option such
+ * as `-O0` or `-Os`. Other options are taken as suffixes to the `-f` prefix
+ * jointly forming the name of an optimization option.
+ *
+ * Not every optimization option that starts with the `-f` prefix specified by
+ * the attribute necessarily has an effect on the function. The `@optimize`
+ * attribute should be used for debugging purposes only. It is not suitable in
+ * production code.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @optimize(2) double fn0(double x);
+ * @optimize("2") double fn1(double x);
+ * @optimize("s") double fn2(double x);
+ * @optimize("Ofast") double fn3(double x);
+ * @optimize("-O2") double fn4(double x);
+ * @optimize("tree-vectorize") double fn5(double x);
+ * @optimize("-ftree-vectorize") double fn6(double x);
+ * @optimize("no-finite-math-only", 3) double fn7(double x);
+ * ---
+ */
+auto optimize(A...)(A arguments)
+ if (allSatisfy!(isStringOrIntValue, arguments))
+{
+ return attribute("optimize", arguments);
+}
+
+auto optimize(A...)(A arguments)
+ if (!allSatisfy!(isStringOrIntValue, arguments))
+{
+ assert(false, "optimize attribute argument not a string or integer constant");
+}
+
+/**
+ * The `@restrict` attribute specifies that a function parameter is to be
+ * restrict-qualified in the C99 sense of the term. The parameter needs to
+ * boil down to either a pointer or reference type, such as a D pointer,
+ * class reference, or a `ref` parameter.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * void func(@restrict ref const float[16] array);
+ * ---
+ */
+enum restrict = attribute("restrict");
+
+/**
+ * The `@section` attribute specifies that a function lives in a particular
+ * section. For when you need certain particular functions to appear in
+ * special sections.
+ *
+ * Some file formats do not support arbitrary sections so the section attribute
+ * is not available on all platforms. If you need to map the entire contents
+ * of a module to a particular section, consider using the facilities of the
+ * linker instead.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @section("bar") extern void func();
+ * ---
+ */
+auto section(string sectionName)
+{
+ return attribute("section", sectionName);
+}
+
+auto section(A...)(A arguments)
+{
+ assert(false, "section attribute argument not a string constant");
+}
+
+/**
+ * The `@symver` attribute creates a symbol version on ELF targets. The syntax
+ * of the string parameter is `name@nodename`. The `name` part of the parameter
+ * is the actual name of the symbol by which it will be externally referenced.
+ * The `nodename` portion should be the name of a node specified in the version
+ * script supplied to the linker when building a shared library. Versioned
+ * symbol must be defined and must be exported with default visibility.
+ *
+ * Finally if the parameter is `name@@nodename` then in addition to creating a
+ * symbol version (as if `name@nodename` was used) the version will be also used
+ * to resolve `name` by the linker.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @symver("foo@VERS_1") int foo_v1();
+ * ---
+ */
+auto symver(A...)(A arguments)
+ if (allSatisfy!(isStringValue, arguments))
+{
+ return attribute("symver", arguments);
+}
+
+auto symver(A...)(A arguments)
+ if (!allSatisfy!(isStringValue, arguments))
+{
+ assert(false, "symver attribute argument not a string constant");
+}
+
+/**
+ * The `@target` attribute is used to specify that a function is to be
+ * compiled with different target options than specified on the command line.
+ * One or more strings can be provided as arguments, separated by commas to
+ * specify multiple options. Each string consists of one or more
+ * comma-separated suffixes to the `-m` prefix jointly forming the name of a
+ * machine-dependent option.
+ *
+ * The target attribute can be used for instance to have a function compiled
+ * with a different ISA (instruction set architecture) than the default.
+ *
+ * The options supported are specific to each target.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @target("arch=core2") void core2_func();
+ * @target("sse3") void sse3_func();
+ * ---
+ */
+auto target(A...)(A arguments)
+ if (allSatisfy!(isStringValue, arguments))
+{
+ return attribute("target", arguments);
+}
+
+auto target(A...)(A arguments)
+ if (!allSatisfy!(isStringValue, arguments))
+{
+ assert(false, "target attribute argument not a string constant");
+}
+
+/**
+ * The `@target_clones` attribute is used to specify that a function be cloned
+ * into multiple versions compiled with different target `options` than
+ * specified on the command line. The supported options and restrictions are
+ * the same as for `@target` attribute.
+ *
+ * It also creates a resolver function that dynamically selects a clone suitable
+ * for current architecture. The resolver is created only if there is a usage
+ * of a function with `@target_clones` attribute.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @target_clones("sse4.1,avx,default") double func(double x);
+ * ---
+ */
+auto target_clones(A...)(A arguments)
+ if (allSatisfy!(isStringValue, arguments))
+{
+ return attribute("target_clones", arguments);
+}
+
+auto target_clones(A...)(A arguments)
+ if (!allSatisfy!(isStringValue, arguments))
+{
+ assert(false, "target attribute argument not a string constant");
+}
+
+/**
+ * The `@used` attribute, annotated to a function, means that code must be
+ * emitted for the function even if it appears that the function is not
+ * referenced. This is useful, for example, when the function is referenced
+ * only in inline assembly.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @used __gshared int var = 0x1000;
+ * ---
+ */
+enum used = attribute("used");
+
+/**
+ * The `@weak` attribute causes a declaration of an external symbol to be
+ * emitted as a weak symbol rather than a global. This is primarily useful in
+ * defining library functions that can be overridden in user code, though it can
+ * also be used with non-function declarations. The overriding symbol must have
+ * the same type as the weak symbol. In addition, if it designates a variable
+ * it must also have the same size and alignment as the weak symbol.
+ *
+ * Weak symbols are supported for ELF targets, and also for a.out targets when
+ * using the GNU assembler and linker.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @weak int func() { return 1; }
+ * ---
+ */
+enum weak = attribute("weak");
+
+/**
+ * The `@noplt` attribute is the counterpart to option `-fno-plt`. Calls to
+ * functions marked with this attribute in position-independent code do not use
+ * the PLT in position-independent code.
+ *
+ * In position-dependant code, a few targets also convert call to functions
+ * that are marked to not use the PLT to use the GOT instead.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @noplt int func();
+ *
+ * ---
+ */
+enum noplt = attribute("noplt");
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Attributes defined for compatibility with LDC.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Specifies that the function returns `null` or a pointer to at least a
+ * certain number of allocated bytes. `sizeArgIdx` and `numArgIdx` specify
+ * the 0-based index of the function arguments that should be used to calculate
+ * the number of bytes returned.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @allocSize(0) extern(C) void* malloc(size_t size);
+ * @allocSize(2,1) extern(C) void* reallocarray(void *ptr, size_t nmemb,
+ * size_t size);
+ * @allocSize(0,1) void* my_calloc(size_t element_size, size_t count,
+ * bool irrelevant);
+ * ---
+ */
+auto allocSize(int sizeArgIdx, int numArgIdx = int.min)
+{
+ return alloc_size(sizeArgIdx, numArgIdx, true);
+}
+
+auto allocSize(A...)(A arguments)
+{
+ assert(false, "allocSize attribute argument value is not an integer constant");
+}
+
+/**
+ * When applied to a global symbol, the compiler, assembler, and linker are
+ * required to treat the symbol as if there is a reference to the symbol that
+ * it cannot see (which is why they have to be named). For example, it
+ * prevents the deletion by the linker of an unreferenced symbol.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @assumeUsed __gshared int var = 0x1000;
+ * ---
+ */
+alias assumeUsed = used;
+
+/// This attribute has no effect.
+enum dynamicCompile = false;
+
+/// ditto
+enum dynamicCompileConst = false;
+
+/// ditto
+enum dynamicCompileEmit = false;
+
+/**
+ * Explicitly sets "fast-math" for a function, enabling aggressive math
+ * optimizations. These optimizations may dramatically change the outcome of
+ * floating point calculations (e.g. because of reassociation).
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @fastmath
+ * double dot(double[] a, double[] b) {
+ * double s = 0;
+ * foreach(size_t i; 0..a.length)
+ * {
+ * // will result in vectorized fused-multiply-add instructions
+ * s += a * b;
+ * }
+ * return s;
+ * }
+ * ---
+ */
+enum fastmath = optimize("Ofast");
+
+/**
+ * Adds GCC's "naked" attribute to a function, disabling function prologue /
+ * epilogue emission.
+ * Intended to be used in combination with basic `asm` statement. While using
+ * extended `asm` or a mixture of basic `asm` and D code may appear to work,
+ * they cannot be depended upon to work reliably and are not supported.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @naked void abort() {
+ * asm { "ud2"; }
+ * }
+ * ---
+ */
+enum naked = attribute("naked");
+
+/**
+ * Sets the optimization strategy for a function.
+ * Valid strategies are "none", "optsize", "minsize". The strategies are
+ * mutually exclusive.
+ *
+ * Example:
+ * ---
+ * import gcc.attributes;
+ *
+ * @optStrategy("none")
+ * int func() {
+ * return call();
+ * }
+ * ---
+ */
+auto optStrategy(string strategy)
+{
+ if (strategy == "none")
+ return optimize("O0");
+ else if (strategy == "optsize" || strategy == "minsize")
+ return optimize("Os");
+ else
+ {
+ assert(false, "unrecognized parameter `" ~ strategy
+ ~ "` for `gcc.attribute.optStrategy`");
+ }
+}
+
+auto optStrategy(A...)(A arguments)
+{
+ assert(false, "optStrategy attribute argument value is not a string constant");
+}
+
+/**
+ * When applied to a function, specifies that the function should be optimzed
+ * by Graphite, GCC's polyhedral optimizer. Useful for optimizing loops for
+ * data locality, vectorization and parallelism.
+ *
+ * Experimental!
+ *
+ * Only effective when GDC was built with ISL included.
+ */
+enum polly = optimize("loop-parallelize-all", "loop-nest-optimize");
diff --git a/libphobos/libdruntime/gcc/backtrace.d b/libphobos/libdruntime/gcc/backtrace.d
index ab559a0..8f5582d 100644
--- a/libphobos/libdruntime/gcc/backtrace.d
+++ b/libphobos/libdruntime/gcc/backtrace.d
@@ -1,5 +1,5 @@
// GNU D Compiler routines for stack backtrace support.
-// Copyright (C) 2013-2020 Free Software Foundation, Inc.
+// Copyright (C) 2013-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
@@ -424,8 +424,10 @@ private:
import core.sys.freebsd.dlfcn;
else version (NetBSD)
import core.sys.netbsd.dlfcn;
+ else version (OpenBSD)
+ import core.sys.openbsd.dlfcn;
else version (Solaris)
- import core.sys.netbsd.dlfcn;
+ import core.sys.solaris.dlfcn;
else version (Posix)
import core.sys.posix.dlfcn;
diff --git a/libphobos/libdruntime/gcc/builtins.d b/libphobos/libdruntime/gcc/builtins.d
index d596173..d87e22c 100644
--- a/libphobos/libdruntime/gcc/builtins.d
+++ b/libphobos/libdruntime/gcc/builtins.d
@@ -1,5 +1,5 @@
/* GNU D Compiler bindings for built-in functions and types.
- Copyright (C) 2006-2020 Free Software Foundation, Inc.
+ Copyright (C) 2006-2021 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/gcc/config.d.in b/libphobos/libdruntime/gcc/config.d.in
index 9ac7d05..b9aa302 100644
--- a/libphobos/libdruntime/gcc/config.d.in
+++ b/libphobos/libdruntime/gcc/config.d.in
@@ -1,5 +1,5 @@
// GNU D Compiler configure constants.
-// Copyright (C) 2015-2020 Free Software Foundation, Inc.
+// Copyright (C) 2015-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d
index 3e78a6c9..eb83751c 100644
--- a/libphobos/libdruntime/gcc/deh.d
+++ b/libphobos/libdruntime/gcc/deh.d
@@ -1,5 +1,5 @@
// GNU D Compiler exception personality routines.
-// Copyright (C) 2011-2020 Free Software Foundation, Inc.
+// Copyright (C) 2011-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
@@ -28,17 +28,12 @@ import gcc.unwind;
import gcc.unwind.pe;
import gcc.builtins;
import gcc.config;
-import gcc.attribute;
+import gcc.attributes;
extern(C)
{
int _d_isbaseof(ClassInfo, ClassInfo);
void _d_createTrace(Object, void*);
-
- // Not used in GDC but declaration required by rt/sections.d
- struct FuncTable
- {
- }
}
/**
@@ -552,7 +547,7 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti
_Unwind_Ptr LPStart = 0;
if (LPStartEncoding != DW_EH_PE_omit)
- LPStart = read_encoded_value(context, LPStartEncoding, &p);
+ LPStart = read_encoded_value(context, LPStartEncoding, p);
else
LPStart = Start;
@@ -568,14 +563,14 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti
// hardcoded OS-specific format.
TTypeEncoding = _TTYPE_ENCODING;
}
- auto TTbase = read_uleb128(&p);
+ auto TTbase = read_uleb128(p);
TType = p + TTbase;
}
// The encoding and length of the call-site table; the action table
// immediately follows.
ubyte CSEncoding = *p++;
- auto CSTableSize = read_uleb128(&p);
+ auto CSTableSize = read_uleb128(p);
const(ubyte)* actionTable = p + CSTableSize;
auto TTypeBase = base_of_encoded_value(TTypeEncoding, context);
@@ -613,8 +608,8 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti
_uleb128_t CSLandingPad, CSAction;
do
{
- CSLandingPad = read_uleb128(&p);
- CSAction = read_uleb128(&p);
+ CSLandingPad = read_uleb128(p);
+ CSAction = read_uleb128(p);
}
while (--ip);
@@ -631,10 +626,10 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti
while (p < actionTable)
{
// Note that all call-site encodings are "absolute" displacements.
- auto CSStart = read_encoded_value(null, CSEncoding, &p);
- auto CSLen = read_encoded_value(null, CSEncoding, &p);
- auto CSLandingPad = read_encoded_value(null, CSEncoding, &p);
- auto CSAction = read_uleb128(&p);
+ auto CSStart = read_encoded_value(null, CSEncoding, p);
+ auto CSLen = read_encoded_value(null, CSEncoding, p);
+ auto CSLandingPad = read_encoded_value(null, CSEncoding, p);
+ auto CSAction = read_uleb128(p);
// The table is sorted, so if we've passed the ip, stop.
if (ip < Start + CSStart)
@@ -708,9 +703,9 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader,
while (1)
{
auto ap = actionRecord;
- auto ARFilter = read_sleb128(&ap);
+ auto ARFilter = read_sleb128(ap);
auto apn = ap;
- auto ARDisp = read_sleb128(&ap);
+ auto ARDisp = read_sleb128(ap);
if (ARFilter == 0)
{
@@ -730,7 +725,7 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader,
// the ClassInfo is stored.
const(ubyte)* tp = TType - ARFilter * encodedSize;
- auto entry = read_encoded_value_with_base(TTypeEncoding, TTypeBase, &tp);
+ auto entry = read_encoded_value_with_base(TTypeEncoding, TTypeBase, tp);
ClassInfo ci = cast(ClassInfo)cast(void*)(entry);
// D does not have catch-all handlers, and so the following
@@ -805,7 +800,7 @@ version (GNU_SEH_Exceptions)
void* ms_orig_context, void* ms_disp)
{
return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
- ms_disp, &__gdc_personality_imp);
+ ms_disp, &gdc_personality);
}
}
else version (GNU_SjLj_Exceptions)
diff --git a/libphobos/libdruntime/gcc/drtstuff.c b/libphobos/libdruntime/gcc/drtstuff.c
index 9ca5d3d..4d7e650 100644
--- a/libphobos/libdruntime/gcc/drtstuff.c
+++ b/libphobos/libdruntime/gcc/drtstuff.c
@@ -1,6 +1,6 @@
/* Provide minfo section bracketing for D executables and shared libraries
when the linker doesn't provide it.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/libphobos/libdruntime/gcc/emutls.d b/libphobos/libdruntime/gcc/emutls.d
index 1436cdb..4237dc7 100644
--- a/libphobos/libdruntime/gcc/emutls.d
+++ b/libphobos/libdruntime/gcc/emutls.d
@@ -1,5 +1,5 @@
// GNU D Compiler emulated TLS routines.
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+// Copyright (C) 2019-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/gcc/gthread.d b/libphobos/libdruntime/gcc/gthread.d
index 65bda7d..5003637 100644
--- a/libphobos/libdruntime/gcc/gthread.d
+++ b/libphobos/libdruntime/gcc/gthread.d
@@ -1,5 +1,5 @@
// GNU D Compiler thread support for emulated TLS routines.
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+// Copyright (C) 2019-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
@@ -86,10 +86,12 @@ else static if (GNU_Thread_Model == ThreadModel.Single)
}
else static if (GNU_Thread_Model == ThreadModel.Win32)
{
+ import core.stdc.config;
+
struct __gthread_once_t
{
- INT done;
- LONG started;
+ int done;
+ c_long started;
}
int __gthr_win32_key_create(__gthread_key_t* keyp, GthreadDestroyFn dtor);
diff --git a/libphobos/libdruntime/gcc/libbacktrace.d.in b/libphobos/libdruntime/gcc/libbacktrace.d.in
index 43370ca..7d8ddfb 100644
--- a/libphobos/libdruntime/gcc/libbacktrace.d.in
+++ b/libphobos/libdruntime/gcc/libbacktrace.d.in
@@ -1,5 +1,5 @@
// GNU D Compiler bindings for the stack backtrace functions.
-// Copyright (C) 2013-2020 Free Software Foundation, Inc.
+// Copyright (C) 2013-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/gcc/sections/android.d b/libphobos/libdruntime/gcc/sections/android.d
deleted file mode 100644
index 2180a0b..0000000
--- a/libphobos/libdruntime/gcc/sections/android.d
+++ /dev/null
@@ -1,184 +0,0 @@
-// Bionic-specific support for sections.
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-module gcc.sections.android;
-
-version (CRuntime_Bionic):
-
-// debug = PRINTF;
-debug(PRINTF) import core.stdc.stdio;
-import core.stdc.stdlib : malloc, free;
-import rt.deh, rt.minfo;
-import core.sys.posix.pthread;
-import core.stdc.stdlib : calloc;
-import core.stdc.string : memcpy;
-
-struct SectionGroup
-{
- static int opApply(scope int delegate(ref SectionGroup) dg)
- {
- return dg(_sections);
- }
-
- static int opApplyReverse(scope int delegate(ref SectionGroup) dg)
- {
- return dg(_sections);
- }
-
- @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
- {
- return _moduleGroup.modules;
- }
-
- @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
- {
- return _moduleGroup;
- }
-
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- auto pbeg = cast(immutable(FuncTable)*)&__start_deh;
- auto pend = cast(immutable(FuncTable)*)&__stop_deh;
- return pbeg[0 .. pend - pbeg];
- }
-
- @property inout(void[])[] gcRanges() inout nothrow @nogc
- {
- return _gcRanges[];
- }
-
-private:
- ModuleGroup _moduleGroup;
- void[][1] _gcRanges;
-}
-
-void initSections() nothrow @nogc
-{
- pthread_key_create(&_tlsKey, null);
-
- auto mbeg = cast(immutable ModuleInfo**)&__start_minfo;
- auto mend = cast(immutable ModuleInfo**)&__stop_minfo;
- _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]);
-
- auto pbeg = cast(void*)&_tlsend;
- auto pend = cast(void*)&__bss_end__;
- // _tlsend is a 32-bit int and may not be 64-bit void*-aligned, so align pbeg.
- version (D_LP64) pbeg = cast(void*)(cast(size_t)(pbeg + 7) & ~cast(size_t)7);
- _sections._gcRanges[0] = pbeg[0 .. pend - pbeg];
-}
-
-void finiSections() nothrow @nogc
-{
- pthread_key_delete(_tlsKey);
-}
-
-void[]* initTLSRanges() nothrow @nogc
-{
- return &getTLSBlock();
-}
-
-void finiTLSRanges(void[]* rng) nothrow @nogc
-{
- .free(rng.ptr);
- .free(rng);
-}
-
-void scanTLSRanges(void[]* rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow
-{
- dg(rng.ptr, rng.ptr + rng.length);
-}
-
-/* NOTE: The Bionic C library ignores thread-local data stored in the normal
- * .tbss/.tdata ELF sections, which are marked with the SHF_TLS/STT_TLS
- * flags. So instead we roll our own by keeping TLS data in the
- * .tdata/.tbss sections but removing the SHF_TLS/STT_TLS flags, and
- * access the TLS data using this function and the _tlsstart/_tlsend
- * symbols as delimiters.
- *
- * This function is called by the code emitted by the compiler. It
- * is expected to translate an address in the TLS static data to
- * the corresponding address in the TLS dynamic per-thread data.
- */
-
-extern(C) void* __tls_get_addr( void* p ) nothrow @nogc
-{
- debug(PRINTF) printf(" __tls_get_addr input - %p\n", p);
- immutable offset = cast(size_t)(p - cast(void*)&_tlsstart);
- auto tls = getTLSBlockAlloc();
- assert(offset < tls.length);
- return tls.ptr + offset;
-}
-
-private:
-
-__gshared pthread_key_t _tlsKey;
-
-ref void[] getTLSBlock() nothrow @nogc
-{
- auto pary = cast(void[]*)pthread_getspecific(_tlsKey);
- if (pary is null)
- {
- pary = cast(void[]*).calloc(1, (void[]).sizeof);
- if (pthread_setspecific(_tlsKey, pary) != 0)
- {
- import core.stdc.stdio;
- perror("pthread_setspecific failed with");
- assert(0);
- }
- }
- return *pary;
-}
-
-ref void[] getTLSBlockAlloc() nothrow @nogc
-{
- auto pary = &getTLSBlock();
- if (!pary.length)
- {
- auto pbeg = cast(void*)&_tlsstart;
- auto pend = cast(void*)&_tlsend;
- auto p = .malloc(pend - pbeg);
- memcpy(p, pbeg, pend - pbeg);
- *pary = p[0 .. pend - pbeg];
- }
- return *pary;
-}
-
-__gshared SectionGroup _sections;
-
-extern(C)
-{
- /* Symbols created by the compiler/linker and inserted into the
- * object file that 'bracket' sections.
- */
- extern __gshared
- {
- void* __start_deh;
- void* __stop_deh;
- void* __start_minfo;
- void* __stop_minfo;
-
- size_t __bss_end__;
-
- int _tlsstart;
- int _tlsend;
- }
-}
diff --git a/libphobos/libdruntime/gcc/sections/common.d b/libphobos/libdruntime/gcc/sections/common.d
new file mode 100644
index 0000000..85fdc0e
--- /dev/null
+++ b/libphobos/libdruntime/gcc/sections/common.d
@@ -0,0 +1,39 @@
+// Contains various utility functions used by the runtime implementation.
+// Copyright (C) 2019-2021 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections.common;
+
+/**
+ * Asserts that the given condition is `true`.
+ *
+ * The assertion is independent from -release, by abort()ing. Regular assertions
+ * throw an AssertError and thus require an initialized GC, which might not be
+ * the case (yet or anymore) for the startup/shutdown code in this package
+ * (called by CRT ctors/dtors etc.).
+ */
+package(gcc) void safeAssert(
+ bool condition, scope string msg, scope string file = __FILE__, size_t line = __LINE__
+) nothrow @nogc @safe
+{
+ import core.internal.abort;
+ condition || abort(msg, file, line);
+}
diff --git a/libphobos/libdruntime/gcc/sections/elf_shared.d b/libphobos/libdruntime/gcc/sections/elf.d
index 59e2dd6..3480fb9 100644
--- a/libphobos/libdruntime/gcc/sections/elf_shared.d
+++ b/libphobos/libdruntime/gcc/sections/elf.d
@@ -1,5 +1,5 @@
// ELF-specific support for sections with shared libraries.
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+// Copyright (C) 2019-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
@@ -20,8 +20,10 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
-module gcc.sections.elf_shared;
+module gcc.sections.elf;
+version (MIPS32) version = MIPS_Any;
+version (MIPS64) version = MIPS_Any;
version (RISCV32) version = RISCV_Any;
version (RISCV64) version = RISCV_Any;
version (S390) version = IBMZ_Any;
@@ -31,13 +33,13 @@ version (CRuntime_Glibc) enum SharedELF = true;
else version (CRuntime_Musl) enum SharedELF = true;
else version (FreeBSD) enum SharedELF = true;
else version (NetBSD) enum SharedELF = true;
+else version (OpenBSD) enum SharedELF = true;
else version (DragonFlyBSD) enum SharedELF = true;
else version (CRuntime_UClibc) enum SharedELF = true;
else version (Solaris) enum SharedELF = true;
else enum SharedELF = false;
static if (SharedELF):
-// debug = PRINTF;
import core.memory;
import core.stdc.config;
import core.stdc.stdio;
@@ -61,6 +63,12 @@ else version (NetBSD)
import core.sys.netbsd.sys.elf;
import core.sys.netbsd.sys.link_elf;
}
+else version (OpenBSD)
+{
+ import core.sys.openbsd.dlfcn;
+ import core.sys.openbsd.sys.elf;
+ import core.sys.openbsd.sys.link_elf;
+}
else version (DragonFlyBSD)
{
import core.sys.dragonflybsd.dlfcn;
@@ -79,25 +87,14 @@ else
static assert(0, "unimplemented");
}
import core.sys.posix.pthread;
-import gcc.builtins;
-import gcc.config;
import rt.deh;
import rt.dmain2;
import rt.minfo;
import rt.util.container.array;
import rt.util.container.hashtab;
-
-/****
- * Asserts the specified condition, independent from -release, by abort()ing.
- * Regular assertions throw an AssertError and thus require an initialized
- * GC, which isn't the case (yet or anymore) for the startup/shutdown code in
- * this module (called by CRT ctors/dtors etc.).
- */
-private void safeAssert(bool condition, scope string msg, size_t line = __LINE__) @nogc nothrow @safe
-{
- import core.internal.abort;
- condition || abort(msg, __FILE__, line);
-}
+import gcc.builtins;
+import gcc.config;
+import gcc.sections.common;
alias DSO SectionGroup;
struct DSO
@@ -132,11 +129,6 @@ struct DSO
return _moduleGroup;
}
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- return null;
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
@@ -175,22 +167,12 @@ private:
__gshared bool _isRuntimeInitialized;
-version (FreeBSD) private __gshared void* dummy_ref;
-version (DragonFlyBSD) private __gshared void* dummy_ref;
-version (NetBSD) private __gshared void* dummy_ref;
-version (Solaris) private __gshared void* dummy_ref;
-
/****
* Gets called on program startup just before GC is initialized.
*/
void initSections() nothrow @nogc
{
_isRuntimeInitialized = true;
- // reference symbol to support weak linkage
- version (FreeBSD) dummy_ref = &_d_dso_registry;
- version (DragonFlyBSD) dummy_ref = &_d_dso_registry;
- version (NetBSD) dummy_ref = &_d_dso_registry;
- version (Solaris) dummy_ref = &_d_dso_registry;
}
@@ -206,6 +188,9 @@ alias ScanDG = void delegate(void* pbeg, void* pend) nothrow;
version (Shared)
{
+ import gcc.sections : pinLoadedLibraries, unpinLoadedLibraries,
+ inheritLoadedLibraries, cleanupLoadedLibraries;
+
/***
* Called once per thread; returns array of thread local storage ranges
*/
@@ -236,7 +221,17 @@ version (Shared)
}
}
+ size_t sizeOfTLS() nothrow @nogc
+ {
+ auto tdsos = initTLSRanges();
+ size_t sum;
+ foreach (ref tdso; *tdsos)
+ sum += tdso._tlsRange.length;
+ return sum;
+ }
+
// interface for core.thread to inherit loaded libraries
+ pragma(mangle, gcc.sections.pinLoadedLibraries.mangleof)
void* pinLoadedLibraries() nothrow @nogc
{
auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);
@@ -255,6 +250,7 @@ version (Shared)
return res;
}
+ pragma(mangle, gcc.sections.unpinLoadedLibraries.mangleof)
void unpinLoadedLibraries(void* p) nothrow @nogc
{
auto pary = cast(Array!(ThreadDSO)*)p;
@@ -274,6 +270,7 @@ version (Shared)
// Called before TLS ctors are ran, copy over the loaded libraries
// of the parent thread.
+ pragma(mangle, gcc.sections.inheritLoadedLibraries.mangleof)
void inheritLoadedLibraries(void* p) nothrow @nogc
{
safeAssert(_loadedDSOs.empty, "DSOs have already been registered for this thread.");
@@ -287,6 +284,7 @@ version (Shared)
}
// Called after all TLS dtors ran, decrements all remaining dlopen refs.
+ pragma(mangle, gcc.sections.cleanupLoadedLibraries.mangleof)
void cleanupLoadedLibraries() nothrow @nogc
{
foreach (ref tdso; _loadedDSOs)
@@ -337,6 +335,15 @@ else
dg(rng.ptr, rng.ptr + rng.length);
}
}
+
+ size_t sizeOfTLS() nothrow @nogc
+ {
+ auto rngs = initTLSRanges();
+ size_t sum;
+ foreach (rng; *rngs)
+ sum += rng.length;
+ return sum;
+ }
}
private:
@@ -383,12 +390,6 @@ version (Shared)
*/
__gshared pthread_mutex_t _handleToDSOMutex;
@property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow { __gshared HashTab!(void*, DSO*) x; return x; }
-
- /*
- * Section in executable that contains copy relocations.
- * Might be null when druntime is dynamically loaded by a C host.
- */
- __gshared const(void)[] _copyRelocSection;
}
else
{
@@ -694,20 +695,22 @@ version (Shared)
@nogc nothrow:
link_map* linkMapForHandle(void* handle)
{
- link_map* map;
- const success = dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0;
- safeAssert(success, "Failed to get DSO info.");
- return map;
+ static if (__traits(compiles, RTLD_DI_LINKMAP))
+ {
+ link_map* map;
+ const success = dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0;
+ safeAssert(success, "Failed to get DSO info.");
+ return map;
+ }
+ else version (OpenBSD)
+ {
+ safeAssert(handle !is null, "Failed to get DSO info.");
+ return cast(link_map*)handle;
+ }
+ else
+ static assert(0, "unimplemented");
}
- link_map* exeLinkMap(link_map* map)
- {
- safeAssert(map !is null, "Invalid link_map.");
- while (map.l_prev !is null)
- map = map.l_prev;
- return map;
- }
-
DSO* dsoForHandle(void* handle)
{
DSO* pdso;
@@ -763,6 +766,8 @@ version (Shared)
// in glibc: #define DL_RO_DYN_SECTION 1
version (RISCV_Any)
strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
+ else version (MIPS_Any)
+ strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
else
strtab = cast(const(char)*)dyn.d_un.d_ptr;
}
@@ -770,6 +775,8 @@ version (Shared)
strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
else version (NetBSD)
strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
+ else version (OpenBSD)
+ strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
else version (DragonFlyBSD)
strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
else version (Solaris)
@@ -799,9 +806,21 @@ version (Shared)
void* handleForName(const char* name)
{
- auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY);
- version (Solaris) { }
- else if (handle !is null) .dlclose(handle); // drop reference count
+ version (Solaris) enum refCounted = false;
+ else version (OpenBSD) enum refCounted = false;
+ else enum refCounted = true;
+
+ static if (__traits(compiles, RTLD_NOLOAD))
+ enum flags = (RTLD_NOLOAD | RTLD_LAZY);
+ else
+ enum flags = RTLD_LAZY;
+
+ auto handle = .dlopen(name, flags);
+ static if (refCounted)
+ {
+ if (handle !is null)
+ .dlclose(handle); // drop reference count
+ }
return handle;
}
}
@@ -895,6 +914,7 @@ bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc
{
version (linux) enum IterateManually = true;
else version (NetBSD) enum IterateManually = true;
+ else version (OpenBSD) enum IterateManually = true;
else version (Solaris) enum IterateManually = true;
else enum IterateManually = false;
@@ -954,29 +974,6 @@ bool findSegmentForAddr(in ref dl_phdr_info info, in void* addr, ElfW!"Phdr"* re
return false;
}
-version (linux) import core.sys.linux.errno : program_invocation_name;
-// should be in core.sys.freebsd.stdlib
-version (FreeBSD) extern(C) const(char)* getprogname() nothrow @nogc;
-version (DragonFlyBSD) extern(C) const(char)* getprogname() nothrow @nogc;
-version (NetBSD) extern(C) const(char)* getprogname() nothrow @nogc;
-version (Solaris) extern(C) const(char)* getprogname() nothrow @nogc;
-
-@property const(char)* progname() nothrow @nogc
-{
- version (linux) return program_invocation_name;
- version (FreeBSD) return getprogname();
- version (DragonFlyBSD) return getprogname();
- version (NetBSD) return getprogname();
- version (Solaris) return getprogname();
-}
-
-const(char)[] dsoName(const char* dlpi_name) nothrow @nogc
-{
- // the main executable doesn't have a name in its dlpi_name field
- const char* p = dlpi_name[0] != 0 ? dlpi_name : progname;
- return p[0 .. strlen(p)];
-}
-
/**************************
* Input:
* addr an internal address of a DSO
diff --git a/libphobos/libdruntime/gcc/sections/macho.d b/libphobos/libdruntime/gcc/sections/macho.d
new file mode 100644
index 0000000..3ce58a5
--- /dev/null
+++ b/libphobos/libdruntime/gcc/sections/macho.d
@@ -0,0 +1,738 @@
+// MACHO-specific support for sections.
+// Copyright (C) 2021 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections.macho;
+
+version (OSX):
+
+import core.memory;
+import core.stdc.stdlib;
+import core.sys.darwin.dlfcn;
+import core.sys.darwin.mach.dyld;
+import core.sys.darwin.mach.getsect;
+import core.sys.posix.pthread;
+import rt.minfo;
+import rt.util.container.array;
+import rt.util.container.hashtab;
+import gcc.sections.common;
+
+version (GNU_EMUTLS)
+ import gcc.emutls;
+
+alias DSO SectionGroup;
+struct DSO
+{
+ static int opApply(scope int delegate(ref DSO) dg)
+ {
+ foreach (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ static int opApplyReverse(scope int delegate(ref DSO) dg)
+ {
+ foreach_reverse (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
+ {
+ return _moduleGroup.modules;
+ }
+
+ @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
+ {
+ return _moduleGroup;
+ }
+
+ @property inout(void[])[] gcRanges() inout nothrow @nogc
+ {
+ return _gcRanges[];
+ }
+
+private:
+
+ invariant()
+ {
+ safeAssert(_moduleGroup.modules.length > 0, "No modules for DSO.");
+ }
+
+ void** _slot;
+ ModuleGroup _moduleGroup;
+ Array!(void[]) _gcRanges;
+
+ version (Shared)
+ {
+ Array!(void[]) _codeSegments; // array of code segments
+ Array!(DSO*) _deps; // D libraries needed by this DSO
+ void* _handle; // corresponding handle
+ }
+}
+
+/****
+ * Boolean flag set to true while the runtime is initialized.
+ */
+__gshared bool _isRuntimeInitialized;
+
+/****
+ * Gets called on program startup just before GC is initialized.
+ */
+void initSections() nothrow @nogc
+{
+ _isRuntimeInitialized = true;
+}
+
+/***
+ * Gets called on program shutdown just after GC is terminated.
+ */
+void finiSections() nothrow @nogc
+{
+ _isRuntimeInitialized = false;
+}
+
+alias ScanDG = void delegate(void* pbeg, void* pend) nothrow;
+
+version (Shared)
+{
+ import gcc.sections : pinLoadedLibraries, unpinLoadedLibraries,
+ inheritLoadedLibraries, cleanupLoadedLibraries;
+
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(ThreadDSO)* initTLSRanges() @nogc nothrow
+ {
+ return &_loadedDSOs();
+ }
+
+ void finiTLSRanges(Array!(ThreadDSO)* tdsos) @nogc nothrow
+ {
+ // Nothing to do here. tdsos used to point to the _loadedDSOs instance
+ // in the dying thread's TLS segment and as such is not valid anymore.
+ // The memory for the array contents was already reclaimed in
+ // cleanupLoadedLibraries().
+ }
+
+ void scanTLSRanges(Array!(ThreadDSO)* tdsos, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+
+ // interface for core.thread to inherit loaded libraries
+ pragma(mangle, gcc.sections.pinLoadedLibraries.mangleof)
+ void* pinLoadedLibraries() nothrow @nogc
+ {
+ auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);
+ res.length = _loadedDSOs.length;
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ (*res)[i] = tdso;
+ if (tdso._addCnt)
+ {
+ // Increment the dlopen ref for explicitly loaded libraries to pin them.
+ const success = .dlopen(nameForDSO(tdso._pdso), RTLD_LAZY) !is null;
+ safeAssert(success, "Failed to increment dlopen ref.");
+ (*res)[i]._addCnt = 1; // new array takes over the additional ref count
+ }
+ }
+ return res;
+ }
+
+ pragma(mangle, gcc.sections.unpinLoadedLibraries.mangleof)
+ void unpinLoadedLibraries(void* p) nothrow @nogc
+ {
+ auto pary = cast(Array!(ThreadDSO)*)p;
+ // In case something failed we need to undo the pinning.
+ foreach (ref tdso; *pary)
+ {
+ if (tdso._addCnt)
+ {
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid library handle.");
+ .dlclose(handle);
+ }
+ }
+ pary.reset();
+ .free(pary);
+ }
+
+ // Called before TLS ctors are ran, copy over the loaded libraries
+ // of the parent thread.
+ pragma(mangle, gcc.sections.inheritLoadedLibraries.mangleof)
+ void inheritLoadedLibraries(void* p) nothrow @nogc
+ {
+ safeAssert(_loadedDSOs.empty, "DSOs have already been registered for this thread.");
+ _loadedDSOs.swap(*cast(Array!(ThreadDSO)*)p);
+ .free(p);
+ }
+
+ // Called after all TLS dtors ran, decrements all remaining dlopen refs.
+ pragma(mangle, gcc.sections.cleanupLoadedLibraries.mangleof)
+ void cleanupLoadedLibraries() nothrow @nogc
+ {
+ foreach (ref tdso; _loadedDSOs)
+ {
+ if (tdso._addCnt == 0) continue;
+
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid DSO handle.");
+ for (; tdso._addCnt > 0; --tdso._addCnt)
+ .dlclose(handle);
+ }
+
+ // Free the memory for the array contents.
+ _loadedDSOs.reset();
+ }
+}
+else
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(void[])* initTLSRanges() nothrow @nogc
+ {
+ return null;
+ }
+
+ void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc
+ {
+ }
+
+ void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+}
+
+private:
+
+version (Shared)
+{
+ /*
+ * Array of thread local DSO metadata for all libraries loaded and
+ * initialized in this thread.
+ *
+ * Note:
+ * A newly spawned thread will inherit these libraries.
+ * Note:
+ * We use an array here to preserve the order of
+ * initialization. If that became a performance issue, we
+ * could use a hash table and enumerate the DSOs during
+ * loading so that the hash table values could be sorted when
+ * necessary.
+ */
+ struct ThreadDSO
+ {
+ DSO* _pdso;
+ static if (_pdso.sizeof == 8) uint _refCnt, _addCnt;
+ else static if (_pdso.sizeof == 4) ushort _refCnt, _addCnt;
+ else static assert(0, "unimplemented");
+ alias _pdso this;
+ }
+
+ @property ref Array!(ThreadDSO) _loadedDSOs() @nogc nothrow
+ {
+ static Array!(ThreadDSO) x;
+ return x;
+ }
+
+ /*
+ * Set to true during rt_loadLibrary/rt_unloadLibrary calls.
+ */
+ bool _rtLoading;
+
+ /*
+ * Hash table to map the native handle (as returned by dlopen)
+ * to the corresponding DSO*, protected by a mutex.
+ */
+ __gshared pthread_mutex_t _handleToDSOMutex;
+ @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow
+ {
+ __gshared HashTab!(void*, DSO*) x;
+ return x;
+ }
+}
+else
+{
+ /*
+ * Static DSOs loaded by the runtime linker. This includes the
+ * executable. These can't be unloaded.
+ */
+ @property ref Array!(DSO*) _loadedDSOs() @nogc nothrow
+ {
+ __gshared Array!(DSO*) x;
+ return x;
+ }
+
+ enum _rtLoading = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Compiler to runtime interface.
+///////////////////////////////////////////////////////////////////////////////
+
+struct MachHeader
+{
+ const(mach_header)* header; // the mach header of the image
+ intptr_t slide; // virtural memory address slide amount
+}
+
+/****
+ * This data structure is generated by the compiler, and then passed to
+ * _d_dso_registry().
+ */
+struct CompilerDSOData
+{
+ size_t _version; // currently 1
+ void** _slot; // can be used to store runtime data
+ immutable(object.ModuleInfo*)* _minfo_beg, _minfo_end; // array of modules in this object file
+}
+
+T[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; }
+
+/* For each shared library and executable, the compiler generates code that
+ * sets up CompilerDSOData and calls _d_dso_registry().
+ * A pointer to that code is inserted into both the .ctors and .dtors
+ * segment so it gets called by the loader on startup and shutdown.
+ */
+extern(C) void _d_dso_registry(CompilerDSOData* data)
+{
+ // only one supported currently
+ safeAssert(data._version >= 1, "Incompatible compiler-generated DSO data version.");
+
+ // no backlink => register
+ if (*data._slot is null)
+ {
+ immutable firstDSO = _loadedDSOs.empty;
+ if (firstDSO) initLocks();
+
+ DSO* pdso = cast(DSO*).calloc(1, DSO.sizeof);
+ assert(typeid(DSO).initializer().ptr is null);
+ pdso._slot = data._slot;
+ *data._slot = pdso; // store backlink in library record
+
+ pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end));
+
+ MachHeader header = void;
+ const headerFound = findImageHeaderForAddr(data._slot, header);
+ safeAssert(headerFound, "Failed to find image header.");
+
+ scanSegments(header, pdso);
+
+ version (Shared)
+ {
+ auto handle = handleForAddr(data._slot);
+
+ getDependencies(header, pdso._deps);
+ pdso._handle = handle;
+ setDSOForHandle(pdso, pdso._handle);
+
+ if (!_rtLoading)
+ {
+ /* This DSO was not loaded by rt_loadLibrary which
+ * happens for all dependencies of an executable or
+ * the first dlopen call from a C program.
+ * In this case we add the DSO to the _loadedDSOs of this
+ * thread with a refCnt of 1 and call the TlsCtors.
+ */
+ immutable ushort refCnt = 1, addCnt = 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ }
+ }
+ else
+ {
+ foreach (p; _loadedDSOs)
+ safeAssert(p !is pdso, "DSO already registered.");
+ _loadedDSOs.insertBack(pdso);
+ }
+
+ // don't initialize modules before rt_init was called
+ if (_isRuntimeInitialized)
+ {
+ registerGCRanges(pdso);
+ // rt_loadLibrary will run tls ctors, so do this only for dlopen
+ immutable runTlsCtors = !_rtLoading;
+ runModuleConstructors(pdso, runTlsCtors);
+ }
+ }
+ // has backlink => unregister
+ else
+ {
+ DSO* pdso = cast(DSO*)*data._slot;
+ *data._slot = null;
+
+ // don't finalizes modules after rt_term was called (see Bugzilla 11378)
+ if (_isRuntimeInitialized)
+ {
+ // rt_unloadLibrary already ran tls dtors, so do this only for dlclose
+ immutable runTlsDtors = !_rtLoading;
+ runModuleDestructors(pdso, runTlsDtors);
+ unregisterGCRanges(pdso);
+ // run finalizers after module dtors (same order as in rt_term)
+ version (Shared) runFinalizers(pdso);
+ }
+
+ version (Shared)
+ {
+ if (!_rtLoading)
+ {
+ /* This DSO was not unloaded by rt_unloadLibrary so we
+ * have to remove it from _loadedDSOs here.
+ */
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ if (tdso._pdso == pdso)
+ {
+ _loadedDSOs.remove(i);
+ break;
+ }
+ }
+ }
+
+ unsetDSOForHandle(pdso, pdso._handle);
+ }
+ else
+ {
+ // static DSOs are unloaded in reverse order
+ safeAssert(pdso == _loadedDSOs.back, "DSO being unregistered isn't current last one.");
+ _loadedDSOs.popBack();
+ }
+
+ freeDSO(pdso);
+
+ // last DSO being unloaded => shutdown registry
+ if (_loadedDSOs.empty)
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_destroy();
+ version (Shared)
+ {
+ safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs.");
+ _handleToDSO.reset();
+ }
+ finiLocks();
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// dynamic loading
+///////////////////////////////////////////////////////////////////////////////
+
+// Shared D libraries are only supported when linking against a shared druntime library.
+
+version (Shared)
+{
+ ThreadDSO* findThreadDSO(DSO* pdso) nothrow @nogc
+ {
+ foreach (ref tdata; _loadedDSOs)
+ if (tdata._pdso == pdso) return &tdata;
+ return null;
+ }
+
+ void incThreadRef(DSO* pdso, bool incAdd)
+ {
+ if (auto tdata = findThreadDSO(pdso)) // already initialized
+ {
+ if (incAdd && ++tdata._addCnt > 1) return;
+ ++tdata._refCnt;
+ }
+ else
+ {
+ foreach (dep; pdso._deps)
+ incThreadRef(dep, false);
+ immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ pdso._moduleGroup.runTlsCtors();
+ }
+ }
+
+ void decThreadRef(DSO* pdso, bool decAdd)
+ {
+ auto tdata = findThreadDSO(pdso);
+ safeAssert(tdata !is null, "Failed to find thread DSO.");
+ safeAssert(!decAdd || tdata._addCnt > 0, "Mismatching rt_unloadLibrary call.");
+
+ if (decAdd && --tdata._addCnt > 0) return;
+ if (--tdata._refCnt > 0) return;
+
+ pdso._moduleGroup.runTlsDtors();
+ foreach (i, ref td; _loadedDSOs)
+ if (td._pdso == pdso) _loadedDSOs.remove(i);
+ foreach (dep; pdso._deps)
+ decThreadRef(dep, false);
+ }
+
+ extern(C) void* rt_loadLibrary(const char* name)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+
+ auto handle = .dlopen(name, RTLD_LAZY);
+ if (handle is null) return null;
+
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ incThreadRef(pdso, true);
+ return handle;
+ }
+
+ extern(C) int rt_unloadLibrary(void* handle)
+ {
+ if (handle is null) return false;
+
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ decThreadRef(pdso, true);
+ return .dlclose(handle) == 0;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// helper functions
+///////////////////////////////////////////////////////////////////////////////
+
+void initLocks() nothrow @nogc
+{
+ version (Shared)
+ !pthread_mutex_init(&_handleToDSOMutex, null) || assert(0);
+}
+
+void finiLocks() nothrow @nogc
+{
+ version (Shared)
+ !pthread_mutex_destroy(&_handleToDSOMutex) || assert(0);
+}
+
+void runModuleConstructors(DSO* pdso, bool runTlsCtors)
+{
+ pdso._moduleGroup.sortCtors();
+ pdso._moduleGroup.runCtors();
+ if (runTlsCtors) pdso._moduleGroup.runTlsCtors();
+}
+
+void runModuleDestructors(DSO* pdso, bool runTlsDtors)
+{
+ if (runTlsDtors) pdso._moduleGroup.runTlsDtors();
+ pdso._moduleGroup.runDtors();
+}
+
+void registerGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.addRange(rng.ptr, rng.length);
+}
+
+void unregisterGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.removeRange(rng.ptr);
+}
+
+version (Shared) void runFinalizers(DSO* pdso)
+{
+ foreach (seg; pdso._codeSegments)
+ GC.runFinalizers(seg);
+}
+
+void freeDSO(DSO* pdso) nothrow @nogc
+{
+ pdso._gcRanges.reset();
+ version (Shared)
+ {
+ pdso._codeSegments.reset();
+ pdso._deps.reset();
+ pdso._handle = null;
+ }
+ .free(pdso);
+}
+
+version (Shared)
+{
+@nogc nothrow:
+ const(char)* nameForDSO(in DSO* pdso)
+ {
+ Dl_info info = void;
+ const success = dladdr(pdso._slot, &info) != 0;
+ safeAssert(success, "Failed to get DSO info.");
+ return info.dli_fname;
+ }
+
+ DSO* dsoForHandle(void* handle)
+ {
+ DSO* pdso;
+ !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);
+ if (auto ppdso = handle in _handleToDSO)
+ pdso = *ppdso;
+ !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0);
+ return pdso;
+ }
+
+ void setDSOForHandle(DSO* pdso, void* handle)
+ {
+ !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);
+ safeAssert(handle !in _handleToDSO, "DSO already registered.");
+ _handleToDSO[handle] = pdso;
+ !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0);
+ }
+
+ void unsetDSOForHandle(DSO* pdso, void* handle)
+ {
+ !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);
+ safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO.");
+ _handleToDSO.remove(handle);
+ !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0);
+ }
+
+ void getDependencies(in MachHeader info, ref Array!(DSO*) deps)
+ {
+ // FIXME: Not implemented yet.
+ }
+
+ void* handleForName(const char* name)
+ {
+ auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY);
+ if (handle !is null) .dlclose(handle); // drop reference count
+ return handle;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Mach-O program header iteration
+///////////////////////////////////////////////////////////////////////////////
+
+/************
+ * Scan segments in the image header and store
+ * the writeable data segments in *pdso.
+ */
+
+void scanSegments(in MachHeader info, DSO* pdso)
+{
+ foreach (e; dataSegs)
+ {
+ auto sect = getSection(info.header, info.slide, e.seg.ptr, e.sect.ptr);
+ if (sect != null)
+ pdso._gcRanges.insertBack((cast(void*)sect.ptr)[0 .. sect.length]);
+ }
+
+ version (Shared)
+ {
+ void[] text = getSection(info.header, info.slide, "__TEXT", "__text");
+ if (!text)
+ assert(0, "Failed to get text section.");
+ pdso._codeSegments.insertBack(text);
+ }
+}
+
+/**************************
+ * Input:
+ * result where the output is to be written
+ * Returns:
+ * true if found, and *result is filled in
+ */
+
+bool findImageHeaderForAddr(in void* addr, out MachHeader result)
+{
+ Dl_info info;
+ if (dladdr(addr, &info) == 0)
+ return false;
+
+ foreach (i; 0 .. _dyld_image_count())
+ {
+ if (info.dli_fbase == _dyld_get_image_header(i))
+ {
+ result.header = cast(const(mach_header)*)info.dli_fbase;
+ result.slide = _dyld_get_image_vmaddr_slide(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+/**************************
+ * Input:
+ * addr an internal address of a DSO
+ * Returns:
+ * the dlopen handle for that DSO or null if addr is not within a loaded DSO
+ */
+version (Shared) void* handleForAddr(void* addr) nothrow @nogc
+{
+ Dl_info info = void;
+ if (dladdr(addr, &info) != 0)
+ return handleForName(info.dli_fname);
+ return null;
+}
+
+struct SegRef
+{
+ string seg;
+ string sect;
+}
+
+static immutable SegRef[] dataSegs = [{SEG_DATA, SECT_DATA},
+ {SEG_DATA, SECT_BSS},
+ {SEG_DATA, SECT_COMMON}];
+
+/**
+ * Returns the section for the named section in the named segment
+ * for the mach_header pointer passed, or null if not found.
+ */
+ubyte[] getSection(in mach_header* header, intptr_t slide,
+ in char* segmentName, in char* sectionName)
+{
+ version (D_LP64)
+ {
+ assert(header.magic == MH_MAGIC_64);
+ auto sect = getsectbynamefromheader_64(cast(mach_header_64*)header,
+ segmentName,
+ sectionName);
+ }
+ else
+ {
+ assert(header.magic == MH_MAGIC);
+ auto sect = getsectbynamefromheader(header,
+ segmentName,
+ sectionName);
+ }
+
+ if (sect !is null && sect.size > 0)
+ return (cast(ubyte*)sect.addr + slide)[0 .. cast(size_t)sect.size];
+ return null;
+}
diff --git a/libphobos/libdruntime/gcc/sections/osx.d b/libphobos/libdruntime/gcc/sections/osx.d
deleted file mode 100644
index cb02b45..0000000
--- a/libphobos/libdruntime/gcc/sections/osx.d
+++ /dev/null
@@ -1,284 +0,0 @@
-// OSX-specific support for sections.
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-module gcc.sections.osx;
-
-version (OSX):
-
-// debug = PRINTF;
-import core.stdc.stdio;
-import core.stdc.string, core.stdc.stdlib;
-import core.sys.posix.pthread;
-import core.sys.darwin.mach.dyld;
-import core.sys.darwin.mach.getsect;
-import rt.deh, rt.minfo;
-import rt.util.container.array;
-
-struct SectionGroup
-{
- static int opApply(scope int delegate(ref SectionGroup) dg)
- {
- return dg(_sections);
- }
-
- static int opApplyReverse(scope int delegate(ref SectionGroup) dg)
- {
- return dg(_sections);
- }
-
- @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
- {
- return _moduleGroup.modules;
- }
-
- @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
- {
- return _moduleGroup;
- }
-
- @property inout(void[])[] gcRanges() inout nothrow @nogc
- {
- return _gcRanges[];
- }
-
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- return _ehTables[];
- }
-
-private:
- immutable(FuncTable)[] _ehTables;
- ModuleGroup _moduleGroup;
- Array!(void[]) _gcRanges;
- immutable(void)[][2] _tlsImage;
-}
-
-/****
- * Boolean flag set to true while the runtime is initialized.
- */
-__gshared bool _isRuntimeInitialized;
-
-/****
- * Gets called on program startup just before GC is initialized.
- */
-void initSections() nothrow @nogc
-{
- pthread_key_create(&_tlsKey, null);
- _dyld_register_func_for_add_image(&sections_osx_onAddImage);
- _isRuntimeInitialized = true;
-}
-
-/***
- * Gets called on program shutdown just after GC is terminated.
- */
-void finiSections() nothrow @nogc
-{
- _sections._gcRanges.reset();
- pthread_key_delete(_tlsKey);
- _isRuntimeInitialized = false;
-}
-
-void[]* initTLSRanges() nothrow @nogc
-{
- return &getTLSBlock();
-}
-
-void finiTLSRanges(void[]* rng) nothrow @nogc
-{
- .free(rng.ptr);
- .free(rng);
-}
-
-void scanTLSRanges(void[]* rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow
-{
- dg(rng.ptr, rng.ptr + rng.length);
-}
-
-// NOTE: The Mach-O object file format does not allow for thread local
-// storage declarations. So instead we roll our own by putting tls
-// into the __tls_data and the __tlscoal_nt sections.
-//
-// This function is called by the code emitted by the compiler. It
-// is expected to translate an address into the TLS static data to
-// the corresponding address in the TLS dynamic per-thread data.
-
-// NB: the compiler mangles this function as '___tls_get_addr' even though it is extern(D)
-extern(D) void* ___tls_get_addr( void* p )
-{
- immutable off = tlsOffset(p);
- auto tls = getTLSBlockAlloc();
- assert(off < tls.length);
- return tls.ptr + off;
-}
-
-private:
-
-__gshared pthread_key_t _tlsKey;
-
-size_t tlsOffset(void* p)
-in
-{
- assert(_sections._tlsImage[0].ptr !is null ||
- _sections._tlsImage[1].ptr !is null);
-}
-body
-{
- // NOTE: p is an address in the TLS static data emitted by the
- // compiler. If it isn't, something is disastrously wrong.
- immutable off0 = cast(size_t)(p - _sections._tlsImage[0].ptr);
- if (off0 < _sections._tlsImage[0].length)
- {
- return off0;
- }
- immutable off1 = cast(size_t)(p - _sections._tlsImage[1].ptr);
- if (off1 < _sections._tlsImage[1].length)
- {
- size_t sz = (_sections._tlsImage[0].length + 15) & ~cast(size_t)15;
- return sz + off1;
- }
- assert(0);
-}
-
-ref void[] getTLSBlock() nothrow @nogc
-{
- auto pary = cast(void[]*)pthread_getspecific(_tlsKey);
- if (pary is null)
- {
- pary = cast(void[]*).calloc(1, (void[]).sizeof);
- if (pthread_setspecific(_tlsKey, pary) != 0)
- {
- import core.stdc.stdio;
- perror("pthread_setspecific failed with");
- assert(0);
- }
- }
- return *pary;
-}
-
-ref void[] getTLSBlockAlloc()
-{
- auto pary = &getTLSBlock();
- if (!pary.length)
- {
- auto imgs = _sections._tlsImage;
- immutable sz0 = (imgs[0].length + 15) & ~cast(size_t)15;
- immutable sz2 = sz0 + imgs[1].length;
- auto p = .malloc(sz2);
- memcpy(p, imgs[0].ptr, imgs[0].length);
- memcpy(p + sz0, imgs[1].ptr, imgs[1].length);
- *pary = p[0 .. sz2];
- }
- return *pary;
-}
-
-__gshared SectionGroup _sections;
-
-extern (C) void sections_osx_onAddImage(in mach_header* h, intptr_t slide)
-{
- foreach (e; dataSegs)
- {
- auto sect = getSection(h, slide, e.seg.ptr, e.sect.ptr);
- if (sect != null)
- _sections._gcRanges.insertBack((cast(void*)sect.ptr)[0 .. sect.length]);
- }
-
- auto minfosect = getSection(h, slide, "__DATA", "__minfodata");
- if (minfosect != null)
- {
- // no support for multiple images yet
- // take the sections from the last static image which is the executable
- if (_isRuntimeInitialized)
- {
- fprintf(stderr, "Loading shared libraries isn't yet supported on OSX.\n");
- return;
- }
- else if (_sections.modules.ptr !is null)
- {
- fprintf(stderr, "Shared libraries are not yet supported on OSX.\n");
- }
-
- debug(PRINTF) printf(" minfodata\n");
- auto p = cast(immutable(ModuleInfo*)*)minfosect.ptr;
- immutable len = minfosect.length / (*p).sizeof;
-
- _sections._moduleGroup = ModuleGroup(p[0 .. len]);
- }
-
- auto ehsect = getSection(h, slide, "__DATA", "__deh_eh");
- if (ehsect != null)
- {
- debug(PRINTF) printf(" deh_eh\n");
- auto p = cast(immutable(FuncTable)*)ehsect.ptr;
- immutable len = ehsect.length / (*p).sizeof;
-
- _sections._ehTables = p[0 .. len];
- }
-
- auto tlssect = getSection(h, slide, "__DATA", "__tls_data");
- if (tlssect != null)
- {
- debug(PRINTF) printf(" tls_data %p %p\n", tlssect.ptr, tlssect.ptr + tlssect.length);
- _sections._tlsImage[0] = (cast(immutable(void)*)tlssect.ptr)[0 .. tlssect.length];
- }
-
- auto tlssect2 = getSection(h, slide, "__DATA", "__tlscoal_nt");
- if (tlssect2 != null)
- {
- debug(PRINTF) printf(" tlscoal_nt %p %p\n", tlssect2.ptr, tlssect2.ptr + tlssect2.length);
- _sections._tlsImage[1] = (cast(immutable(void)*)tlssect2.ptr)[0 .. tlssect2.length];
- }
-}
-
-struct SegRef
-{
- string seg;
- string sect;
-}
-
-static immutable SegRef[] dataSegs = [{SEG_DATA, SECT_DATA},
- {SEG_DATA, SECT_BSS},
- {SEG_DATA, SECT_COMMON}];
-
-ubyte[] getSection(in mach_header* header, intptr_t slide,
- in char* segmentName, in char* sectionName)
-{
- version (X86)
- {
- assert(header.magic == MH_MAGIC);
- auto sect = getsectbynamefromheader(header,
- segmentName,
- sectionName);
- }
- else version (X86_64)
- {
- assert(header.magic == MH_MAGIC_64);
- auto sect = getsectbynamefromheader_64(cast(mach_header_64*)header,
- segmentName,
- sectionName);
- }
- else
- static assert(0, "unimplemented");
-
- if (sect !is null && sect.size > 0)
- return (cast(ubyte*)sect.addr + slide)[0 .. cast(size_t)sect.size];
- return null;
-}
diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d
index 81fa58a..1e887cd 100644
--- a/libphobos/libdruntime/gcc/sections/package.d
+++ b/libphobos/libdruntime/gcc/sections/package.d
@@ -1,5 +1,5 @@
// Run-time support for retrieving platform-specific sections.
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+// Copyright (C) 2019-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
@@ -22,27 +22,31 @@
module gcc.sections;
-version (CRuntime_Glibc)
- public import gcc.sections.elf_shared;
-else version (CRuntime_Musl)
- public import gcc.sections.elf_shared;
-else version (CRuntime_UClibc)
- public import gcc.sections.elf_shared;
-else version (FreeBSD)
- public import gcc.sections.elf_shared;
-else version (NetBSD)
- public import gcc.sections.elf_shared;
-else version (DragonFlyBSD)
- public import gcc.sections.elf_shared;
-else version (Solaris)
- public import gcc.sections.elf_shared;
-else version (OSX)
- public import gcc.sections.osx;
-else version (CRuntime_DigitalMars)
- public import gcc.sections.win32;
-else version (CRuntime_Microsoft)
- public import gcc.sections.win64;
-else version (CRuntime_Bionic)
- public import gcc.sections.android;
+version (CRuntime_Glibc) version = SectionsElf;
+version (CRuntime_Musl) version = SectionsElf;
+version (CRuntime_UClibc) version = SectionsElf;
+version (FreeBSD) version = SectionsElf;
+version (NetBSD) version = SectionsElf;
+version (OpenBSD) version = SectionsElf;
+version (DragonFlyBSD) version = SectionsElf;
+version (Solaris) version = SectionsElf;
+version (OSX) version = SectionsMacho;
+version (Windows) version = SectionsPeCoff;
+
+version (SectionsElf)
+ public import gcc.sections.elf;
+else version (SectionsMacho)
+ public import gcc.sections.macho;
+else version (SectionsPeCoff)
+ public import gcc.sections.pecoff;
else
static assert(0, "unimplemented");
+
+version (Shared)
+{
+ // interface for core.thread to inherit loaded libraries
+ void* pinLoadedLibraries() nothrow @nogc;
+ void unpinLoadedLibraries(void* p) nothrow @nogc;
+ void inheritLoadedLibraries(void* p) nothrow @nogc;
+ void cleanupLoadedLibraries() nothrow @nogc;
+}
diff --git a/libphobos/libdruntime/gcc/sections/pecoff.d b/libphobos/libdruntime/gcc/sections/pecoff.d
new file mode 100644
index 0000000..ed0340e
--- /dev/null
+++ b/libphobos/libdruntime/gcc/sections/pecoff.d
@@ -0,0 +1,826 @@
+// PE/COFF-specific support for sections.
+// Copyright (C) 2021 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections.pecoff;
+
+version (Windows):
+
+import core.memory;
+import core.stdc.stdlib;
+import core.sys.windows.winbase;
+import core.sys.windows.windef;
+import core.sys.windows.winnt;
+import rt.minfo;
+import rt.util.container.array;
+import rt.util.container.hashtab;
+import gcc.sections.common;
+
+version (GNU_EMUTLS)
+ import gcc.emutls;
+
+alias DSO SectionGroup;
+struct DSO
+{
+ static int opApply(scope int delegate(ref DSO) dg)
+ {
+ foreach (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ static int opApplyReverse(scope int delegate(ref DSO) dg)
+ {
+ foreach_reverse (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
+ {
+ return _moduleGroup.modules;
+ }
+
+ @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
+ {
+ return _moduleGroup;
+ }
+
+ @property inout(void[])[] gcRanges() inout nothrow @nogc
+ {
+ return _gcRanges[];
+ }
+
+private:
+
+ invariant()
+ {
+ safeAssert(_moduleGroup.modules.length > 0, "No modules for DSO.");
+ }
+
+ void** _slot;
+ ModuleGroup _moduleGroup;
+ Array!(void[]) _gcRanges;
+
+ version (Shared)
+ {
+ Array!(void[]) _codeSegments; // array of code segments
+ Array!(DSO*) _deps; // D libraries needed by this DSO
+ void* _handle; // corresponding handle
+ }
+}
+
+/****
+ * Boolean flag set to true while the runtime is initialized.
+ */
+__gshared bool _isRuntimeInitialized;
+
+/****
+ * Gets called on program startup just before GC is initialized.
+ */
+void initSections() nothrow @nogc
+{
+ _isRuntimeInitialized = true;
+}
+
+/***
+ * Gets called on program shutdown just after GC is terminated.
+ */
+void finiSections() nothrow @nogc
+{
+ _isRuntimeInitialized = false;
+}
+
+alias ScanDG = void delegate(void* pbeg, void* pend) nothrow;
+
+version (Shared)
+{
+ import gcc.sections : pinLoadedLibraries, unpinLoadedLibraries,
+ inheritLoadedLibraries, cleanupLoadedLibraries;
+
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(ThreadDSO)* initTLSRanges() @nogc nothrow
+ {
+ return &_loadedDSOs();
+ }
+
+ void finiTLSRanges(Array!(ThreadDSO)* tdsos) @nogc nothrow
+ {
+ // Nothing to do here. tdsos used to point to the _loadedDSOs instance
+ // in the dying thread's TLS segment and as such is not valid anymore.
+ // The memory for the array contents was already reclaimed in
+ // cleanupLoadedLibraries().
+ }
+
+ void scanTLSRanges(Array!(ThreadDSO)* tdsos, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+
+ // interface for core.thread to inherit loaded libraries
+ pragma(mangle, gcc.sections.pinLoadedLibraries.mangleof)
+ void* pinLoadedLibraries() nothrow @nogc
+ {
+ auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);
+ res.length = _loadedDSOs.length;
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ (*res)[i] = tdso;
+ if (tdso._addCnt)
+ {
+ // Increment the DLL ref for explicitly loaded libraries to pin them.
+ char[MAX_PATH] buf;
+ char[] buffer = buf[];
+ const success = .LoadLibraryA(nameForDSO(tdso._pdso, buffer)) !is null;
+ safeAssert(success, "Failed to increment DLL ref.");
+ (*res)[i]._addCnt = 1; // new array takes over the additional ref count
+ }
+ }
+ return res;
+ }
+
+ pragma(mangle, gcc.sections.unpinLoadedLibraries.mangleof)
+ void unpinLoadedLibraries(void* p) nothrow @nogc
+ {
+ auto pary = cast(Array!(ThreadDSO)*)p;
+ // In case something failed we need to undo the pinning.
+ foreach (ref tdso; *pary)
+ {
+ if (tdso._addCnt)
+ {
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid library handle.");
+ .FreeLibrary(handle);
+ }
+ }
+ pary.reset();
+ .free(pary);
+ }
+
+ // Called before TLS ctors are ran, copy over the loaded libraries
+ // of the parent thread.
+ pragma(mangle, gcc.sections.inheritLoadedLibraries.mangleof)
+ void inheritLoadedLibraries(void* p) nothrow @nogc
+ {
+ safeAssert(_loadedDSOs.empty, "DSOs have already been registered for this thread.");
+ _loadedDSOs.swap(*cast(Array!(ThreadDSO)*)p);
+ .free(p);
+ }
+
+ // Called after all TLS dtors ran, decrements all remaining DLL refs.
+ pragma(mangle, gcc.sections.cleanupLoadedLibraries.mangleof)
+ void cleanupLoadedLibraries() nothrow @nogc
+ {
+ foreach (ref tdso; _loadedDSOs)
+ {
+ if (tdso._addCnt == 0) continue;
+
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid DSO handle.");
+ for (; tdso._addCnt > 0; --tdso._addCnt)
+ .FreeLibrary(handle);
+ }
+
+ // Free the memory for the array contents.
+ _loadedDSOs.reset();
+ }
+}
+else
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(void[])* initTLSRanges() nothrow @nogc
+ {
+ return null;
+ }
+
+ void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc
+ {
+ }
+
+ void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+}
+
+private:
+
+version (Shared)
+{
+ /*
+ * Array of thread local DSO metadata for all libraries loaded and
+ * initialized in this thread.
+ *
+ * Note:
+ * A newly spawned thread will inherit these libraries.
+ * Note:
+ * We use an array here to preserve the order of
+ * initialization. If that became a performance issue, we
+ * could use a hash table and enumerate the DSOs during
+ * loading so that the hash table values could be sorted when
+ * necessary.
+ */
+ struct ThreadDSO
+ {
+ DSO* _pdso;
+ static if (_pdso.sizeof == 8) uint _refCnt, _addCnt;
+ else static if (_pdso.sizeof == 4) ushort _refCnt, _addCnt;
+ else static assert(0, "unimplemented");
+ alias _pdso this;
+ }
+
+ @property ref Array!(ThreadDSO) _loadedDSOs() @nogc nothrow
+ {
+ static Array!(ThreadDSO) x;
+ return x;
+ }
+
+ /*
+ * Set to true during rt_loadLibrary/rt_unloadLibrary calls.
+ */
+ bool _rtLoading;
+
+ /*
+ * Hash table to map the native handle (as returned by dlopen)
+ * to the corresponding DSO*, protected by a mutex.
+ */
+ __gshared CRITICAL_SECTION _handleToDSOMutex;
+ @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow
+ {
+ __gshared HashTab!(void*, DSO*) x;
+ return x;
+ }
+}
+else
+{
+ /*
+ * Static DSOs loaded by the runtime linker. This includes the
+ * executable. These can't be unloaded.
+ */
+ @property ref Array!(DSO*) _loadedDSOs() @nogc nothrow
+ {
+ __gshared Array!(DSO*) x;
+ return x;
+ }
+
+ enum _rtLoading = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Compiler to runtime interface.
+///////////////////////////////////////////////////////////////////////////////
+
+/****
+ * This data structure is generated by the compiler, and then passed to
+ * _d_dso_registry().
+ */
+struct CompilerDSOData
+{
+ size_t _version; // currently 1
+ void** _slot; // can be used to store runtime data
+ immutable(object.ModuleInfo*)* _minfo_beg, _minfo_end; // array of modules in this object file
+}
+
+T[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; }
+
+/* For each shared library and executable, the compiler generates code that
+ * sets up CompilerDSOData and calls _d_dso_registry().
+ * A pointer to that code is inserted into both the .ctors and .dtors
+ * segment so it gets called by the loader on startup and shutdown.
+ */
+extern(C) void _d_dso_registry(CompilerDSOData* data)
+{
+ // only one supported currently
+ safeAssert(data._version >= 1, "Incompatible compiler-generated DSO data version.");
+
+ // no backlink => register
+ if (*data._slot is null)
+ {
+ immutable firstDSO = _loadedDSOs.empty;
+ if (firstDSO) initLocks();
+
+ DSO* pdso = cast(DSO*).calloc(1, DSO.sizeof);
+ assert(typeid(DSO).initializer().ptr is null);
+ pdso._slot = data._slot;
+ *data._slot = pdso; // store backlink in library record
+
+ pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end));
+
+ HMODULE handle = void;
+ const moduleFound = findModuleHandleForAddr(data._slot, handle);
+ safeAssert(moduleFound, "Failed to find image header.");
+
+ scanSegments(handle, pdso);
+
+ version (Shared)
+ {
+ getDependencies(handle, pdso._deps);
+ pdso._handle = handle;
+ setDSOForHandle(pdso, pdso._handle);
+
+ if (!_rtLoading)
+ {
+ /* This DSO was not loaded by rt_loadLibrary which
+ * happens for all dependencies of an executable or
+ * the first dlopen call from a C program.
+ * In this case we add the DSO to the _loadedDSOs of this
+ * thread with a refCnt of 1 and call the TlsCtors.
+ */
+ immutable ushort refCnt = 1, addCnt = 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ }
+ }
+ else
+ {
+ foreach (p; _loadedDSOs)
+ safeAssert(p !is pdso, "DSO already registered.");
+ _loadedDSOs.insertBack(pdso);
+ }
+
+ // don't initialize modules before rt_init was called
+ if (_isRuntimeInitialized)
+ {
+ registerGCRanges(pdso);
+ // rt_loadLibrary will run tls ctors, so do this only for dlopen
+ immutable runTlsCtors = !_rtLoading;
+ runModuleConstructors(pdso, runTlsCtors);
+ }
+ }
+ // has backlink => unregister
+ else
+ {
+ DSO* pdso = cast(DSO*)*data._slot;
+ *data._slot = null;
+
+ // don't finalizes modules after rt_term was called (see Bugzilla 11378)
+ if (_isRuntimeInitialized)
+ {
+ // rt_unloadLibrary already ran tls dtors, so do this only for dlclose
+ immutable runTlsDtors = !_rtLoading;
+ runModuleDestructors(pdso, runTlsDtors);
+ unregisterGCRanges(pdso);
+ // run finalizers after module dtors (same order as in rt_term)
+ version (Shared) runFinalizers(pdso);
+ }
+
+ version (Shared)
+ {
+ if (!_rtLoading)
+ {
+ /* This DSO was not unloaded by rt_unloadLibrary so we
+ * have to remove it from _loadedDSOs here.
+ */
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ if (tdso._pdso == pdso)
+ {
+ _loadedDSOs.remove(i);
+ break;
+ }
+ }
+ }
+
+ unsetDSOForHandle(pdso, pdso._handle);
+ }
+ else
+ {
+ // static DSOs are unloaded in reverse order
+ safeAssert(pdso == _loadedDSOs.back, "DSO being unregistered isn't current last one.");
+ _loadedDSOs.popBack();
+ }
+
+ freeDSO(pdso);
+
+ // last DSO being unloaded => shutdown registry
+ if (_loadedDSOs.empty)
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_destroy();
+ version (Shared)
+ {
+ safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs.");
+ _handleToDSO.reset();
+ }
+ finiLocks();
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// dynamic loading
+///////////////////////////////////////////////////////////////////////////////
+
+// Shared D libraries are only supported when linking against a shared druntime library.
+
+version (Shared)
+{
+ ThreadDSO* findThreadDSO(DSO* pdso) nothrow @nogc
+ {
+ foreach (ref tdata; _loadedDSOs)
+ if (tdata._pdso == pdso) return &tdata;
+ return null;
+ }
+
+ void incThreadRef(DSO* pdso, bool incAdd)
+ {
+ if (auto tdata = findThreadDSO(pdso)) // already initialized
+ {
+ if (incAdd && ++tdata._addCnt > 1) return;
+ ++tdata._refCnt;
+ }
+ else
+ {
+ foreach (dep; pdso._deps)
+ incThreadRef(dep, false);
+ immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ pdso._moduleGroup.runTlsCtors();
+ }
+ }
+
+ void decThreadRef(DSO* pdso, bool decAdd)
+ {
+ auto tdata = findThreadDSO(pdso);
+ safeAssert(tdata !is null, "Failed to find thread DSO.");
+ safeAssert(!decAdd || tdata._addCnt > 0, "Mismatching rt_unloadLibrary call.");
+
+ if (decAdd && --tdata._addCnt > 0) return;
+ if (--tdata._refCnt > 0) return;
+
+ pdso._moduleGroup.runTlsDtors();
+ foreach (i, ref td; _loadedDSOs)
+ if (td._pdso == pdso) _loadedDSOs.remove(i);
+ foreach (dep; pdso._deps)
+ decThreadRef(dep, false);
+ }
+}
+
+/***********************************
+ * These are a temporary means of providing a GC hook for DLL use. They may be
+ * replaced with some other similar functionality later.
+ */
+extern (C)
+{
+ void* gc_getProxy();
+ void gc_setProxy(void* p);
+ void gc_clrProxy();
+
+ alias void function(void*) gcSetFn;
+ alias void function() gcClrFn;
+}
+
+/*******************************************
+ * Loads a DLL written in D with the name 'name'.
+ * Returns:
+ * opaque handle to the DLL if successfully loaded
+ * null if failure
+ */
+extern(C) void* rt_loadLibrary(const char* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryA(name));
+}
+
+extern (C) void* rt_loadLibraryW(const wchar_t* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryW(name));
+}
+
+void* initLibrary(void* handle)
+{
+ if (handle is null)
+ return null;
+
+ version (Shared)
+ {
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ incThreadRef(pdso, true);
+ }
+ gcSetFn gcSet = cast(gcSetFn) GetProcAddress(handle, "gc_setProxy");
+ if (gcSet !is null)
+ {
+ // BUG: Set proxy, but too late
+ gcSet(gc_getProxy());
+ }
+ return handle;
+}
+
+/*************************************
+ * Unloads DLL that was previously loaded by rt_loadLibrary().
+ * Input:
+ * handle the handle returned by rt_loadLibrary()
+ * Returns:
+ * 1 succeeded
+ * 0 some failure happened
+ */
+extern(C) int rt_unloadLibrary(void* handle)
+{
+ if (handle is null)
+ return false;
+
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ decThreadRef(pdso, true);
+ }
+ gcClrFn gcClr = cast(gcClrFn) GetProcAddress(handle, "gc_clrProxy");
+ if (gcClr !is null)
+ gcClr();
+ return .FreeLibrary(handle) != 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// helper functions
+///////////////////////////////////////////////////////////////////////////////
+
+void initLocks() nothrow @nogc
+{
+ version (Shared)
+ InitializeCriticalSection(&_handleToDSOMutex);
+}
+
+void finiLocks() nothrow @nogc
+{
+ version (Shared)
+ DeleteCriticalSection(&_handleToDSOMutex);
+}
+
+void runModuleConstructors(DSO* pdso, bool runTlsCtors)
+{
+ pdso._moduleGroup.sortCtors();
+ pdso._moduleGroup.runCtors();
+ if (runTlsCtors) pdso._moduleGroup.runTlsCtors();
+}
+
+void runModuleDestructors(DSO* pdso, bool runTlsDtors)
+{
+ if (runTlsDtors) pdso._moduleGroup.runTlsDtors();
+ pdso._moduleGroup.runDtors();
+}
+
+void registerGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.addRange(rng.ptr, rng.length);
+}
+
+void unregisterGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.removeRange(rng.ptr);
+}
+
+version (Shared) void runFinalizers(DSO* pdso)
+{
+ foreach (seg; pdso._codeSegments)
+ GC.runFinalizers(seg);
+}
+
+void freeDSO(DSO* pdso) nothrow @nogc
+{
+ pdso._gcRanges.reset();
+ version (Shared)
+ {
+ pdso._codeSegments.reset();
+ pdso._deps.reset();
+ pdso._handle = null;
+ }
+ .free(pdso);
+}
+
+version (Shared)
+{
+@nogc nothrow:
+ const(char)* nameForDSO(DSO* pdso, ref char[] buffer)
+ {
+ const success = GetModuleFileNameA(pdso._handle, buffer.ptr, cast(DWORD)buffer.length) != 0;
+ safeAssert(success, "Failed to get DLL name.");
+ return buffer.ptr;
+ }
+
+ DSO* dsoForHandle(in void* handle)
+ {
+ DSO* pdso;
+ .EnterCriticalSection(&_handleToDSOMutex);
+ if (auto ppdso = handle in _handleToDSO)
+ pdso = *ppdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ return pdso;
+ }
+
+ void setDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(handle !in _handleToDSO, "DSO already registered.");
+ _handleToDSO[handle] = pdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void unsetDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO.");
+ _handleToDSO.remove(handle);
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void getDependencies(in HMODULE handle, ref Array!(DSO*) deps)
+ {
+ auto nthdr = getNTHeader(handle);
+ auto import_entry = nthdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+ auto addr = import_entry.VirtualAddress;
+ auto datasize = import_entry.Size;
+
+ if (addr == 0 && datasize == 0)
+ {
+ // Maybe the optional header isn't there, look for the section.
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ addr = section.VirtualAddress;
+ datasize = section.Misc.VirtualSize;
+ break;
+ }
+ if (datasize == 0)
+ return;
+ }
+ else
+ {
+ bool foundSection = false;
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ // Section containing import table has no contents.
+ if (section.Misc.VirtualSize == 0)
+ return;
+ foundSection = true;
+ break;
+ }
+ // There is an import table, but the section containing it could not be found
+ if (!foundSection)
+ return;
+ }
+
+ // Get the names of each DLL
+ for (uint i = 0; i + IMAGE_IMPORT_DESCRIPTOR.sizeof <= datasize;
+ i += IMAGE_IMPORT_DESCRIPTOR.sizeof)
+ {
+ const data = cast(PIMAGE_IMPORT_DESCRIPTOR)(handle + addr + i);
+ if (data.Name == 0)
+ break;
+
+ // dll name of dependency
+ auto name = cast(char*)(handle + data.Name);
+ // get handle without loading the library
+ auto libhandle = handleForName(name);
+ // the runtime linker has already loaded all dependencies
+ safeAssert(handle !is null, "Failed to get library handle.");
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ deps.insertBack(pdso); // append it to the dependencies
+ }
+ }
+
+ void* handleForName(const char* name)
+ {
+ return GetModuleHandleA(name);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PE/COFF program header iteration
+///////////////////////////////////////////////////////////////////////////////
+
+bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc
+{
+ if (name[] != cast(char[])section.Name[0 .. name.length])
+ return false;
+ return name.length == 8 || section.Name[name.length] == 0;
+}
+
+/************
+ * Scan segments in the image header and store
+ * the writeable data segments in *pdso.
+ */
+
+void scanSegments(in HMODULE handle, DSO* pdso) nothrow @nogc
+{
+ foreach (section; getSectionHeader(handle))
+ {
+ // the ".data" image section includes both object file sections ".data" and ".bss"
+ if (compareSectionName(section, ".data"))
+ {
+ auto data = cast(void*)handle + section.VirtualAddress;
+ pdso._gcRanges.insertBack(data[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+
+ version (Shared)
+ {
+ if (compareSectionName(section, ".text"))
+ {
+ auto text = cast(void*)handle + section.VirtualAddress;
+ pdso._codeSegments.insertBack(text[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+ }
+ }
+}
+
+/**************************
+ * Input:
+ * handle where the output is to be written
+ * Returns:
+ * true if found, and *handle is filled in
+ */
+
+bool findModuleHandleForAddr(in void* addr, out HMODULE handle) nothrow @nogc
+{
+ if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ cast(const(wchar)*) addr, &handle))
+ return true;
+
+ return false;
+}
+
+/**
+ * Returns the image NT header for the HMODULE handle passed,
+ * or null if not found.
+ */
+PIMAGE_NT_HEADERS getNTHeader(in HMODULE handle) nothrow @nogc
+{
+ auto doshdr = cast(PIMAGE_DOS_HEADER)handle;
+ if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
+ return null;
+
+ return cast(typeof(return))(cast(void*)doshdr + doshdr.e_lfanew);
+}
+
+/**
+ * Returns the image section header for the HMODULE handle passed,
+ * or null if not found.
+ */
+IMAGE_SECTION_HEADER[] getSectionHeader(in HMODULE handle) nothrow @nogc
+{
+ if (auto nthdr = getNTHeader(handle))
+ {
+ const void* opthdr = &nthdr.OptionalHeader;
+ const offset = nthdr.FileHeader.SizeOfOptionalHeader;
+ const length = nthdr.FileHeader.NumberOfSections;
+ return (cast(PIMAGE_SECTION_HEADER)(opthdr + offset))[0 .. length];
+ }
+ return null;
+}
diff --git a/libphobos/libdruntime/gcc/sections/win32.d b/libphobos/libdruntime/gcc/sections/win32.d
deleted file mode 100644
index fd28c7a..0000000
--- a/libphobos/libdruntime/gcc/sections/win32.d
+++ /dev/null
@@ -1,183 +0,0 @@
-// Win32-specific support for sections.
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-module gcc.sections.win32;
-
-version (CRuntime_DigitalMars):
-
-// debug = PRINTF;
-debug(PRINTF) import core.stdc.stdio;
-import rt.minfo;
-import core.stdc.stdlib : malloc, free;
-
-struct SectionGroup
-{
- static int opApply(scope int delegate(ref SectionGroup) dg)
- {
- return dg(_sections);
- }
-
- static int opApplyReverse(scope int delegate(ref SectionGroup) dg)
- {
- return dg(_sections);
- }
-
- @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
- {
- return _moduleGroup.modules;
- }
-
- @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
- {
- return _moduleGroup;
- }
-
- @property inout(void[])[] gcRanges() inout nothrow @nogc
- {
- return _gcRanges[];
- }
-
-private:
- ModuleGroup _moduleGroup;
- void[][] _gcRanges;
-}
-
-shared(bool) conservative;
-
-void initSections() nothrow @nogc
-{
- _sections._moduleGroup = ModuleGroup(getModuleInfos());
-
- import rt.sections;
- conservative = !scanDataSegPrecisely();
-
- if (conservative)
- {
- _sections._gcRanges = (cast(void[]*) malloc(2 * (void[]).sizeof))[0..2];
-
- auto databeg = cast(void*)&_xi_a;
- auto dataend = cast(void*)_moduleinfo_array.ptr;
- _sections._gcRanges[0] = databeg[0 .. dataend - databeg];
-
- // skip module info and CONST segment
- auto bssbeg = cast(void*)&_edata;
- auto bssend = cast(void*)&_end;
- _sections._gcRanges[1] = bssbeg[0 .. bssend - bssbeg];
- }
- else
- {
- size_t count = &_DPend - &_DPbegin;
- auto ranges = cast(void[]*) malloc(count * (void[]).sizeof);
- size_t r = 0;
- void* prev = null;
- for (size_t i = 0; i < count; i++)
- {
- void* addr = (&_DPbegin)[i];
- if (prev + (void*).sizeof == addr)
- ranges[r-1] = ranges[r-1].ptr[0 .. ranges[r-1].length + (void*).sizeof];
- else
- ranges[r++] = (cast(void**)addr)[0..1];
- prev = addr;
- }
- _sections._gcRanges = ranges[0..r];
- }
-}
-
-void finiSections() nothrow @nogc
-{
- free(_sections._gcRanges.ptr);
-}
-
-void[] initTLSRanges() nothrow @nogc
-{
- auto pbeg = cast(void*)&_tlsstart;
- auto pend = cast(void*)&_tlsend;
- return pbeg[0 .. pend - pbeg];
-}
-
-void finiTLSRanges(void[] rng) nothrow @nogc
-{
-}
-
-void scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow
-{
- if (conservative)
- {
- dg(rng.ptr, rng.ptr + rng.length);
- }
- else
- {
- for (auto p = &_TPbegin; p < &_TPend; )
- {
- uint beg = *p++;
- uint end = beg + cast(uint)((void*).sizeof);
- while (p < &_TPend && *p == end)
- {
- end += (void*).sizeof;
- p++;
- }
- dg(rng.ptr + beg, rng.ptr + end);
- }
- }
-}
-
-private:
-
-__gshared SectionGroup _sections;
-
-// Windows: this gets initialized by minit.asm
-extern(C) __gshared immutable(ModuleInfo*)[] _moduleinfo_array;
-extern(C) void _minit() nothrow @nogc;
-
-immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc
-out (result)
-{
- foreach (m; result)
- assert(m !is null);
-}
-body
-{
- // _minit directly alters the global _moduleinfo_array
- _minit();
- return _moduleinfo_array;
-}
-
-extern(C)
-{
- extern __gshared
- {
- int _xi_a; // &_xi_a just happens to be start of data segment
- int _edata; // &_edata is start of BSS segment
- int _end; // &_end is past end of BSS
-
- void* _DPbegin; // first entry in the array of pointers addresses
- void* _DPend; // &_DPend points after last entry of array
- uint _TPbegin; // first entry in the array of TLS offsets of pointers
- uint _TPend; // &_DPend points after last entry of array
- }
-
- extern
- {
- int _tlsstart;
- int _tlsend;
- }
-}
diff --git a/libphobos/libdruntime/gcc/sections/win64.d b/libphobos/libdruntime/gcc/sections/win64.d
deleted file mode 100644
index 1a4ee98..0000000
--- a/libphobos/libdruntime/gcc/sections/win64.d
+++ /dev/null
@@ -1,321 +0,0 @@
-// Win64-specific support for sections.
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-module gcc.sections.win64;
-
-version (CRuntime_Microsoft):
-
-// debug = PRINTF;
-debug(PRINTF) import core.stdc.stdio;
-import core.stdc.stdlib : malloc, free;
-import rt.deh, rt.minfo;
-
-struct SectionGroup
-{
- static int opApply(scope int delegate(ref SectionGroup) dg)
- {
- return dg(_sections);
- }
-
- static int opApplyReverse(scope int delegate(ref SectionGroup) dg)
- {
- return dg(_sections);
- }
-
- @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
- {
- return _moduleGroup.modules;
- }
-
- @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
- {
- return _moduleGroup;
- }
-
- version (Win64)
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- auto pbeg = cast(immutable(FuncTable)*)&_deh_beg;
- auto pend = cast(immutable(FuncTable)*)&_deh_end;
- return pbeg[0 .. pend - pbeg];
- }
-
- @property inout(void[])[] gcRanges() inout nothrow @nogc
- {
- return _gcRanges[];
- }
-
-private:
- ModuleGroup _moduleGroup;
- void[][] _gcRanges;
-}
-
-shared(bool) conservative;
-
-void initSections() nothrow @nogc
-{
- _sections._moduleGroup = ModuleGroup(getModuleInfos());
-
- // the ".data" image section includes both object file sections ".data" and ".bss"
- void[] dataSection = findImageSection(".data");
- debug(PRINTF) printf("found .data section: [%p,+%llx]\n", dataSection.ptr,
- cast(ulong)dataSection.length);
-
- import rt.sections;
- conservative = !scanDataSegPrecisely();
-
- if (conservative)
- {
- _sections._gcRanges = (cast(void[]*) malloc((void[]).sizeof))[0..1];
- _sections._gcRanges[0] = dataSection;
- }
- else
- {
- size_t count = &_DP_end - &_DP_beg;
- auto ranges = cast(void[]*) malloc(count * (void[]).sizeof);
- size_t r = 0;
- void* prev = null;
- for (size_t i = 0; i < count; i++)
- {
- auto off = (&_DP_beg)[i];
- if (off == 0) // skip zero entries added by incremental linking
- continue; // assumes there is no D-pointer at the very beginning of .data
- void* addr = dataSection.ptr + off;
- debug(PRINTF) printf(" scan %p\n", addr);
- // combine consecutive pointers into single range
- if (prev + (void*).sizeof == addr)
- ranges[r-1] = ranges[r-1].ptr[0 .. ranges[r-1].length + (void*).sizeof];
- else
- ranges[r++] = (cast(void**)addr)[0..1];
- prev = addr;
- }
- _sections._gcRanges = ranges[0..r];
- }
-}
-
-void finiSections() nothrow @nogc
-{
- .free(cast(void*)_sections.modules.ptr);
- .free(_sections._gcRanges.ptr);
-}
-
-void[] initTLSRanges() nothrow @nogc
-{
- void* pbeg;
- void* pend;
- // with VS2017 15.3.1, the linker no longer puts TLS segments into a
- // separate image section. That way _tls_start and _tls_end no
- // longer generate offsets into .tls, but DATA.
- // Use the TEB entry to find the start of TLS instead and read the
- // length from the TLS directory
- version (D_InlineAsm_X86)
- {
- asm @nogc nothrow
- {
- mov EAX, _tls_index;
- mov ECX, FS:[0x2C]; // _tls_array
- mov EAX, [ECX+4*EAX];
- mov pbeg, EAX;
- add EAX, [_tls_used+4]; // end
- sub EAX, [_tls_used+0]; // start
- mov pend, EAX;
- }
- }
- else version (D_InlineAsm_X86_64)
- {
- asm @nogc nothrow
- {
- xor RAX, RAX;
- mov EAX, _tls_index;
- mov RCX, 0x58;
- mov RCX, GS:[RCX]; // _tls_array (immediate value causes fixup)
- mov RAX, [RCX+8*RAX];
- mov pbeg, RAX;
- add RAX, [_tls_used+8]; // end
- sub RAX, [_tls_used+0]; // start
- mov pend, RAX;
- }
- }
- else
- static assert(false, "Architecture not supported.");
-
- return pbeg[0 .. pend - pbeg];
-}
-
-void finiTLSRanges(void[] rng) nothrow @nogc
-{
-}
-
-void scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow
-{
- if (conservative)
- {
- dg(rng.ptr, rng.ptr + rng.length);
- }
- else
- {
- for (auto p = &_TP_beg; p < &_TP_end; )
- {
- uint beg = *p++;
- uint end = beg + cast(uint)((void*).sizeof);
- while (p < &_TP_end && *p == end)
- {
- end += (void*).sizeof;
- p++;
- }
- dg(rng.ptr + beg, rng.ptr + end);
- }
- }
-}
-
-private:
-__gshared SectionGroup _sections;
-
-extern(C)
-{
- extern __gshared void* _minfo_beg;
- extern __gshared void* _minfo_end;
-}
-
-immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc
-out (result)
-{
- foreach (m; result)
- assert(m !is null);
-}
-body
-{
- auto m = (cast(immutable(ModuleInfo*)*)&_minfo_beg)[1 .. &_minfo_end - &_minfo_beg];
- /* Because of alignment inserted by the linker, various null pointers
- * are there. We need to filter them out.
- */
- auto p = m.ptr;
- auto pend = m.ptr + m.length;
-
- // count non-null pointers
- size_t cnt;
- for (; p < pend; ++p)
- {
- if (*p !is null) ++cnt;
- }
-
- auto result = (cast(immutable(ModuleInfo)**).malloc(cnt * size_t.sizeof))[0 .. cnt];
-
- p = m.ptr;
- cnt = 0;
- for (; p < pend; ++p)
- if (*p !is null) result[cnt++] = *p;
-
- return cast(immutable)result;
-}
-
-extern(C)
-{
- /* Symbols created by the compiler/linker and inserted into the
- * object file that 'bracket' sections.
- */
- extern __gshared
- {
- void* __ImageBase;
-
- void* _deh_beg;
- void* _deh_end;
-
- uint _DP_beg;
- uint _DP_end;
- uint _TP_beg;
- uint _TP_end;
-
- void*[2] _tls_used; // start, end
- int _tls_index;
- }
-}
-
-/////////////////////////////////////////////////////////////////////
-
-enum IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ
-
-struct IMAGE_DOS_HEADER // DOS .EXE header
-{
- ushort e_magic; // Magic number
- ushort[29] e_res2; // Reserved ushorts
- int e_lfanew; // File address of new exe header
-}
-
-struct IMAGE_FILE_HEADER
-{
- ushort Machine;
- ushort NumberOfSections;
- uint TimeDateStamp;
- uint PointerToSymbolTable;
- uint NumberOfSymbols;
- ushort SizeOfOptionalHeader;
- ushort Characteristics;
-}
-
-struct IMAGE_NT_HEADERS
-{
- uint Signature;
- IMAGE_FILE_HEADER FileHeader;
- // optional header follows
-}
-
-struct IMAGE_SECTION_HEADER
-{
- char[8] Name = 0;
- union {
- uint PhysicalAddress;
- uint VirtualSize;
- }
- uint VirtualAddress;
- uint SizeOfRawData;
- uint PointerToRawData;
- uint PointerToRelocations;
- uint PointerToLinenumbers;
- ushort NumberOfRelocations;
- ushort NumberOfLinenumbers;
- uint Characteristics;
-}
-
-bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc
-{
- if (name[] != section.Name[0 .. name.length])
- return false;
- return name.length == 8 || section.Name[name.length] == 0;
-}
-
-void[] findImageSection(string name) nothrow @nogc
-{
- if (name.length > 8) // section name from string table not supported
- return null;
- IMAGE_DOS_HEADER* doshdr = cast(IMAGE_DOS_HEADER*) &__ImageBase;
- if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
- return null;
-
- auto nthdr = cast(IMAGE_NT_HEADERS*)(cast(void*)doshdr + doshdr.e_lfanew);
- auto sections = cast(IMAGE_SECTION_HEADER*)(cast(void*)nthdr + IMAGE_NT_HEADERS.sizeof + nthdr.FileHeader.SizeOfOptionalHeader);
- for (ushort i = 0; i < nthdr.FileHeader.NumberOfSections; i++)
- if (compareSectionName (sections[i], name))
- return (cast(void*)&__ImageBase + sections[i].VirtualAddress)[0 .. sections[i].VirtualSize];
-
- return null;
-}
diff --git a/libphobos/libdruntime/gcc/unwind/arm.d b/libphobos/libdruntime/gcc/unwind/arm.d
index 85fa58b..986a532 100644
--- a/libphobos/libdruntime/gcc/unwind/arm.d
+++ b/libphobos/libdruntime/gcc/unwind/arm.d
@@ -1,5 +1,5 @@
// Exception handling and frame unwind runtime interface routines.
-// Copyright (C) 2011-2020 Free Software Foundation, Inc.
+// Copyright (C) 2011-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/gcc/unwind/arm_common.d b/libphobos/libdruntime/gcc/unwind/arm_common.d
index 656b5d4..3124eb0 100644
--- a/libphobos/libdruntime/gcc/unwind/arm_common.d
+++ b/libphobos/libdruntime/gcc/unwind/arm_common.d
@@ -1,5 +1,5 @@
// Exception handling and frame unwind runtime interface routines.
-// Copyright (C) 2011-2020 Free Software Foundation, Inc.
+// Copyright (C) 2011-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/gcc/unwind/c6x.d b/libphobos/libdruntime/gcc/unwind/c6x.d
index e4936b6..5f6516a 100644
--- a/libphobos/libdruntime/gcc/unwind/c6x.d
+++ b/libphobos/libdruntime/gcc/unwind/c6x.d
@@ -1,5 +1,5 @@
// Exception handling and frame unwind runtime interface routines.
-// Copyright (C) 2011-2020 Free Software Foundation, Inc.
+// Copyright (C) 2011-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/gcc/unwind/generic.d b/libphobos/libdruntime/gcc/unwind/generic.d
index 9c164b6..592b3af 100644
--- a/libphobos/libdruntime/gcc/unwind/generic.d
+++ b/libphobos/libdruntime/gcc/unwind/generic.d
@@ -1,5 +1,5 @@
// Exception handling and frame unwind runtime interface routines.
-// Copyright (C) 2011-2020 Free Software Foundation, Inc.
+// Copyright (C) 2011-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
@@ -269,6 +269,6 @@ version (GNU_SEH_Exceptions)
ExceptionCollidedUnwind
}
- extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*,
+ extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*, void*,
_Unwind_Personality_Fn);
}
diff --git a/libphobos/libdruntime/gcc/unwind/package.d b/libphobos/libdruntime/gcc/unwind/package.d
index 3267ed3..0098b41 100644
--- a/libphobos/libdruntime/gcc/unwind/package.d
+++ b/libphobos/libdruntime/gcc/unwind/package.d
@@ -1,5 +1,5 @@
// Exception handling and frame unwind runtime interface routines.
-// Copyright (C) 2011-2020 Free Software Foundation, Inc.
+// Copyright (C) 2011-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
diff --git a/libphobos/libdruntime/gcc/unwind/pe.d b/libphobos/libdruntime/gcc/unwind/pe.d
index 648684e..b9b05cb 100644
--- a/libphobos/libdruntime/gcc/unwind/pe.d
+++ b/libphobos/libdruntime/gcc/unwind/pe.d
@@ -1,5 +1,5 @@
// Exception handling and frame unwind runtime interface routines.
-// Copyright (C) 2011-2020 Free Software Foundation, Inc.
+// Copyright (C) 2011-2021 Free Software Foundation, Inc.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
@@ -103,40 +103,37 @@ _Unwind_Ptr base_of_encoded_value(ubyte encoding, _Unwind_Context* context)
assert(0);
}
-// Read an unsigned leb128 value from P, *P is incremented past the value.
+// Read an unsigned leb128 value from P, P is incremented past the value.
// We assume that a word is large enough to hold any value so encoded;
// if it is smaller than a pointer on some target, pointers should not be
// leb128 encoded on that target.
-_uleb128_t read_uleb128(const(ubyte)** p)
+_uleb128_t read_uleb128(ref const(ubyte)* p)
{
- auto q = *p;
_uleb128_t result = 0;
uint shift = 0;
while (1)
{
- ubyte b = *q++;
+ ubyte b = *p++;
result |= cast(_uleb128_t)(b & 0x7F) << shift;
if ((b & 0x80) == 0)
break;
shift += 7;
}
- *p = q;
return result;
}
// Similar, but read a signed leb128 value.
-_sleb128_t read_sleb128(const(ubyte)** p)
+_sleb128_t read_sleb128(ref const(ubyte)* p)
{
- auto q = *p;
_sleb128_t result = 0;
uint shift = 0;
ubyte b = void;
while (1)
{
- b = *q++;
+ b = *p++;
result |= cast(_sleb128_t)(b & 0x7F) << shift;
shift += 7;
if ((b & 0x80) == 0)
@@ -147,69 +144,82 @@ _sleb128_t read_sleb128(const(ubyte)** p)
if (shift < result.sizeof * 8 && (b & 0x40))
result |= -(cast(_sleb128_t)1 << shift);
- *p = q;
return result;
}
-// Load an encoded value from memory at P. The value is returned in VAL;
-// The function returns P incremented past the value. BASE is as given
+// Similar, but read an unaligned value of type T.
+pragma(inline, true)
+private T read_unaligned(T)(ref const(ubyte)* p)
+{
+ version (X86) enum hasUnalignedLoads = true;
+ else version (X86_64) enum hasUnalignedLoads = true;
+ else enum hasUnalignedLoads = false;
+
+ static if (hasUnalignedLoads)
+ {
+ T result = *cast(T*)p;
+ }
+ else
+ {
+ import core.stdc.string : memcpy;
+ T result = void;
+ memcpy(&result, p, T.sizeof);
+ }
+ p += T.sizeof;
+ return result;
+}
+
+// Load an encoded value from memory at P. The function returns the
+// encoded value. P is incremented past the value. BASE is as given
// by base_of_encoded_value for this encoding in the appropriate context.
_Unwind_Ptr read_encoded_value_with_base(ubyte encoding, _Unwind_Ptr base,
- const(ubyte)** p)
+ ref const(ubyte)* p)
{
- auto q = *p;
+ auto psave = p;
_Unwind_Internal_Ptr result;
if (encoding == DW_EH_PE_aligned)
{
- _Unwind_Internal_Ptr a = cast(_Unwind_Internal_Ptr)q;
+ _Unwind_Internal_Ptr a = cast(_Unwind_Internal_Ptr)p;
a = cast(_Unwind_Internal_Ptr)((a + (void*).sizeof - 1) & - (void*).sizeof);
result = *cast(_Unwind_Internal_Ptr*)a;
- q = cast(ubyte*) cast(_Unwind_Internal_Ptr)(a + (void*).sizeof);
+ p = cast(ubyte*) cast(_Unwind_Internal_Ptr)(a + (void*).sizeof);
}
else
{
switch (encoding & 0x0f)
{
case DW_EH_PE_uleb128:
- result = cast(_Unwind_Internal_Ptr)read_uleb128(&q);
+ result = cast(_Unwind_Internal_Ptr)read_uleb128(p);
break;
case DW_EH_PE_sleb128:
- result = cast(_Unwind_Internal_Ptr)read_sleb128(&q);
+ result = cast(_Unwind_Internal_Ptr)read_sleb128(p);
break;
case DW_EH_PE_udata2:
- result = cast(_Unwind_Internal_Ptr) *cast(ushort*)q;
- q += 2;
+ result = cast(_Unwind_Internal_Ptr)read_unaligned!ushort(p);
break;
case DW_EH_PE_udata4:
- result = cast(_Unwind_Internal_Ptr) *cast(uint*)q;
- q += 4;
+ result = cast(_Unwind_Internal_Ptr)read_unaligned!uint(p);
break;
case DW_EH_PE_udata8:
- result = cast(_Unwind_Internal_Ptr) *cast(ulong*)q;
- q += 8;
+ result = cast(_Unwind_Internal_Ptr)read_unaligned!ulong(p);
break;
case DW_EH_PE_sdata2:
- result = cast(_Unwind_Internal_Ptr) *cast(short*)q;
- q += 2;
+ result = cast(_Unwind_Internal_Ptr)read_unaligned!short(p);
break;
case DW_EH_PE_sdata4:
- result = cast(_Unwind_Internal_Ptr) *cast(int*)q;
- q += 4;
+ result = cast(_Unwind_Internal_Ptr)read_unaligned!int(p);
break;
case DW_EH_PE_sdata8:
- result = cast(_Unwind_Internal_Ptr) *cast(long*)q;
- q += 8;
+ result = cast(_Unwind_Internal_Ptr)read_unaligned!long(p);
break;
case DW_EH_PE_absptr:
- if (size_t.sizeof == 8)
- goto case DW_EH_PE_udata8;
- else
- goto case DW_EH_PE_udata4;
+ result = cast(_Unwind_Internal_Ptr)read_unaligned!(size_t)(p);
+ break;
default:
__builtin_abort();
@@ -218,20 +228,19 @@ _Unwind_Ptr read_encoded_value_with_base(ubyte encoding, _Unwind_Ptr base,
if (result != 0)
{
result += ((encoding & 0x70) == DW_EH_PE_pcrel
- ? cast(_Unwind_Internal_Ptr)*p : base);
+ ? cast(_Unwind_Internal_Ptr)psave : base);
if (encoding & DW_EH_PE_indirect)
result = *cast(_Unwind_Internal_Ptr*)result;
}
}
- *p = q;
return result;
}
// Like read_encoded_value_with_base, but get the base from the context
// rather than providing it directly.
_Unwind_Ptr read_encoded_value(_Unwind_Context* context, ubyte encoding,
- const(ubyte)** p)
+ ref const(ubyte)* p)
{
auto base = base_of_encoded_value(encoding, context);
return read_encoded_value_with_base(encoding, base, p);
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index d7588dc..e96d1c4 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -16,27 +16,14 @@ private
extern (C) void rt_finalize(void *data, bool det=true);
}
-// NOTE: For some reason, this declaration method doesn't work
-// in this particular file (and this file only). It must
-// be a DMD thing.
-//alias typeof(int.sizeof) size_t;
-//alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
+alias size_t = typeof(int.sizeof);
+alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0);
-version (D_LP64)
-{
- alias size_t = ulong;
- alias ptrdiff_t = long;
-}
-else
-{
- alias size_t = uint;
- alias ptrdiff_t = int;
-}
-
-alias sizediff_t = ptrdiff_t; //For backwards compatibility only.
+alias sizediff_t = ptrdiff_t; // For backwards compatibility only.
+alias noreturn = typeof(*null); /// bottom type
-alias hash_t = size_t; //For backwards compatibility only.
-alias equals_t = bool; //For backwards compatibility only.
+alias hash_t = size_t; // For backwards compatibility only.
+alias equals_t = bool; // For backwards compatibility only.
alias string = immutable(char)[];
alias wstring = immutable(wchar)[];
@@ -44,6 +31,27 @@ alias dstring = immutable(dchar)[];
version (D_ObjectiveC) public import core.attribute : selector;
+// Some ABIs use a complex varargs implementation requiring TypeInfo.argTypes().
+version (GNU)
+{
+ // No TypeInfo-based core.vararg.va_arg().
+}
+else version (X86_64)
+{
+ version (DigitalMars) version = WithArgTypes;
+ else version (Windows) { /* no need for Win64 ABI */ }
+ else version = WithArgTypes;
+}
+else version (AArch64)
+{
+ // Apple uses a trivial varargs implementation
+ version (OSX) {}
+ else version (iOS) {}
+ else version (TVOS) {}
+ else version (WatchOS) {}
+ else version = WithArgTypes;
+}
+
/**
* All D class objects inherit from Object.
*/
@@ -311,7 +319,7 @@ class TypeInfo
/** Return internal info on arguments fitting into 8byte.
* See X86-64 ABI 3.2.3
*/
- version (X86_64) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow
+ version (WithArgTypes) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow
{
arg1 = this;
return 0;
@@ -319,7 +327,7 @@ class TypeInfo
/** Return info used by the garbage collector to do precise collection.
*/
- @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return null; }
+ @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return rtinfoHasPointers; } // better safe than sorry
}
class TypeInfo_Enum : TypeInfo
@@ -351,7 +359,7 @@ class TypeInfo_Enum : TypeInfo
override @property size_t talign() nothrow pure const { return base.talign; }
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
return base.argTypes(arg1, arg2);
}
@@ -509,12 +517,14 @@ class TypeInfo_Array : TypeInfo
return (void[]).alignof;
}
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
arg1 = typeid(size_t);
arg2 = typeid(void*);
return 0;
}
+
+ override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(void[]); }
}
class TypeInfo_StaticArray : TypeInfo
@@ -636,11 +646,14 @@ class TypeInfo_StaticArray : TypeInfo
return value.talign;
}
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
arg1 = typeid(void*);
return 0;
}
+
+ // just return the rtInfo of the element, we have no generic type T to run RTInfo!T on
+ override @property immutable(void)* rtInfo() nothrow pure const @safe { return value.rtInfo(); }
}
class TypeInfo_AssociativeArray : TypeInfo
@@ -692,7 +705,7 @@ class TypeInfo_AssociativeArray : TypeInfo
return (char[int]).alignof;
}
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
arg1 = typeid(void*);
return 0;
@@ -727,7 +740,7 @@ class TypeInfo_Vector : TypeInfo
override @property size_t talign() nothrow pure const { return 16; }
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
return base.argTypes(arg1, arg2);
}
@@ -767,6 +780,8 @@ class TypeInfo_Function : TypeInfo
return null;
}
+ override @property immutable(void)* rtInfo() nothrow pure const @safe { return rtinfoNoPointers; }
+
TypeInfo next;
/**
@@ -852,12 +867,14 @@ class TypeInfo_Delegate : TypeInfo
return dg.alignof;
}
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
arg1 = typeid(void*);
arg2 = typeid(void*);
return 0;
}
+
+ override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(int delegate()); }
}
/**
@@ -1228,9 +1245,9 @@ class TypeInfo_Struct : TypeInfo
uint m_align;
- override @property immutable(void)* rtInfo() const { return m_RTInfo; }
+ override @property immutable(void)* rtInfo() nothrow pure const @safe { return m_RTInfo; }
- version (X86_64)
+ version (WithArgTypes)
{
override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
@@ -1337,7 +1354,7 @@ class TypeInfo_Tuple : TypeInfo
assert(0);
}
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
assert(0);
}
@@ -1379,7 +1396,7 @@ class TypeInfo_Const : TypeInfo
override @property size_t talign() nothrow pure const { return base.talign; }
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
{
return base.argTypes(arg1, arg2);
}
@@ -3165,11 +3182,32 @@ void __ctfeWrite(const string s) @nogc @safe pure nothrow {}
* Create RTInfo for type T
*/
+template RTInfoImpl(size_t[] pointerBitmap)
+{
+ immutable size_t[pointerBitmap.length] RTInfoImpl = pointerBitmap[];
+}
+
+template NoPointersBitmapPayload(size_t N)
+{
+ enum size_t[N] NoPointersBitmapPayload = 0;
+}
+
template RTInfo(T)
{
- enum RTInfo = null;
+ enum pointerBitmap = __traits(getPointerBitmap, T);
+ static if (pointerBitmap[1 .. $] == NoPointersBitmapPayload!(pointerBitmap.length - 1))
+ enum RTInfo = rtinfoNoPointers;
+ else
+ enum RTInfo = RTInfoImpl!(pointerBitmap).ptr;
}
+/**
+* shortcuts for the precise GC, also generated by the compiler
+* used instead of the actual pointer bitmap
+*/
+enum immutable(void)* rtinfoNoPointers = null;
+enum immutable(void)* rtinfoHasPointers = cast(void*)1;
+
// lhs == rhs lowers to __equals(lhs, rhs) for dynamic arrays
bool __equals(T1, T2)(T1[] lhs, T2[] rhs)
{
diff --git a/libphobos/libdruntime/rt/aaA.d b/libphobos/libdruntime/rt/aaA.d
index 631847e..0ccf902 100644
--- a/libphobos/libdruntime/rt/aaA.d
+++ b/libphobos/libdruntime/rt/aaA.d
@@ -271,7 +271,7 @@ TypeInfo_Struct fakeEntryTI(const TypeInfo keyti, const TypeInfo valti)
// we don't expect the Entry objects to be used outside of this module, so we have control
// over the non-usage of the callback methods and other entries and can keep these null
// xtoHash, xopEquals, xopCmp, xtoString and xpostblit
- ti.m_RTInfo = null;
+ ti.m_RTInfo = rtinfoNoPointers;
immutable entrySize = talign(kti.tsize, vti.talign) + vti.tsize;
ti.m_init = (cast(ubyte*) null)[0 .. entrySize]; // init length, but not ptr
diff --git a/libphobos/libdruntime/rt/critical_.d b/libphobos/libdruntime/rt/critical_.d
index 15c460a..9404261 100644
--- a/libphobos/libdruntime/rt/critical_.d
+++ b/libphobos/libdruntime/rt/critical_.d
@@ -25,7 +25,10 @@ extern (C) void _d_critical_init()
extern (C) void _d_critical_term()
{
- for (auto p = head; p; p = p.next)
+ // This function is only ever called by the runtime shutdown code
+ // and therefore is single threaded so the following cast is fine.
+ auto h = cast()head;
+ for (auto p = h; p; p = p.next)
destroyMutex(cast(Mutex*)&p.mtx);
}
@@ -43,7 +46,7 @@ extern (C) void _d_criticalenter2(D_CRITICAL_SECTION** pcs)
lockMutex(cast(Mutex*)&gcs.mtx);
if (atomicLoad!(MemoryOrder.raw)(*cast(shared) pcs) is null)
{
- auto cs = new shared(D_CRITICAL_SECTION);
+ auto cs = new shared D_CRITICAL_SECTION;
initMutex(cast(Mutex*)&cs.mtx);
atomicStore!(MemoryOrder.rel)(*cast(shared) pcs, cs);
}
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 3d5ba29..e6acbd5 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -9,6 +9,9 @@
* Source: $(DRUNTIMESRC src/rt/_dmain2.d)
*/
+/* NOTE: This file has been patched from the original DMD distribution to
+ * work with the GDC compiler.
+ */
module rt.dmain2;
private
@@ -70,70 +73,6 @@ version (CRuntime_Microsoft)
extern(C) void init_msvc();
}
-/***********************************
- * These are a temporary means of providing a GC hook for DLL use. They may be
- * replaced with some other similar functionality later.
- */
-extern (C)
-{
- void* gc_getProxy();
- void gc_setProxy(void* p);
- void gc_clrProxy();
-
- alias void* function() gcGetFn;
- alias void function(void*) gcSetFn;
- alias void function() gcClrFn;
-}
-
-version (Windows)
-{
- /*******************************************
- * Loads a DLL written in D with the name 'name'.
- * Returns:
- * opaque handle to the DLL if successfully loaded
- * null if failure
- */
- extern (C) void* rt_loadLibrary(const char* name)
- {
- return initLibrary(.LoadLibraryA(name));
- }
-
- extern (C) void* rt_loadLibraryW(const wchar_t* name)
- {
- return initLibrary(.LoadLibraryW(name));
- }
-
- void* initLibrary(void* mod)
- {
- // BUG: LoadLibrary() call calls rt_init(), which fails if proxy is not set!
- // (What? LoadLibrary() is a Windows API call, it shouldn't call rt_init().)
- if (mod is null)
- return mod;
- gcSetFn gcSet = cast(gcSetFn) GetProcAddress(mod, "gc_setProxy");
- if (gcSet !is null)
- { // BUG: Set proxy, but too late
- gcSet(gc_getProxy());
- }
- return mod;
- }
-
- /*************************************
- * Unloads DLL that was previously loaded by rt_loadLibrary().
- * Input:
- * ptr the handle returned by rt_loadLibrary()
- * Returns:
- * 1 succeeded
- * 0 some failure happened
- */
- extern (C) int rt_unloadLibrary(void* ptr)
- {
- gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
- if (gcClr !is null)
- gcClr();
- return FreeLibrary(ptr) != 0;
- }
-}
-
/* To get out-of-band access to the args[] passed to main().
*/
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index 95f0ff5..6a6eb50 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -44,17 +44,9 @@ private
}
}
-private immutable bool callStructDtorsDuringGC;
-
extern (C) void lifetime_init()
{
// this is run before static ctors, so it is safe to modify immutables
- import rt.config;
- string s = rt_configOption("callStructDtorsDuringGC");
- if (s != null)
- cast() callStructDtorsDuringGC = s[0] == '1' || s[0] == 'y' || s[0] == 'Y';
- else
- cast() callStructDtorsDuringGC = true;
}
/**
@@ -214,9 +206,6 @@ inout(TypeInfo) unqualify(inout(TypeInfo) cti) pure nothrow @nogc
// size used to store the TypeInfo at the end of an allocation for structs that have a destructor
size_t structTypeInfoSize(const TypeInfo ti) pure nothrow @nogc
{
- if (!callStructDtorsDuringGC)
- return 0;
-
if (ti && typeid(ti) is typeid(TypeInfo_Struct)) // avoid a complete dynamic type cast
{
auto sti = cast(TypeInfo_Struct)cast(void*)ti;
@@ -975,7 +964,7 @@ extern (C) void[] _d_newarrayT(const TypeInfo ti, size_t length) pure nothrow
*/
extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) pure nothrow
{
- import core.internal.traits : TypeTuple;
+ import core.internal.traits : AliasSeq;
void[] result = _d_newarrayU(ti, length);
auto tinext = unqualify(ti.next);
@@ -985,7 +974,7 @@ extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) pure nothrow
switch (init.length)
{
- foreach (T; TypeTuple!(ubyte, ushort, uint, ulong))
+ foreach (T; AliasSeq!(ubyte, ushort, uint, ulong))
{
case T.sizeof:
(cast(T*)result.ptr)[0 .. size * length / T.sizeof] = *cast(T*)init.ptr;
@@ -2539,33 +2528,30 @@ unittest
delete arr1;
assert(dtorCount == 7);
- if (callStructDtorsDuringGC)
- {
- dtorCount = 0;
- S1* s2 = new S1;
- GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
- assert(dtorCount == 1);
- GC.free(s2);
+ dtorCount = 0;
+ S1* s2 = new S1;
+ GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
+ assert(dtorCount == 1);
+ GC.free(s2);
- dtorCount = 0;
- const(S1)* s3 = new const(S1);
- GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
- assert(dtorCount == 1);
- GC.free(cast(void*)s3);
+ dtorCount = 0;
+ const(S1)* s3 = new const(S1);
+ GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
+ assert(dtorCount == 1);
+ GC.free(cast(void*)s3);
- dtorCount = 0;
- shared(S1)* s4 = new shared(S1);
- GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
- assert(dtorCount == 1);
- GC.free(cast(void*)s4);
+ dtorCount = 0;
+ shared(S1)* s4 = new shared(S1);
+ GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
+ assert(dtorCount == 1);
+ GC.free(cast(void*)s4);
- dtorCount = 0;
- const(S1)[] carr1 = new const(S1)[5];
- BlkInfo blkinf1 = GC.query(carr1.ptr);
- GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
- assert(dtorCount == 5);
- GC.free(blkinf1.base);
- }
+ dtorCount = 0;
+ const(S1)[] carr1 = new const(S1)[5];
+ BlkInfo blkinf1 = GC.query(carr1.ptr);
+ GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
+ assert(dtorCount == 5);
+ GC.free(blkinf1.base);
dtorCount = 0;
S1[] arr2 = new S1[10];
@@ -2573,14 +2559,11 @@ unittest
arr2.assumeSafeAppend;
assert(dtorCount == 4); // destructors run explicitely?
- if (callStructDtorsDuringGC)
- {
- dtorCount = 0;
- BlkInfo blkinf = GC.query(arr2.ptr);
- GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
- assert(dtorCount == 6);
- GC.free(blkinf.base);
- }
+ dtorCount = 0;
+ BlkInfo blkinf = GC.query(arr2.ptr);
+ GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
+ assert(dtorCount == 6);
+ GC.free(blkinf.base);
// associative arrays
import rt.aaA : entryDtor;
@@ -2590,36 +2573,27 @@ unittest
S1[int] aa1;
aa1[0] = S1(0);
aa1[1] = S1(1);
- if (callStructDtorsDuringGC)
- {
- dtorCount = 0;
- aa1 = null;
- GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);
- assert(dtorCount == 2);
- }
+ dtorCount = 0;
+ aa1 = null;
+ GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);
+ assert(dtorCount == 2);
int[S1] aa2;
aa2[S1(0)] = 0;
aa2[S1(1)] = 1;
aa2[S1(2)] = 2;
- if (callStructDtorsDuringGC)
- {
- dtorCount = 0;
- aa2 = null;
- GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);
- assert(dtorCount == 3);
- }
+ dtorCount = 0;
+ aa2 = null;
+ GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);
+ assert(dtorCount == 3);
S1[2][int] aa3;
aa3[0] = [S1(0),S1(2)];
aa3[1] = [S1(1),S1(3)];
- if (callStructDtorsDuringGC)
- {
- dtorCount = 0;
- aa3 = null;
- GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);
- assert(dtorCount == 4);
- }
+ dtorCount = 0;
+ aa3 = null;
+ GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);
+ assert(dtorCount == 4);
}
// test class finalizers exception handling
@@ -2661,9 +2635,6 @@ unittest
debug(SENTINEL) {} else
unittest
{
- if (!callStructDtorsDuringGC)
- return;
-
bool test(E)()
{
import core.exception;
diff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d
index e38b015..8cb3c3a 100644
--- a/libphobos/libdruntime/rt/monitor_.d
+++ b/libphobos/libdruntime/rt/monitor_.d
@@ -28,15 +28,11 @@ in
body
{
auto m = ensureMonitor(cast(Object) owner);
- auto i = m.impl;
- if (i is null)
+ if (m.impl is null)
{
atomicOp!("+=")(m.refs, cast(size_t) 1);
- ownee.__monitor = owner.__monitor;
- return;
}
- // If m.impl is set (ie. if this is a user-created monitor), assume
- // the monitor is garbage collected and simply copy the reference.
+ // Assume the monitor is garbage collected and simply copy the reference.
ownee.__monitor = owner.__monitor;
}
@@ -60,6 +56,26 @@ extern (C) void _d_monitordelete(Object h, bool det)
}
}
+// does not call dispose events, for internal use only
+extern (C) void _d_monitordelete_nogc(Object h) @nogc
+{
+ auto m = getMonitor(h);
+ if (m is null)
+ return;
+
+ if (m.impl)
+ {
+ // let the GC collect the monitor
+ setMonitor(h, null);
+ }
+ else if (!atomicOp!("-=")(m.refs, cast(size_t) 1))
+ {
+ // refcount == 0 means unshared => no synchronization required
+ deleteMonitor(cast(Monitor*) m);
+ setMonitor(h, null);
+ }
+}
+
extern (C) void _d_monitorenter(Object h)
in
{
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Acdouble.d b/libphobos/libdruntime/rt/typeinfo/ti_Acdouble.d
deleted file mode 100644
index 4eea4ad..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Acdouble.d
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Acdouble;
-
-private import rt.util.typeinfo;
-
-// cdouble[]
-
-class TypeInfo_Ar : TypeInfo_Array
-{
- alias F = cdouble;
-
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return (F[]).stringof; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- return Array!F.hashOf(*cast(F[]*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Acfloat.d b/libphobos/libdruntime/rt/typeinfo/ti_Acfloat.d
deleted file mode 100644
index 126bfd8..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Acfloat.d
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Acfloat;
-
-private import rt.util.typeinfo;
-
-// cfloat[]
-
-class TypeInfo_Aq : TypeInfo_Array
-{
- alias F = cfloat;
-
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return (F[]).stringof; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- return Array!F.hashOf(*cast(F[]*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Acreal.d b/libphobos/libdruntime/rt/typeinfo/ti_Acreal.d
deleted file mode 100644
index 1d1421f..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Acreal.d
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Acreal;
-
-private import rt.util.typeinfo;
-
-// creal[]
-
-class TypeInfo_Ac : TypeInfo_Array
-{
- alias F = creal;
-
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return (F[]).stringof; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- return Array!F.hashOf(*cast(F[]*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Adouble.d b/libphobos/libdruntime/rt/typeinfo/ti_Adouble.d
deleted file mode 100644
index 7790492..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Adouble.d
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Adouble;
-
-private import rt.util.typeinfo;
-
-// double[]
-
-class TypeInfo_Ad : TypeInfo_Array
-{
- alias F = double;
-
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return (F[]).stringof; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- return Array!F.hashOf(*cast(F[]*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
-
-// idouble[]
-
-class TypeInfo_Ap : TypeInfo_Ad
-{
- alias F = idouble;
-
- override string toString() const { return (F[]).stringof; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Afloat.d b/libphobos/libdruntime/rt/typeinfo/ti_Afloat.d
deleted file mode 100644
index f6ae827..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Afloat.d
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Afloat;
-
-private import rt.util.typeinfo;
-
-// float[]
-
-class TypeInfo_Af : TypeInfo_Array
-{
- alias F = float;
-
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return (F[]).stringof; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- return Array!F.hashOf(*cast(F[]*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
-
-// ifloat[]
-
-class TypeInfo_Ao : TypeInfo_Af
-{
- alias F = ifloat;
-
- override string toString() const { return (F[]).stringof; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Ag.d b/libphobos/libdruntime/rt/typeinfo/ti_Ag.d
deleted file mode 100644
index f61bd34..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Ag.d
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Ag;
-
-private import core.stdc.string;
-private import core.internal.string;
-
-// byte[]
-
-class TypeInfo_Ag : TypeInfo_Array
-{
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return "byte[]"; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- const s = *cast(const void[]*)p;
- return hashOf(s);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- byte[] s1 = *cast(byte[]*)p1;
- byte[] s2 = *cast(byte[]*)p2;
-
- return s1.length == s2.length &&
- memcmp(cast(byte *)s1, cast(byte *)s2, s1.length) == 0;
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- byte[] s1 = *cast(byte[]*)p1;
- byte[] s2 = *cast(byte[]*)p2;
- size_t len = s1.length;
-
- if (s2.length < len)
- len = s2.length;
- for (size_t u = 0; u < len; u++)
- {
- int result = s1[u] - s2[u];
- if (result)
- return result;
- }
- if (s1.length < s2.length)
- return -1;
- else if (s1.length > s2.length)
- return 1;
- return 0;
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(byte);
- }
-}
-
-
-// ubyte[]
-
-class TypeInfo_Ah : TypeInfo_Ag
-{
- override string toString() const { return "ubyte[]"; }
-
- override int compare(in void* p1, in void* p2) const
- {
- char[] s1 = *cast(char[]*)p1;
- char[] s2 = *cast(char[]*)p2;
-
- return dstrcmp(s1, s2);
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(ubyte);
- }
-}
-
-// void[]
-
-class TypeInfo_Av : TypeInfo_Ah
-{
- override string toString() const { return "void[]"; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(void);
- }
-}
-
-// bool[]
-
-class TypeInfo_Ab : TypeInfo_Ah
-{
- override string toString() const { return "bool[]"; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(bool);
- }
-}
-
-// char[]
-
-class TypeInfo_Aa : TypeInfo_Ah
-{
- override string toString() const { return "char[]"; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- char[] s = *cast(char[]*)p;
- return hashOf(s);
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(char);
- }
-}
-
-// string
-
-class TypeInfo_Aya : TypeInfo_Aa
-{
- override string toString() const { return "immutable(char)[]"; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(immutable(char));
- }
-}
-
-// const(char)[]
-
-class TypeInfo_Axa : TypeInfo_Aa
-{
- override string toString() const { return "const(char)[]"; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(const(char));
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Aint.d b/libphobos/libdruntime/rt/typeinfo/ti_Aint.d
deleted file mode 100644
index 828fbc0..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Aint.d
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Aint;
-
-private import core.stdc.string;
-
-extern (C) void[] _adSort(void[] a, TypeInfo ti);
-
-// int[]
-
-class TypeInfo_Ai : TypeInfo_Array
-{
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return "int[]"; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- // Hash as if unsigned.
- const s = *cast(const uint[]*)p;
- return hashOf(s);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- int[] s1 = *cast(int[]*)p1;
- int[] s2 = *cast(int[]*)p2;
-
- return s1.length == s2.length &&
- memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0;
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- int[] s1 = *cast(int[]*)p1;
- int[] s2 = *cast(int[]*)p2;
- size_t len = s1.length;
-
- if (s2.length < len)
- len = s2.length;
- for (size_t u = 0; u < len; u++)
- {
- if (s1[u] < s2[u])
- return -1;
- else if (s1[u] > s2[u])
- return 1;
- }
- if (s1.length < s2.length)
- return -1;
- else if (s1.length > s2.length)
- return 1;
- return 0;
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(int);
- }
-}
-
-unittest
-{
- int[][] a = [[5,3,8,7], [2,5,3,8,7]];
- _adSort(*cast(void[]*)&a, typeid(a[0]));
- assert(a == [[2,5,3,8,7], [5,3,8,7]]);
-
- a = [[5,3,8,7], [5,3,8]];
- _adSort(*cast(void[]*)&a, typeid(a[0]));
- assert(a == [[5,3,8], [5,3,8,7]]);
-}
-
-unittest
-{
- // Issue 13073: original code uses int subtraction which is susceptible to
- // integer overflow, causing the following case to fail.
- int[] a = [int.max, int.max];
- int[] b = [int.min, int.min];
- assert(a > b);
- assert(b < a);
-}
-
-// uint[]
-
-class TypeInfo_Ak : TypeInfo_Ai
-{
- override string toString() const { return "uint[]"; }
-
- override int compare(in void* p1, in void* p2) const
- {
- uint[] s1 = *cast(uint[]*)p1;
- uint[] s2 = *cast(uint[]*)p2;
- size_t len = s1.length;
-
- if (s2.length < len)
- len = s2.length;
- for (size_t u = 0; u < len; u++)
- {
- if (s1[u] < s2[u])
- return -1;
- else if (s1[u] > s2[u])
- return 1;
- }
- if (s1.length < s2.length)
- return -1;
- else if (s1.length > s2.length)
- return 1;
- return 0;
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(uint);
- }
-}
-
-unittest
-{
- // Original test case from issue 13073
- uint x = 0x22_DF_FF_FF;
- uint y = 0xA2_DF_FF_FF;
- assert(!(x < y && y < x));
- uint[] a = [x];
- uint[] b = [y];
- assert(!(a < b && b < a)); // Original failing case
- uint[1] a1 = [x];
- uint[1] b1 = [y];
- assert(!(a1 < b1 && b1 < a1)); // Original failing case
-}
-
-// dchar[]
-
-class TypeInfo_Aw : TypeInfo_Ak
-{
- override string toString() const { return "dchar[]"; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(dchar);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Along.d b/libphobos/libdruntime/rt/typeinfo/ti_Along.d
deleted file mode 100644
index 51c741a..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Along.d
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Along;
-
-private import core.stdc.string;
-
-// long[]
-
-class TypeInfo_Al : TypeInfo_Array
-{
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return "long[]"; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- // Hash as if unsigned.
- const s = *cast(const ulong[]*)p;
- return hashOf(s);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- long[] s1 = *cast(long[]*)p1;
- long[] s2 = *cast(long[]*)p2;
-
- return s1.length == s2.length &&
- memcmp(cast(void *)s1, cast(void *)s2, s1.length * long.sizeof) == 0;
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- long[] s1 = *cast(long[]*)p1;
- long[] s2 = *cast(long[]*)p2;
- size_t len = s1.length;
-
- if (s2.length < len)
- len = s2.length;
- for (size_t u = 0; u < len; u++)
- {
- if (s1[u] < s2[u])
- return -1;
- else if (s1[u] > s2[u])
- return 1;
- }
- if (s1.length < s2.length)
- return -1;
- else if (s1.length > s2.length)
- return 1;
- return 0;
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(long);
- }
-}
-
-
-// ulong[]
-
-class TypeInfo_Am : TypeInfo_Al
-{
- override string toString() const { return "ulong[]"; }
-
- override int compare(in void* p1, in void* p2) const
- {
- ulong[] s1 = *cast(ulong[]*)p1;
- ulong[] s2 = *cast(ulong[]*)p2;
- size_t len = s1.length;
-
- if (s2.length < len)
- len = s2.length;
- for (size_t u = 0; u < len; u++)
- {
- if (s1[u] < s2[u])
- return -1;
- else if (s1[u] > s2[u])
- return 1;
- }
- if (s1.length < s2.length)
- return -1;
- else if (s1.length > s2.length)
- return 1;
- return 0;
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(ulong);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Areal.d b/libphobos/libdruntime/rt/typeinfo/ti_Areal.d
deleted file mode 100644
index f1dd458..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Areal.d
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Areal;
-
-private import rt.util.typeinfo;
-
-// real[]
-
-class TypeInfo_Ae : TypeInfo_Array
-{
- alias F = real;
-
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return (F[]).stringof; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- return Array!F.hashOf(*cast(F[]*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
-
-// ireal[]
-
-class TypeInfo_Aj : TypeInfo_Ae
-{
- alias F = ireal;
-
- override string toString() const { return (F[]).stringof; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(F);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_Ashort.d b/libphobos/libdruntime/rt/typeinfo/ti_Ashort.d
deleted file mode 100644
index e4b47e2..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_Ashort.d
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_Ashort;
-
-private import core.stdc.string;
-
-// short[]
-
-class TypeInfo_As : TypeInfo_Array
-{
- override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
-
- override string toString() const { return "short[]"; }
-
- override size_t getHash(scope const void* p) @trusted const
- {
- // Hash as if unsigned.
- const s = *cast(const ushort[]*)p;
- return hashOf(s);
- }
-
- override bool equals(in void* p1, in void* p2) const
- {
- short[] s1 = *cast(short[]*)p1;
- short[] s2 = *cast(short[]*)p2;
-
- return s1.length == s2.length &&
- memcmp(cast(void *)s1, cast(void *)s2, s1.length * short.sizeof) == 0;
- }
-
- override int compare(in void* p1, in void* p2) const
- {
- short[] s1 = *cast(short[]*)p1;
- short[] s2 = *cast(short[]*)p2;
- size_t len = s1.length;
-
- if (s2.length < len)
- len = s2.length;
- for (size_t u = 0; u < len; u++)
- {
- int result = s1[u] - s2[u];
- if (result)
- return result;
- }
- if (s1.length < s2.length)
- return -1;
- else if (s1.length > s2.length)
- return 1;
- return 0;
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(short);
- }
-}
-
-
-// ushort[]
-
-class TypeInfo_At : TypeInfo_As
-{
- override string toString() const { return "ushort[]"; }
-
- override int compare(in void* p1, in void* p2) const
- {
- ushort[] s1 = *cast(ushort[]*)p1;
- ushort[] s2 = *cast(ushort[]*)p2;
- size_t len = s1.length;
-
- if (s2.length < len)
- len = s2.length;
- for (size_t u = 0; u < len; u++)
- {
- int result = s1[u] - s2[u];
- if (result)
- return result;
- }
- if (s1.length < s2.length)
- return -1;
- else if (s1.length > s2.length)
- return 1;
- return 0;
- }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(ushort);
- }
-}
-
-// wchar[]
-
-class TypeInfo_Au : TypeInfo_At
-{
- override string toString() const { return "wchar[]"; }
-
- override @property inout(TypeInfo) next() inout
- {
- return cast(inout)typeid(wchar);
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_C.d b/libphobos/libdruntime/rt/typeinfo/ti_C.d
deleted file mode 100644
index df49873..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_C.d
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_C;
-
-// Object
-
-class TypeInfo_C : TypeInfo
-{
- @trusted:
- const:
- //pure:
- //nothrow:
-
- override size_t getHash(scope const void* p)
- {
- Object o = *cast(Object*)p;
- return o ? o.toHash() : 0;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- Object o1 = *cast(Object*)p1;
- Object o2 = *cast(Object*)p2;
-
- return o1 == o2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- Object o1 = *cast(Object*)p1;
- Object o2 = *cast(Object*)p2;
- int c = 0;
-
- // Regard null references as always being "less than"
- if (!(o1 is o2))
- {
- if (o1)
- {
- if (!o2)
- c = 1;
- else
- c = o1.opCmp(o2);
- }
- else
- c = -1;
- }
- return c;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return Object.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. Object.sizeof];
- }
-
- override @property uint flags() nothrow pure
- {
- return 1;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_byte.d b/libphobos/libdruntime/rt/typeinfo/ti_byte.d
deleted file mode 100644
index 6a3efb1..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_byte.d
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_byte;
-
-// byte
-
-class TypeInfo_g : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "byte"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const byte *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(byte *)p1 == *cast(byte *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- return *cast(byte *)p1 - *cast(byte *)p2;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return byte.sizeof;
- }
-
- override const(void)[] initializer() @trusted
- {
- return (cast(void *)null)[0 .. byte.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- byte t;
-
- t = *cast(byte *)p1;
- *cast(byte *)p1 = *cast(byte *)p2;
- *cast(byte *)p2 = t;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_cdouble.d b/libphobos/libdruntime/rt/typeinfo/ti_cdouble.d
deleted file mode 100644
index c396a17..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_cdouble.d
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_cdouble;
-
-private import rt.util.typeinfo;
-
-// cdouble
-
-class TypeInfo_r : TypeInfo
-{
- pure:
- nothrow:
- @safe:
-
- alias F = cdouble;
-
- override string toString() const { return F.stringof; }
-
- override size_t getHash(scope const void* p) const @trusted
- {
- return Floating!F.hashOf(*cast(F*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
- }
-
- override @property size_t tsize() const
- {
- return F.sizeof;
- }
-
- override void swap(void *p1, void *p2) const @trusted
- {
- F t = *cast(F*)p1;
- *cast(F*)p1 = *cast(F*)p2;
- *cast(F*)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable F r;
- return (&r)[0 .. 1];
- }
-
- override @property size_t talign() const
- {
- return F.alignof;
- }
-
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
- {
- arg1 = typeid(double);
- arg2 = typeid(double);
- return 0;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_cent.d b/libphobos/libdruntime/rt/typeinfo/ti_cent.d
deleted file mode 100644
index a74f796..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_cent.d
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2015.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2015.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_cent;
-
-static if (is(cent)):
-
-// cent
-
-class TypeInfo_zi : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "cent"; }
-
- override size_t getHash(scope const void* p)
- {
- // cent & ucent hash the same if ucent.sizeof >= size_t.sizeof.
- return hashOf(*cast(const ucent*) p);
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(cent *)p1 == *cast(cent *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- if (*cast(cent *)p1 < *cast(cent *)p2)
- return -1;
- else if (*cast(cent *)p1 > *cast(cent *)p2)
- return 1;
- return 0;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return cent.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. cent.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- cent t;
-
- t = *cast(cent *)p1;
- *cast(cent *)p1 = *cast(cent *)p2;
- *cast(cent *)p2 = t;
- }
-
- override @property size_t talign() nothrow pure
- {
- return cent.alignof;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_cfloat.d b/libphobos/libdruntime/rt/typeinfo/ti_cfloat.d
deleted file mode 100644
index a3ad4ca..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_cfloat.d
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_cfloat;
-
-private import rt.util.typeinfo;
-
-// cfloat
-
-class TypeInfo_q : TypeInfo
-{
- pure:
- nothrow:
- @safe:
-
- alias F = cfloat;
-
- override string toString() const { return F.stringof; }
-
- override size_t getHash(scope const void* p) const @trusted
- {
- return Floating!F.hashOf(*cast(F*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
- }
-
- override @property size_t tsize() const
- {
- return F.sizeof;
- }
-
- override void swap(void *p1, void *p2) const @trusted
- {
- F t = *cast(F*)p1;
- *cast(F*)p1 = *cast(F*)p2;
- *cast(F*)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable F r;
- return (&r)[0 .. 1];
- }
-
- override @property size_t talign() const
- {
- return F.alignof;
- }
-
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
- {
- arg1 = typeid(double);
- return 0;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_char.d b/libphobos/libdruntime/rt/typeinfo/ti_char.d
deleted file mode 100644
index fbc5680..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_char.d
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_char;
-
-// char
-
-class TypeInfo_a : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "char"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const char *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(char *)p1 == *cast(char *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- return *cast(char *)p1 - *cast(char *)p2;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return char.sizeof;
- }
-
- override void swap(void *p1, void *p2)
- {
- char t;
-
- t = *cast(char *)p1;
- *cast(char *)p1 = *cast(char *)p2;
- *cast(char *)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable char c;
-
- return (&c)[0 .. 1];
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_creal.d b/libphobos/libdruntime/rt/typeinfo/ti_creal.d
deleted file mode 100644
index c064b7b..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_creal.d
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_creal;
-
-private import rt.util.typeinfo;
-
-// creal
-
-class TypeInfo_c : TypeInfo
-{
- pure:
- nothrow:
- @safe:
-
- alias F = creal;
-
- override string toString() const { return F.stringof; }
-
- override size_t getHash(scope const void* p) const @trusted
- {
- return Floating!F.hashOf(*cast(F*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
- }
-
- override @property size_t tsize() const
- {
- return F.sizeof;
- }
-
- override void swap(void *p1, void *p2) const @trusted
- {
- F t = *cast(F*)p1;
- *cast(F*)p1 = *cast(F*)p2;
- *cast(F*)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable F r;
- return (&r)[0 .. 1];
- }
-
- override @property size_t talign() const
- {
- return F.alignof;
- }
-
- version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
- {
- arg1 = typeid(real);
- arg2 = typeid(real);
- return 0;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_dchar.d b/libphobos/libdruntime/rt/typeinfo/ti_dchar.d
deleted file mode 100644
index 5d6fea1..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_dchar.d
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_dchar;
-
-// dchar
-
-class TypeInfo_w : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "dchar"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const dchar *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(dchar *)p1 == *cast(dchar *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- return *cast(dchar *)p1 - *cast(dchar *)p2;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return dchar.sizeof;
- }
-
- override void swap(void *p1, void *p2)
- {
- dchar t;
-
- t = *cast(dchar *)p1;
- *cast(dchar *)p1 = *cast(dchar *)p2;
- *cast(dchar *)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable dchar c;
-
- return (&c)[0 .. 1];
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_delegate.d b/libphobos/libdruntime/rt/typeinfo/ti_delegate.d
deleted file mode 100644
index aaddd85..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_delegate.d
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_delegate;
-
-
-// delegate
-
-alias void delegate(int) dg;
-
-class TypeInfo_D : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override size_t getHash(scope const void* p)
- {
- return hashOf(*cast(dg*)p);
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(dg *)p1 == *cast(dg *)p2;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return dg.sizeof;
- }
-
- override void swap(void *p1, void *p2)
- {
- dg t;
-
- t = *cast(dg *)p1;
- *cast(dg *)p1 = *cast(dg *)p2;
- *cast(dg *)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable dg d;
-
- return (cast(void *)null)[0 .. dg.sizeof];
- }
-
- override @property uint flags() nothrow pure
- {
- return 1;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_double.d b/libphobos/libdruntime/rt/typeinfo/ti_double.d
deleted file mode 100644
index f5671cd..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_double.d
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_double;
-
-private import rt.util.typeinfo;
-
-// double
-
-class TypeInfo_d : TypeInfo
-{
- pure:
- nothrow:
- @safe:
-
- alias F = double;
-
- override string toString() const { return F.stringof; }
-
- override size_t getHash(scope const void* p) const @trusted
- {
- return Floating!F.hashOf(*cast(F*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
- }
-
- override @property size_t tsize() const
- {
- return F.sizeof;
- }
-
- override void swap(void *p1, void *p2) const @trusted
- {
- F t = *cast(F*)p1;
- *cast(F*)p1 = *cast(F*)p2;
- *cast(F*)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable F r;
- return (&r)[0 .. 1];
- }
-
- override @property size_t talign() const
- {
- return F.alignof;
- }
-
- version (Windows)
- {
- }
- else version (X86_64)
- {
- // 2 means arg to function is passed in XMM registers
- override @property uint flags() const { return 2; }
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_float.d b/libphobos/libdruntime/rt/typeinfo/ti_float.d
deleted file mode 100644
index 4cd68c7..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_float.d
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_float;
-
-private import rt.util.typeinfo;
-
-// float
-
-class TypeInfo_f : TypeInfo
-{
- pure:
- nothrow:
- @safe:
-
- alias F = float;
-
- override string toString() const { return F.stringof; }
-
- override size_t getHash(scope const void* p) const @trusted
- {
- return Floating!F.hashOf(*cast(F*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
- }
-
- override @property size_t tsize() const
- {
- return F.sizeof;
- }
-
- override void swap(void *p1, void *p2) const @trusted
- {
- F t = *cast(F*)p1;
- *cast(F*)p1 = *cast(F*)p2;
- *cast(F*)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable F r;
- return (&r)[0 .. 1];
- }
-
- version (Windows)
- {
- }
- else version (X86_64)
- {
- // 2 means arg to function is passed in XMM registers
- override @property uint flags() const { return 2; }
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_idouble.d b/libphobos/libdruntime/rt/typeinfo/ti_idouble.d
deleted file mode 100644
index f068549..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_idouble.d
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_idouble;
-
-private import rt.typeinfo.ti_double;
-
-// idouble
-
-class TypeInfo_p : TypeInfo_d
-{
- pure:
- nothrow:
- @safe:
-
- override string toString() const { return idouble.stringof; }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ifloat.d b/libphobos/libdruntime/rt/typeinfo/ti_ifloat.d
deleted file mode 100644
index 062b3f4..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_ifloat.d
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_ifloat;
-
-private import rt.typeinfo.ti_float;
-
-// ifloat
-
-class TypeInfo_o : TypeInfo_f
-{
- pure:
- nothrow:
- @safe:
-
- override string toString() const { return ifloat.stringof; }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_int.d b/libphobos/libdruntime/rt/typeinfo/ti_int.d
deleted file mode 100644
index 6e32c43..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_int.d
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_int;
-
-// int
-
-class TypeInfo_i : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "int"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const int *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(uint *)p1 == *cast(uint *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- if (*cast(int*) p1 < *cast(int*) p2)
- return -1;
- else if (*cast(int*) p1 > *cast(int*) p2)
- return 1;
- return 0;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return int.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. int.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- int t;
-
- t = *cast(int *)p1;
- *cast(int *)p1 = *cast(int *)p2;
- *cast(int *)p2 = t;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ireal.d b/libphobos/libdruntime/rt/typeinfo/ti_ireal.d
deleted file mode 100644
index c1334f7..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_ireal.d
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_ireal;
-
-private import rt.typeinfo.ti_real;
-
-// ireal
-
-class TypeInfo_j : TypeInfo_e
-{
- pure:
- nothrow:
- @safe:
-
- override string toString() const { return ireal.stringof; }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_long.d b/libphobos/libdruntime/rt/typeinfo/ti_long.d
deleted file mode 100644
index 78fea11..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_long.d
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_long;
-
-// long
-
-class TypeInfo_l : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "long"; }
-
- override size_t getHash(scope const void* p)
- {
- static if (ulong.sizeof <= size_t.sizeof)
- return *cast(const long*)p;
- else
- // long & ulong hash the same if ulong.sizeof > size_t.sizeof.
- return hashOf(*cast(const ulong*)p);
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(long *)p1 == *cast(long *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- if (*cast(long *)p1 < *cast(long *)p2)
- return -1;
- else if (*cast(long *)p1 > *cast(long *)p2)
- return 1;
- return 0;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return long.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. long.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- long t;
-
- t = *cast(long *)p1;
- *cast(long *)p1 = *cast(long *)p2;
- *cast(long *)p2 = t;
- }
-
- override @property size_t talign() nothrow pure
- {
- return long.alignof;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_n.d b/libphobos/libdruntime/rt/typeinfo/ti_n.d
deleted file mode 100644
index b6cea03..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_n.d
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2016.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Kenji Hara
- */
-
-/* Copyright Digital Mars 2016.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_n;
-
-// typeof(null)
-
-class TypeInfo_n : TypeInfo
-{
- override string toString() const @safe { return "typeof(null)"; }
-
- override size_t getHash(scope const void* p) const
- {
- return 0;
- }
-
- override bool equals(in void* p1, in void* p2) const @trusted
- {
- //return *cast(typeof(null)*)p1 is *cast(typeof(null)*)p2;
- return true;
- }
-
- override int compare(in void* p1, in void* p2) const @trusted
- {
- //if (*cast(int*) p1 < *cast(int*) p2)
- // return -1;
- //else if (*cast(int*) p1 > *cast(int*) p2)
- // return 1;
- return 0;
- }
-
- override @property size_t tsize() const
- {
- return typeof(null).sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void*)null)[0 .. typeof(null).sizeof];
- }
-
- override void swap(void *p1, void *p2) const @trusted
- {
- //auto t = *cast(typeof(null)*)p1;
- //*cast(typeof(null)*)p1 = *cast(typeof(null)*)p2;
- //*cast(typeof(null)*)p2 = t;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ptr.d b/libphobos/libdruntime/rt/typeinfo/ti_ptr.d
deleted file mode 100644
index 8857ef9..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_ptr.d
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_ptr;
-
-// internal typeinfo for any pointer type
-// please keep in sync with TypeInfo_Pointer
-
-class TypeInfo_P : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override size_t getHash(scope const void* p)
- {
- size_t addr = cast(size_t) *cast(const void**)p;
- return addr ^ (addr >> 4);
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(void**)p1 == *cast(void**)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- if (*cast(void**)p1 < *cast(void**)p2)
- return -1;
- else if (*cast(void**)p1 > *cast(void**)p2)
- return 1;
- else
- return 0;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return (void*).sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. (void*).sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- void* tmp = *cast(void**)p1;
- *cast(void**)p1 = *cast(void**)p2;
- *cast(void**)p2 = tmp;
- }
-
- override @property uint flags() nothrow pure const { return 1; }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_real.d b/libphobos/libdruntime/rt/typeinfo/ti_real.d
deleted file mode 100644
index fb20f14..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_real.d
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_real;
-
-private import rt.util.typeinfo;
-
-// real
-
-class TypeInfo_e : TypeInfo
-{
- pure:
- nothrow:
- @safe:
-
- alias F = real;
-
- override string toString() const { return F.stringof; }
-
- override size_t getHash(scope const void* p) const @trusted
- {
- return Floating!F.hashOf(*cast(F*)p);
- }
-
- override bool equals(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
- }
-
- override int compare(in void* p1, in void* p2) const @trusted
- {
- return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
- }
-
- override @property size_t tsize() const
- {
- return F.sizeof;
- }
-
- override void swap(void *p1, void *p2) const @trusted
- {
- F t = *cast(F*)p1;
- *cast(F*)p1 = *cast(F*)p2;
- *cast(F*)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable F r;
- return (&r)[0 .. 1];
- }
-
- override @property size_t talign() const
- {
- return F.alignof;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_short.d b/libphobos/libdruntime/rt/typeinfo/ti_short.d
deleted file mode 100644
index bccbe63..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_short.d
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_short;
-
-// short
-
-class TypeInfo_s : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "short"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const short *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(short *)p1 == *cast(short *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- return *cast(short *)p1 - *cast(short *)p2;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return short.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. short.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- short t;
-
- t = *cast(short *)p1;
- *cast(short *)p1 = *cast(short *)p2;
- *cast(short *)p2 = t;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ubyte.d b/libphobos/libdruntime/rt/typeinfo/ti_ubyte.d
deleted file mode 100644
index 9643179..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_ubyte.d
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_ubyte;
-
-// ubyte
-
-class TypeInfo_h : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "ubyte"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const ubyte *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(ubyte *)p1 == *cast(ubyte *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- return *cast(ubyte *)p1 - *cast(ubyte *)p2;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return ubyte.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. ubyte.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- ubyte t;
-
- t = *cast(ubyte *)p1;
- *cast(ubyte *)p1 = *cast(ubyte *)p2;
- *cast(ubyte *)p2 = t;
- }
-}
-
-class TypeInfo_b : TypeInfo_h
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "bool"; }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ucent.d b/libphobos/libdruntime/rt/typeinfo/ti_ucent.d
deleted file mode 100644
index ffa67d8..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_ucent.d
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2015.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2015.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_ucent;
-
-static if (is(ucent)):
-
-// ucent
-
-class TypeInfo_zk : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "ucent"; }
-
- override size_t getHash(scope const void* p)
- {
- return hashOf(*cast(const ucent*) p);
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(ucent *)p1 == *cast(ucent *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- if (*cast(ucent *)p1 < *cast(ucent *)p2)
- return -1;
- else if (*cast(ucent *)p1 > *cast(ucent *)p2)
- return 1;
- return 0;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return ucent.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. ucent.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- ucent t;
-
- t = *cast(ucent *)p1;
- *cast(ucent *)p1 = *cast(ucent *)p2;
- *cast(ucent *)p2 = t;
- }
-
- override @property size_t talign() nothrow pure
- {
- return ucent.alignof;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_uint.d b/libphobos/libdruntime/rt/typeinfo/ti_uint.d
deleted file mode 100644
index 09bff18..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_uint.d
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_uint;
-
-// uint
-
-class TypeInfo_k : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "uint"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const uint *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(uint *)p1 == *cast(uint *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- if (*cast(uint*) p1 < *cast(uint*) p2)
- return -1;
- else if (*cast(uint*) p1 > *cast(uint*) p2)
- return 1;
- return 0;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return uint.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. uint.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- int t;
-
- t = *cast(uint *)p1;
- *cast(uint *)p1 = *cast(uint *)p2;
- *cast(uint *)p2 = t;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ulong.d b/libphobos/libdruntime/rt/typeinfo/ti_ulong.d
deleted file mode 100644
index 3fdaacd..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_ulong.d
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_ulong;
-
-
-// ulong
-
-class TypeInfo_m : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "ulong"; }
-
- override size_t getHash(scope const void* p)
- {
- static if (ulong.sizeof <= size_t.sizeof)
- return *cast(const ulong*)p;
- else
- return hashOf(*cast(const ulong*)p);
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(ulong *)p1 == *cast(ulong *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- if (*cast(ulong *)p1 < *cast(ulong *)p2)
- return -1;
- else if (*cast(ulong *)p1 > *cast(ulong *)p2)
- return 1;
- return 0;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return ulong.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. ulong.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- ulong t;
-
- t = *cast(ulong *)p1;
- *cast(ulong *)p1 = *cast(ulong *)p2;
- *cast(ulong *)p2 = t;
- }
-
- override @property size_t talign() nothrow pure
- {
- return ulong.alignof;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_ushort.d b/libphobos/libdruntime/rt/typeinfo/ti_ushort.d
deleted file mode 100644
index 90623f2..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_ushort.d
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_ushort;
-
-// ushort
-
-class TypeInfo_t : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "ushort"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const ushort *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(ushort *)p1 == *cast(ushort *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- return *cast(ushort *)p1 - *cast(ushort *)p2;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return ushort.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. ushort.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- ushort t;
-
- t = *cast(ushort *)p1;
- *cast(ushort *)p1 = *cast(ushort *)p2;
- *cast(ushort *)p2 = t;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_void.d b/libphobos/libdruntime/rt/typeinfo/ti_void.d
deleted file mode 100644
index 1facb95..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_void.d
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_void;
-
-// void
-
-class TypeInfo_v : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() const pure nothrow @safe { return "void"; }
-
- override size_t getHash(scope const void* p)
- {
- assert(0);
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(byte *)p1 == *cast(byte *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- return *cast(byte *)p1 - *cast(byte *)p2;
- }
-
- override @property size_t tsize() nothrow pure
- {
- return void.sizeof;
- }
-
- override const(void)[] initializer() const @trusted
- {
- return (cast(void *)null)[0 .. void.sizeof];
- }
-
- override void swap(void *p1, void *p2)
- {
- byte t;
-
- t = *cast(byte *)p1;
- *cast(byte *)p1 = *cast(byte *)p2;
- *cast(byte *)p2 = t;
- }
-
- override @property uint flags() nothrow pure
- {
- return 1;
- }
-}
diff --git a/libphobos/libdruntime/rt/typeinfo/ti_wchar.d b/libphobos/libdruntime/rt/typeinfo/ti_wchar.d
deleted file mode 100644
index dcf8256..0000000
--- a/libphobos/libdruntime/rt/typeinfo/ti_wchar.d
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * TypeInfo support code.
- *
- * Copyright: Copyright Digital Mars 2004 - 2009.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2004 - 2009.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.typeinfo.ti_wchar;
-
-// wchar
-
-class TypeInfo_u : TypeInfo
-{
- @trusted:
- const:
- pure:
- nothrow:
-
- override string toString() { return "wchar"; }
-
- override size_t getHash(scope const void* p)
- {
- return *cast(const wchar *)p;
- }
-
- override bool equals(in void* p1, in void* p2)
- {
- return *cast(wchar *)p1 == *cast(wchar *)p2;
- }
-
- override int compare(in void* p1, in void* p2)
- {
- return *cast(wchar *)p1 - *cast(wchar *)p2;
- }
-
- override @property size_t tsize()
- {
- return wchar.sizeof;
- }
-
- override void swap(void *p1, void *p2)
- {
- wchar t;
-
- t = *cast(wchar *)p1;
- *cast(wchar *)p1 = *cast(wchar *)p2;
- *cast(wchar *)p2 = t;
- }
-
- override const(void)[] initializer() const @trusted
- {
- static immutable wchar c;
-
- return (&c)[0 .. 1];
- }
-}
diff --git a/libphobos/libdruntime/rt/util/typeinfo.d b/libphobos/libdruntime/rt/util/typeinfo.d
index 2cc1c23..31770a0 100644
--- a/libphobos/libdruntime/rt/util/typeinfo.d
+++ b/libphobos/libdruntime/rt/util/typeinfo.d
@@ -266,3 +266,520 @@ unittest
}
}();
}
+
+// Reduces to `T` if `cond` is `true` or `U` otherwise.
+private template Select(bool cond, T, U)
+{
+ static if (cond) alias Select = T;
+ else alias Select = U;
+}
+
+/*
+TypeInfo information for built-in types.
+
+A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
+equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example:
+`float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
+the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
+during compilation whether they have different signedness and override appropriately. For initializer, we
+detect if we need to override. The overriding initializer should be nonzero.
+*/
+private class TypeInfoGeneric(T, Base = T) : Select!(is(T == Base), TypeInfo, TypeInfoGeneric!Base)
+if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
+{
+ const: nothrow: pure: @trusted:
+
+ // Returns the type name.
+ override string toString() const pure nothrow @safe { return T.stringof; }
+
+ // `getHash` is the same for `Base` and `T`, introduce it just once.
+ static if (is(T == Base))
+ override size_t getHash(scope const void* p)
+ {
+ static if (__traits(isFloating, T))
+ return Floating!T.hashOf(*cast(T*)p);
+ else
+ return hashOf(*cast(const T *)p);
+ }
+
+ // `equals` is the same for `Base` and `T`, introduce it just once.
+ static if (is(T == Base))
+ override bool equals(in void* p1, in void* p2)
+ {
+ static if (__traits(isFloating, T))
+ return Floating!T.equals(*cast(T*)p1, *cast(T*)p2);
+ else
+ return *cast(T *)p1 == *cast(T *)p2;
+ }
+
+ // `T` and `Base` may have different signedness, so this function is introduced conditionally.
+ static if (is(T == Base) || (__traits(isIntegral, T) && T.max != Base.max))
+ override int compare(in void* p1, in void* p2)
+ {
+ static if (__traits(isFloating, T))
+ {
+ return Floating!T.compare(*cast(T*)p1, *cast(T*)p2);
+ }
+ else static if (T.sizeof < int.sizeof)
+ {
+ // Taking the difference will always fit in an int.
+ return int(*cast(T *) p1) - int(*cast(T *) p2);
+ }
+ else
+ {
+ auto lhs = *cast(T *) p1, rhs = *cast(T *) p2;
+ return (lhs > rhs) - (lhs < rhs);
+ }
+ }
+
+ static if (is(T == Base))
+ override @property size_t tsize() nothrow pure
+ {
+ return T.sizeof;
+ }
+
+ static if (is(T == Base))
+ override @property size_t talign() nothrow pure
+ {
+ return T.alignof;
+ }
+
+ // Override initializer only if necessary.
+ static if (is(T == Base) || T.init != Base.init)
+ override const(void)[] initializer() @trusted
+ {
+ static if (__traits(isZeroInit, T))
+ {
+ return (cast(void *)null)[0 .. T.sizeof];
+ }
+ else
+ {
+ static immutable T[1] c;
+ return c;
+ }
+ }
+
+ // `swap` is the same for `Base` and `T`, so introduce only once.
+ static if (is(T == Base))
+ override void swap(void *p1, void *p2)
+ {
+ auto t = *cast(T *) p1;
+ *cast(T *)p1 = *cast(T *)p2;
+ *cast(T *)p2 = t;
+ }
+
+ static if (is(T == Base) || RTInfo!T != RTInfo!Base)
+ override @property immutable(void)* rtInfo() nothrow pure const @safe
+ {
+ return RTInfo!T;
+ }
+
+ static if (is(T == Base))
+ static if (__traits(isFloating, T) && T.mant_dig != 64)
+ // FP types except 80-bit X87 are passed in SIMD register.
+ override @property uint flags() const { return 2; }
+}
+
+unittest
+{
+ assert(typeid(int).toString == "int");
+
+ with (typeid(double))
+ {
+ double a = 42, b = 43;
+ assert(equals(&a, &a));
+ assert(!equals(&a, &b));
+ assert(compare(&a, &a) == 0);
+ assert(compare(&a, &b) == -1);
+ assert(compare(&b, &a) == 1);
+ }
+
+ with (typeid(short))
+ {
+ short c = 42, d = 43;
+ assert(equals(&c, &c));
+ assert(!equals(&c, &d));
+ assert(compare(&c, &c) == 0);
+ assert(compare(&c, &d) == -1);
+ assert(compare(&d, &c) == 1);
+ assert(initializer.ptr is null);
+ assert(initializer.length == short.sizeof);
+ swap(&d, &c);
+ assert(c == 43 && d == 42);
+ }
+}
+
+/*
+TypeInfo information for arrays of built-in types.
+
+A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
+equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example:
+`float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
+the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
+during compilation whether they have different signedness and override appropriately. For initializer, we
+detect if we need to override. The overriding initializer should be nonzero.
+*/
+private class TypeInfoArrayGeneric(T, Base = T) : Select!(is(T == Base), TypeInfo_Array, TypeInfoArrayGeneric!Base)
+{
+ static if (is(T == Base))
+ override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
+
+ override string toString() const { return (T[]).stringof; }
+
+ static if (is(T == Base))
+ override size_t getHash(scope const void* p) @trusted const
+ {
+ static if (__traits(isFloating, T))
+ return Array!T.hashOf(*cast(T[]*)p);
+ else
+ return hashOf(*cast(const T[]*) p);
+ }
+
+ static if (is(T == Base))
+ override bool equals(in void* p1, in void* p2) const
+ {
+ static if (__traits(isFloating, T))
+ {
+ return Array!T.equals(*cast(T[]*)p1, *cast(T[]*)p2);
+ }
+ else
+ {
+ import core.stdc.string;
+ auto s1 = *cast(T[]*)p1;
+ auto s2 = *cast(T[]*)p2;
+ return s1.length == s2.length &&
+ memcmp(s1.ptr, s2.ptr, s1.length) == 0;
+ }
+ }
+
+ static if (is(T == Base) || (__traits(isIntegral, T) && T.max != Base.max))
+ override int compare(in void* p1, in void* p2) const
+ {
+ static if (__traits(isFloating, T))
+ {
+ return Array!T.compare(*cast(T[]*)p1, *cast(T[]*)p2);
+ }
+ else
+ {
+ auto s1 = *cast(T[]*)p1;
+ auto s2 = *cast(T[]*)p2;
+ auto len = s1.length;
+
+ if (s2.length < len)
+ len = s2.length;
+ for (size_t u = 0; u < len; u++)
+ {
+ if (int result = (s1[u] > s2[u]) - (s1[u] < s2[u]))
+ return result;
+ }
+ return (s1.length > s2.length) - (s1.length < s2.length);
+ }
+ }
+
+ override @property inout(TypeInfo) next() inout
+ {
+ return cast(inout) typeid(T);
+ }
+}
+
+unittest
+{
+ assert(typeid(int[]) == typeid(int[]));
+ assert(typeid(int[]) != typeid(uint[]));
+ assert(typeid(int[]).toString == "int[]");
+
+ with (typeid(double[]))
+ {
+ double[] a = [ 1, 2, 3 ], b = [ 2, 3 ];
+ assert(equals(&a, &a));
+ assert(!equals(&a, &b));
+ assert(compare(&a, &a) == 0);
+ assert(compare(&a, &b) == -1);
+ assert(compare(&b, &a) == 1);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Predefined TypeInfos
+////////////////////////////////////////////////////////////////////////////////
+
+// void
+class TypeInfo_v : TypeInfoGeneric!ubyte
+{
+ const: nothrow: pure: @trusted:
+
+ override string toString() const pure nothrow @safe { return "void"; }
+
+ override size_t getHash(scope const void* p)
+ {
+ assert(0);
+ }
+
+ override @property uint flags() nothrow pure
+ {
+ return 1;
+ }
+
+ unittest
+ {
+ assert(typeid(void).toString == "void");
+ assert(typeid(void).flags == 1);
+ }
+}
+
+// All integrals.
+class TypeInfo_h : TypeInfoGeneric!ubyte {}
+class TypeInfo_b : TypeInfoGeneric!(bool, ubyte) {}
+class TypeInfo_g : TypeInfoGeneric!(byte, ubyte) {}
+class TypeInfo_a : TypeInfoGeneric!(char, ubyte) {}
+class TypeInfo_t : TypeInfoGeneric!ushort {}
+class TypeInfo_s : TypeInfoGeneric!(short, ushort) {}
+class TypeInfo_u : TypeInfoGeneric!(wchar, ushort) {}
+class TypeInfo_w : TypeInfoGeneric!(dchar, uint) {}
+class TypeInfo_k : TypeInfoGeneric!uint {}
+class TypeInfo_i : TypeInfoGeneric!(int, uint) {}
+class TypeInfo_m : TypeInfoGeneric!ulong {}
+class TypeInfo_l : TypeInfoGeneric!(long, ulong) {}
+static if (is(cent)) class TypeInfo_zi : TypeInfoGeneric!cent {}
+static if (is(ucent)) class TypeInfo_zk : TypeInfoGeneric!ucent {}
+
+// All simple floating-point types.
+class TypeInfo_f : TypeInfoGeneric!float {}
+class TypeInfo_o : TypeInfoGeneric!(ifloat, float) {}
+class TypeInfo_d : TypeInfoGeneric!double {}
+class TypeInfo_p : TypeInfoGeneric!(idouble, double) {}
+class TypeInfo_e : TypeInfoGeneric!real {}
+class TypeInfo_j : TypeInfoGeneric!(ireal, real) {}
+
+// All complex floating-point types.
+
+// cfloat
+class TypeInfo_q : TypeInfoGeneric!cfloat
+{
+ const: nothrow: pure: @trusted:
+ static if (__traits(hasMember, TypeInfo, "argTypes"))
+ override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ {
+ arg1 = typeid(double);
+ return 0;
+ }
+}
+
+// cdouble
+class TypeInfo_r : TypeInfoGeneric!cdouble
+{
+ const: nothrow: pure: @trusted:
+ static if (__traits(hasMember, TypeInfo, "argTypes"))
+ override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ {
+ arg1 = typeid(double);
+ arg2 = typeid(double);
+ return 0;
+ }
+}
+
+// creal
+class TypeInfo_c : TypeInfoGeneric!creal
+{
+ const: nothrow: pure: @trusted:
+ static if (__traits(hasMember, TypeInfo, "argTypes"))
+ override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
+ {
+ arg1 = typeid(real);
+ arg2 = typeid(real);
+ return 0;
+ }
+}
+
+static if (__traits(hasMember, TypeInfo, "argTypes"))
+ unittest
+ {
+ TypeInfo t1, t2;
+ assert(typeid(cfloat).argTypes(t1, t2) == 0 && t1 == typeid(double) &&
+ t2 is null);
+ assert(typeid(cdouble).argTypes(t1, t2) == 0 && t1 == typeid(double) &&
+ t2 == typeid(double));
+ assert(typeid(creal).argTypes(t1, t2) == 0 && t1 == typeid(real) &&
+ t2 == typeid(real));
+ }
+
+// Arrays of all integrals.
+class TypeInfo_Ah : TypeInfoArrayGeneric!ubyte {}
+class TypeInfo_Ab : TypeInfoArrayGeneric!(bool, ubyte) {}
+class TypeInfo_Ag : TypeInfoArrayGeneric!(byte, ubyte) {}
+class TypeInfo_Aa : TypeInfoArrayGeneric!(char, ubyte) {}
+class TypeInfo_Axa : TypeInfoArrayGeneric!(const char) {}
+class TypeInfo_Aya : TypeInfoArrayGeneric!(immutable char)
+{
+ // Must override this, otherwise "string" is returned.
+ override string toString() const { return "immutable(char)[]"; }
+}
+class TypeInfo_At : TypeInfoArrayGeneric!ushort {}
+class TypeInfo_As : TypeInfoArrayGeneric!(short, ushort) {}
+class TypeInfo_Au : TypeInfoArrayGeneric!(wchar, ushort) {}
+class TypeInfo_Ak : TypeInfoArrayGeneric!uint {}
+class TypeInfo_Ai : TypeInfoArrayGeneric!(int, uint) {}
+class TypeInfo_Aw : TypeInfoArrayGeneric!(dchar, uint) {}
+class TypeInfo_Am : TypeInfoArrayGeneric!ulong {}
+class TypeInfo_Al : TypeInfoArrayGeneric!(long, ulong) {}
+
+version (unittest)
+ private extern (C) void[] _adSort(void[] a, TypeInfo ti);
+
+unittest
+{
+ assert(typeid(string).toString() == "immutable(char)[]");
+ int[][] a = [[5,3,8,7], [2,5,3,8,7]];
+ _adSort(*cast(void[]*)&a, typeid(a[0]));
+ assert(a == [[2,5,3,8,7], [5,3,8,7]]);
+
+ a = [[5,3,8,7], [5,3,8]];
+ _adSort(*cast(void[]*)&a, typeid(a[0]));
+ assert(a == [[5,3,8], [5,3,8,7]]);
+}
+
+unittest
+{
+ // https://issues.dlang.org/show_bug.cgi?id=13073: original code uses int subtraction which is susceptible to
+ // integer overflow, causing the following case to fail.
+ int[] a = [int.max, int.max];
+ int[] b = [int.min, int.min];
+ assert(a > b);
+ assert(b < a);
+}
+
+unittest
+{
+ // Original test case from issue 13073
+ uint x = 0x22_DF_FF_FF;
+ uint y = 0xA2_DF_FF_FF;
+ assert(!(x < y && y < x));
+ uint[] a = [x];
+ uint[] b = [y];
+ assert(!(a < b && b < a)); // Original failing case
+ uint[1] a1 = [x];
+ uint[1] b1 = [y];
+ assert(!(a1 < b1 && b1 < a1)); // Original failing case
+}
+
+// Arrays of all floating point types.
+class TypeInfo_Af : TypeInfoArrayGeneric!float {}
+class TypeInfo_Ao : TypeInfoArrayGeneric!(ifloat, float) {}
+class TypeInfo_Ad : TypeInfoArrayGeneric!double {}
+class TypeInfo_Ap : TypeInfoArrayGeneric!(idouble, double) {}
+class TypeInfo_Ae : TypeInfoArrayGeneric!real {}
+class TypeInfo_Aj : TypeInfoArrayGeneric!(ireal, real) {}
+class TypeInfo_Aq : TypeInfoArrayGeneric!cfloat {}
+class TypeInfo_Ar : TypeInfoArrayGeneric!cdouble {}
+class TypeInfo_Ac : TypeInfoArrayGeneric!creal {}
+
+// void[] is a bit different, behaves like ubyte[] for comparison purposes.
+class TypeInfo_Av : TypeInfo_Ah
+{
+ override string toString() const { return "void[]"; }
+
+ override @property inout(TypeInfo) next() inout
+ {
+ return cast(inout) typeid(void);
+ }
+
+ unittest
+ {
+ assert(typeid(void[]).toString == "void[]");
+ assert(typeid(void[]).next == typeid(void));
+ }
+}
+
+// all delegates
+unittest
+{
+ assert(typeid(void delegate(int)).flags == 1);
+}
+
+// typeof(null)
+class TypeInfo_n : TypeInfo
+{
+ override string toString() const @safe { return "typeof(null)"; }
+
+ override size_t getHash(scope const void* p) const
+ {
+ return 0;
+ }
+
+ override bool equals(in void* p1, in void* p2) const @trusted
+ {
+ return true;
+ }
+
+ override int compare(in void* p1, in void* p2) const @trusted
+ {
+ return 0;
+ }
+
+ override @property size_t tsize() const
+ {
+ return typeof(null).sizeof;
+ }
+
+ override const(void)[] initializer() const @trusted
+ {
+ __gshared immutable void[typeof(null).sizeof] init;
+ return init;
+ }
+
+ override void swap(void *p1, void *p2) const @trusted
+ {
+ }
+
+ override @property immutable(void)* rtInfo() nothrow pure const @safe { return rtinfoNoPointers; }
+
+ unittest
+ {
+ with (typeid(typeof(null)))
+ {
+ assert(toString == "typeof(null)");
+ assert(getHash(null) == 0);
+ assert(equals(null, null));
+ assert(compare(null, null) == 0);
+ assert(tsize == typeof(null).sizeof);
+ assert(initializer == new ubyte[(void*).sizeof]);
+ assert(rtInfo == rtinfoNoPointers);
+ }
+ }
+}
+
+// Test typeinfo for classes.
+unittest
+{
+ static class Bacon
+ {
+ int sizzle = 1;
+ override int opCmp(Object rhs) const
+ {
+ if (auto rhsb = cast(Bacon) rhs)
+ return (sizzle > rhsb.sizzle) - (sizzle < rhsb.sizzle);
+ return 0;
+ }
+ }
+ Object obj = new Bacon;
+ Bacon obj2 = new Bacon;
+ obj2.sizzle = 2;
+ auto dummy = new Object;
+ with (typeid(obj))
+ {
+ assert(toString[$ - 6 .. $] == ".Bacon");
+ assert(getHash(&obj) != 0);
+ assert(equals(&obj, &obj));
+ assert(!equals(&obj, &obj2));
+ assert(compare(&obj, &dummy) == 0);
+ assert(compare(&obj, &obj) == 0);
+ assert(compare(&obj, &obj2) == -1);
+ assert(compare(&obj2, &obj) == 1);
+ assert(tsize == Object.sizeof);
+ assert(rtInfo == RTInfo!Bacon);
+ assert(tsize == Object.sizeof);
+ assert(initializer.ptr !is null);
+ assert(initializer.length == __traits(classInstanceSize, Bacon));
+ assert(flags == 1);
+ }
+}
diff --git a/libphobos/m4/autoconf.m4 b/libphobos/m4/autoconf.m4
index f46a780..f0ca947 100644
--- a/libphobos/m4/autoconf.m4
+++ b/libphobos/m4/autoconf.m4
@@ -27,7 +27,7 @@ AU_DEFUN([AC_LANG_D], [AC_LANG(D)])
# AC_LANG_PROGRAM(D)([PROLOGUE], [BODY])
# ---------------------------------------
m4_define([AC_LANG_PROGRAM(D)],
-[module mod;
+[module object;
$1
extern(C) int main() {
diff --git a/libphobos/m4/druntime.m4 b/libphobos/m4/druntime.m4
index 7221712..2a7a689 100644
--- a/libphobos/m4/druntime.m4
+++ b/libphobos/m4/druntime.m4
@@ -116,3 +116,22 @@ AC_DEFUN([DRUNTIME_INSTALL_DIRECTORIES],
gdc_include_dir='$(libdir)/gcc/${target_alias}/${gcc_version}/include/d'
AC_SUBST(gdc_include_dir)
])
+
+# DRUNTIME_SECTION_FLAGS
+# ----------------------
+# Check for -ffunction-sections nad -fdata-sections.
+AC_DEFUN([DRUNTIME_SECTION_FLAGS],
+[
+ WITH_LOCAL_DRUNTIME([
+ AC_LANG_PUSH([D])
+ GDCFLAGS="$GDCFLAGS -g -Werror -ffunction-sections -fdata-sections"
+ AC_TRY_COMPILE([int foo; void bar() { }],[return 0;],
+ [ac_fdsections=yes], [ac_fdsections=no])
+ if test "x$ac_fdsections" = "xyes"; then
+ SECTION_FLAGS='-ffunction-sections -fdata-sections'
+ fi
+ AC_MSG_RESULT($ac_fdsections)
+ AC_LANG_POP([D])
+ ], [-nophoboslib])
+ AC_SUBST(SECTION_FLAGS)
+])
diff --git a/libphobos/m4/druntime/libraries.m4 b/libphobos/m4/druntime/libraries.m4
index 743d3e3..45a56f6 100644
--- a/libphobos/m4/druntime/libraries.m4
+++ b/libphobos/m4/druntime/libraries.m4
@@ -116,7 +116,7 @@ AC_DEFUN([DRUNTIME_LIBRARIES_ATOMIC],
DCFG_HAVE_LIBATOMIC=false
LIBATOMIC=
- AS_IF([test "x$with_libatomic" != "xno"], [
+ AS_IF([test "x$enable_libatomic" != "xno" && test "x$with_libatomic" != "xno"], [
DCFG_HAVE_LIBATOMIC=true
LIBATOMIC=../../libatomic/libatomic_convenience.la
], [
@@ -145,7 +145,7 @@ AC_DEFUN([DRUNTIME_LIBRARIES_BACKTRACE],
AS_HELP_STRING([--without-libbacktrace],
[Do not use libbacktrace in core.runtime (default: auto)]))
- AS_IF([test "x$with_libbacktrace" != "xno"], [
+ AS_IF([test "x$enable_libbacktrace" != "xno" && test "x$with_libbacktrace" != "xno"], [
LIBBACKTRACE=../../libbacktrace/libbacktrace.la
gdc_save_CPPFLAGS=$CPPFLAGS
diff --git a/libphobos/m4/druntime/os.m4 b/libphobos/m4/druntime/os.m4
index ed93e30..15cde3b 100644
--- a/libphobos/m4/druntime/os.m4
+++ b/libphobos/m4/druntime/os.m4
@@ -54,9 +54,10 @@ AC_DEFUN([DRUNTIME_OS_DETECT],
# DRUNTIME_OS_SOURCES
# -------------------
-# Detect target OS and add DRUNTIME_OS_AIX DRUNTIME_OS_DARWIN
-# DRUNTIME_OS_FREEBSD DRUNTIME_OS_LINUX DRUNTIME_OS_MINGW
-# DRUNTIME_OS_SOLARIS DRUNTIME_OS_OPENBSD conditionals.
+# Detect target OS and add DRUNTIME_OS_AIX DRUNTIME_OS_ANDROID
+# DRUNTIME_OS_DARWIN DRUNTIME_OS_DRAGONFLYBSD DRUNTIME_OS_FREEBSD
+# DRUNTIME_OS_LINUX DRUNTIME_OS_MINGW DRUNTIME_OS_NETBSD
+# DRUNTIME_OS_OPENBSD DRUNTIME_OS_SOLARIS conditionals.
# If the system is posix, add DRUNTIME_OS_POSIX conditional.
AC_DEFUN([DRUNTIME_OS_SOURCES],
[
@@ -149,17 +150,31 @@ AC_DEFUN([DRUNTIME_OS_ARM_EABI_UNWINDER],
# substitute DCFG_MINFO_BRACKETING.
AC_DEFUN([DRUNTIME_OS_MINFO_BRACKETING],
[
+ AC_REQUIRE([DRUNTIME_OS_DETECT])
+
AC_LANG_PUSH([C])
AC_MSG_CHECKING([for minfo section bracketing])
+ case "$druntime_cv_target_os" in
+ darwin*)
+ section="__DATA,__minfodata"
+ start="section\$start\$__DATA\$__minfodata"
+ stop="section\$end\$__DATA\$__minfodata"
+ ;;
+ *)
+ section="minfo"
+ start="__start_minfo"
+ stop="__stop_minfo"
+ ;;
+ esac
AC_LINK_IFELSE([AC_LANG_SOURCE([
- void* module_info_ptr __attribute__((section ("minfo")));
- extern void* __start_minfo __attribute__((visibility ("hidden")));
- extern void* __stop_minfo __attribute__((visibility ("hidden")));
+ void* module_info_ptr __attribute__((section ("$section")));
+ extern void* start_minfo __asm__("$start") __attribute__((visibility ("hidden")));
+ extern void* stop_minfo __asm__("$stop") __attribute__((visibility ("hidden")));
int main()
{
// Never run, just to prevent compiler from optimizing access
- return &__start_minfo == &__stop_minfo;
+ return (int)(&stop_minfo - &start_minfo);
}
])],
[AC_MSG_RESULT([yes])
diff --git a/libphobos/m4/gcc_support.m4 b/libphobos/m4/gcc_support.m4
index 0903ed4..cc1acb4 100644
--- a/libphobos/m4/gcc_support.m4
+++ b/libphobos/m4/gcc_support.m4
@@ -27,7 +27,7 @@ AC_DEFUN([PHOBOS_ABS_SRCDIR], [
AC_DEFUN([WITH_LOCAL_DRUNTIME], [
AC_REQUIRE([PHOBOS_ABS_SRCDIR])
gdc_save_DFLAGS=$GDCFLAGS
- GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $2 $GDCFLAGS"
+ GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $2 $GDCFLAGS"
$1
GDCFLAGS=$gdc_save_DFLAGS
])
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index cd620c9..01cf594 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-38873fe6ee70fe8e2b7a41b7c3663e090e27d61b
+55bb17543138a87c376a84745f2a30ec00bdecd9
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am
index 3769d8e..9f62510 100644
--- a/libphobos/src/Makefile.am
+++ b/libphobos/src/Makefile.am
@@ -1,5 +1,5 @@
## Makefile for the Phobos standard library.
-## Copyright (C) 2012-2020 Free Software Foundation, Inc.
+## Copyright (C) 2012-2021 Free Software Foundation, Inc.
##
## GCC is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@@ -24,8 +24,8 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) \
# D flags for compilation
AM_DFLAGS= \
- $(phobos_compiler_pic_flag) \
- $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
+ $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
AM_CFLAGS=$(CET_FLAGS)
@@ -45,8 +45,12 @@ libgphobos_la_SOURCES = $(ALL_PHOBOS_SOURCES)
libgphobos_la_LIBTOOLFLAGS =
libgphobos_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../libdruntime/gcc \
-version-info $(libtool_VERSION)
+if ENABLE_LIBDRUNTIME_ONLY
+libgphobos_la_LIBADD = ../libdruntime/libgdruntime_convenience.la
+else
libgphobos_la_LIBADD = \
../libdruntime/libgdruntime_convenience.la $(LIBZ)
+endif
libgphobos_la_DEPENDENCIES = \
../libdruntime/libgdruntime_convenience.la libgphobos.spec
@@ -135,11 +139,11 @@ PHOBOS_DSOURCES = etc/c/curl.d etc/c/sqlite3.d etc/c/zlib.d \
std/regex/internal/backtracking.d std/regex/internal/generator.d \
std/regex/internal/ir.d std/regex/internal/kickstart.d \
std/regex/internal/parser.d std/regex/internal/tests.d \
- std/regex/internal/thompson.d std/regex/package.d std/signals.d \
- std/socket.d std/stdint.d std/stdio.d std/string.d std/system.d \
- std/traits.d std/typecons.d std/typetuple.d std/uni.d std/uri.d \
- std/utf.d std/uuid.d std/variant.d std/windows/charset.d \
- std/windows/registry.d std/windows/syserror.d std/xml.d std/zip.d \
- std/zlib.d
+ std/regex/internal/tests2.d std/regex/internal/thompson.d \
+ std/regex/package.d std/signals.d std/socket.d std/stdint.d \
+ std/stdio.d std/string.d std/system.d std/traits.d std/typecons.d \
+ std/typetuple.d std/uni.d std/uri.d std/utf.d std/uuid.d std/variant.d \
+ std/windows/charset.d std/windows/registry.d std/windows/syserror.d \
+ std/xml.d std/zip.d std/zlib.d
endif
diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in
index 2e72178..f8b7648 100644
--- a/libphobos/src/Makefile.in
+++ b/libphobos/src/Makefile.in
@@ -249,6 +249,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/kickstart.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/parser.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/tests.lo \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/tests2.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/thompson.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/package.lo \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/signals.lo std/socket.lo \
@@ -387,6 +388,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
+SECTION_FLAGS = @SECTION_FLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -414,6 +416,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -443,6 +447,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -477,8 +482,8 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) \
# D flags for compilation
AM_DFLAGS = \
- $(phobos_compiler_pic_flag) \
- $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
+ $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
@@ -499,9 +504,10 @@ libgphobos_la_LIBTOOLFLAGS =
libgphobos_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../libdruntime/gcc \
-version-info $(libtool_VERSION)
-libgphobos_la_LIBADD = \
- ../libdruntime/libgdruntime_convenience.la $(LIBZ)
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@libgphobos_la_LIBADD = \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ ../libdruntime/libgdruntime_convenience.la $(LIBZ)
+@ENABLE_LIBDRUNTIME_ONLY_TRUE@libgphobos_la_LIBADD = ../libdruntime/libgdruntime_convenience.la
libgphobos_la_DEPENDENCIES = \
../libdruntime/libgdruntime_convenience.la libgphobos.spec
@@ -569,12 +575,12 @@ libgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/backtracking.d std/regex/internal/generator.d \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/ir.d std/regex/internal/kickstart.d \
@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/parser.d std/regex/internal/tests.d \
-@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/thompson.d std/regex/package.d std/signals.d \
-@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/socket.d std/stdint.d std/stdio.d std/string.d std/system.d \
-@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/traits.d std/typecons.d std/typetuple.d std/uni.d std/uri.d \
-@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/utf.d std/uuid.d std/variant.d std/windows/charset.d \
-@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/windows/registry.d std/windows/syserror.d std/xml.d std/zip.d \
-@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/zlib.d
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/tests2.d std/regex/internal/thompson.d \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/package.d std/signals.d std/socket.d std/stdint.d \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/stdio.d std/string.d std/system.d std/traits.d std/typecons.d \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/typetuple.d std/uni.d std/uri.d std/utf.d std/uuid.d std/variant.d \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/windows/charset.d std/windows/registry.d std/windows/syserror.d \
+@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/xml.d std/zip.d std/zlib.d
# Source file definitions. Boring stuff, auto-generated with
@@ -848,6 +854,7 @@ std/regex/internal/ir.lo: std/regex/internal/$(am__dirstamp)
std/regex/internal/kickstart.lo: std/regex/internal/$(am__dirstamp)
std/regex/internal/parser.lo: std/regex/internal/$(am__dirstamp)
std/regex/internal/tests.lo: std/regex/internal/$(am__dirstamp)
+std/regex/internal/tests2.lo: std/regex/internal/$(am__dirstamp)
std/regex/internal/thompson.lo: std/regex/internal/$(am__dirstamp)
std/regex/$(am__dirstamp):
@$(MKDIR_P) std/regex
diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d
index c77792d..19cfb77 100644
--- a/libphobos/src/std/algorithm/iteration.d
+++ b/libphobos/src/std/algorithm/iteration.d
@@ -769,9 +769,9 @@ private struct MapResult(alias fun, Range)
string s1 = "hello world!";
dstring s2 = "日本語";
dstring s3 = "hello world!"d;
- auto ms1 = map!(std.ascii.toUpper)(s1);
- auto ms2 = map!(std.ascii.toUpper)(s2);
- auto ms3 = map!(std.ascii.toUpper)(s3);
+ auto ms1 = map!(toUpper)(s1);
+ auto ms2 = map!(toUpper)(s2);
+ auto ms3 = map!(toUpper)(s3);
static assert(!is(ms1[0])); //narrow strings can't be indexed
assert(ms2[0] == '日');
assert(ms3[0] == 'H');
@@ -4450,7 +4450,7 @@ private struct SplitterResult(alias isTerminator, Range)
["là", "dove", "terminava", "quella", "valle"]
));
assert(equal(
- splitter!(std.uni.isWhite)("là dove terminava quella valle"),
+ splitter!(isWhite)("là dove terminava quella valle"),
["là", "dove", "terminava", "quella", "valle"]
));
assert(equal(splitter!"a=='本'"("日本語"), ["日", "語"]));
diff --git a/libphobos/src/std/algorithm/searching.d b/libphobos/src/std/algorithm/searching.d
index 6468a87..09073f6 100644
--- a/libphobos/src/std/algorithm/searching.d
+++ b/libphobos/src/std/algorithm/searching.d
@@ -959,8 +959,8 @@ if (isInputRange!R &&
import std.ascii : isDigit;
import std.uni : isWhite;
- assert(countUntil!(std.uni.isWhite)("hello world") == 5);
- assert(countUntil!(std.ascii.isDigit)("hello world") == -1);
+ assert(countUntil!(isWhite)("hello world") == 5);
+ assert(countUntil!(isDigit)("hello world") == -1);
assert(countUntil!"a > 20"([0, 7, 12, 22, 9]) == 3);
}
diff --git a/libphobos/src/std/container/rbtree.d b/libphobos/src/std/container/rbtree.d
index 861da5e..5e31ac2 100644
--- a/libphobos/src/std/container/rbtree.d
+++ b/libphobos/src/std/container/rbtree.d
@@ -1814,8 +1814,8 @@ assert(equal(rbt[], [5]));
test!byte();
}
-import std.range.primitives : isInputRange, isSomeString, ElementType;
-import std.traits : isArray;
+import std.range.primitives : isInputRange, ElementType;
+import std.traits : isArray, isSomeString;
/++
Convenience function for creating a $(D RedBlackTree!E) from a list of
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index 743d203..3560d13 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -3148,8 +3148,6 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum
{
version (CRuntime_Microsoft)
ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod
- else version (CRuntime_Bionic)
- ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod
else
ld1 = strtold(s.ptr, null);
}
@@ -3969,7 +3967,7 @@ if (isOctalLiteral(num))
/// Ditto
template octal(alias decimalInteger)
-if (isIntegral!(typeof(decimalInteger)))
+if (is(typeof(decimalInteger)) && isIntegral!(typeof(decimalInteger)))
{
enum octal = octal!(typeof(decimalInteger))(to!string(decimalInteger));
}
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
index 326b544..913d360 100644
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -7,6 +7,15 @@
+/
module std.datetime.systime;
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
import core.time;
import std.datetime.date;
import std.datetime.timezone;
@@ -39,6 +48,16 @@ version (unittest)
initializeTests();
}
+version (unittest) private bool clockSupported(ClockType c)
+{
+ // Skip unsupported clocks on older linux kernels, assume that only
+ // CLOCK_MONOTONIC and CLOCK_REALTIME exist, as that is the lowest
+ // common denominator supported by all versions of Linux pre-2.6.12.
+ version (Linux_Pre_2639)
+ return c == ClockType.normal || c == ClockType.precise;
+ else
+ return true;
+}
/++
Effectively a namespace to make it clear that the methods it contains are
@@ -95,10 +114,13 @@ public:
foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second))
{
scope(failure) writefln("ClockType.%s", ct);
- auto value1 = Clock.currTime!ct;
- auto value2 = Clock.currTime!ct(UTC());
- assert(value1 <= value2, format("%s %s", value1, value2));
- assert(abs(value1 - value2) <= seconds(2));
+ static if (clockSupported(ct))
+ {
+ auto value1 = Clock.currTime!ct;
+ auto value2 = Clock.currTime!ct(UTC());
+ assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct));
+ assert(abs(value1 - value2) <= seconds(2), format("ClockType.%s", ct));
+ }
}
}
@@ -148,18 +170,19 @@ public:
static import core.stdc.time;
enum hnsecsToUnixEpoch = unixTimeToStdTime(0);
- version (OSX)
+ version (Darwin)
{
static if (clockType == ClockType.second)
return unixTimeToStdTime(core.stdc.time.time(null));
else
{
import core.sys.posix.sys.time : gettimeofday, timeval;
- timeval tv;
- if (gettimeofday(&tv, null) != 0)
- throw new TimeException("Call to gettimeofday() failed");
+ timeval tv = void;
+ // Posix gettimeofday called with a valid timeval address
+ // and a null second parameter doesn't fail.
+ gettimeofday(&tv, null);
return convert!("seconds", "hnsecs")(tv.tv_sec) +
- convert!("usecs", "hnsecs")(tv.tv_usec) +
+ tv.tv_usec * 10 +
hnsecsToUnixEpoch;
}
}
@@ -175,9 +198,16 @@ public:
else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
else static assert(0, "Previous static if is wrong.");
- timespec ts;
- if (clock_gettime(clockArg, &ts) != 0)
- throw new TimeException("Call to clock_gettime() failed");
+ timespec ts = void;
+ immutable error = clock_gettime(clockArg, &ts);
+ // Posix clock_gettime called with a valid address and valid clock_id is only
+ // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
+ // is long or larger overflow won't happen before 292 billion years A.D.
+ static if (ts.tv_sec.max < long.max)
+ {
+ if (error)
+ throw new TimeException("Call to clock_gettime() failed");
+ }
return convert!("seconds", "hnsecs")(ts.tv_sec) +
ts.tv_nsec / 100 +
hnsecsToUnixEpoch;
@@ -192,9 +222,16 @@ public:
else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE;
else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND;
else static assert(0, "Previous static if is wrong.");
- timespec ts;
- if (clock_gettime(clockArg, &ts) != 0)
- throw new TimeException("Call to clock_gettime() failed");
+ timespec ts = void;
+ immutable error = clock_gettime(clockArg, &ts);
+ // Posix clock_gettime called with a valid address and valid clock_id is only
+ // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
+ // is long or larger overflow won't happen before 292 billion years A.D.
+ static if (ts.tv_sec.max < long.max)
+ {
+ if (error)
+ throw new TimeException("Call to clock_gettime() failed");
+ }
return convert!("seconds", "hnsecs")(ts.tv_sec) +
ts.tv_nsec / 100 +
hnsecsToUnixEpoch;
@@ -205,12 +242,38 @@ public:
return unixTimeToStdTime(core.stdc.time.time(null));
else
{
- import core.sys.posix.sys.time : gettimeofday, timeval;
- timeval tv;
- if (gettimeofday(&tv, null) != 0)
- throw new TimeException("Call to gettimeofday() failed");
- return convert!("seconds", "hnsecs")(tv.tv_sec) +
- convert!("usecs", "hnsecs")(tv.tv_usec) +
+ import core.sys.netbsd.time : clock_gettime, CLOCK_REALTIME;
+ timespec ts = void;
+ immutable error = clock_gettime(CLOCK_REALTIME, &ts);
+ // Posix clock_gettime called with a valid address and valid clock_id is only
+ // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
+ // is long or larger overflow won't happen before 292 billion years A.D.
+ static if (ts.tv_sec.max < long.max)
+ {
+ if (error)
+ throw new TimeException("Call to clock_gettime() failed");
+ }
+ return convert!("seconds", "hnsecs")(ts.tv_sec) +
+ ts.tv_nsec / 100 +
+ hnsecsToUnixEpoch;
+ }
+ }
+ else version (OpenBSD)
+ {
+ static if (clockType == ClockType.second)
+ return unixTimeToStdTime(core.stdc.time.time(null));
+ else
+ {
+ import core.sys.openbsd.time : clock_gettime, CLOCK_REALTIME;
+ static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME;
+ else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
+ else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
+ else static assert(0, "Previous static if is wrong.");
+ timespec ts;
+ if (clock_gettime(clockArg, &ts) != 0)
+ throw new TimeException("Call to clock_gettime() failed");
+ return convert!("seconds", "hnsecs")(ts.tv_sec) +
+ ts.tv_nsec / 100 +
hnsecsToUnixEpoch;
}
}
@@ -223,9 +286,16 @@ public:
else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE;
else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND;
else static assert(0, "Previous static if is wrong.");
- timespec ts;
- if (clock_gettime(clockArg, &ts) != 0)
- throw new TimeException("Call to clock_gettime() failed");
+ timespec ts = void;
+ immutable error = clock_gettime(clockArg, &ts);
+ // Posix clock_gettime called with a valid address and valid clock_id is only
+ // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
+ // is long or larger overflow won't happen before 292 billion years A.D.
+ static if (ts.tv_sec.max < long.max)
+ {
+ if (error)
+ throw new TimeException("Call to clock_gettime() failed");
+ }
return convert!("seconds", "hnsecs")(ts.tv_sec) +
ts.tv_nsec / 100 +
hnsecsToUnixEpoch;
@@ -241,9 +311,16 @@ public:
else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
else static assert(0, "Previous static if is wrong.");
- timespec ts;
- if (clock_gettime(clockArg, &ts) != 0)
- throw new TimeException("Call to clock_gettime() failed");
+ timespec ts = void;
+ immutable error = clock_gettime(clockArg, &ts);
+ // Posix clock_gettime called with a valid address and valid clock_id is only
+ // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
+ // is long or larger overflow won't happen before 292 billion years A.D.
+ static if (ts.tv_sec.max < long.max)
+ {
+ if (error)
+ throw new TimeException("Call to clock_gettime() failed");
+ }
return convert!("seconds", "hnsecs")(ts.tv_sec) +
ts.tv_nsec / 100 +
hnsecsToUnixEpoch;
@@ -270,10 +347,13 @@ public:
foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second))
{
scope(failure) writefln("ClockType.%s", ct);
- auto value1 = Clock.currStdTime!ct;
- auto value2 = Clock.currStdTime!ct;
- assert(value1 <= value2, format("%s %s", value1, value2));
- assert(abs(value1 - value2) <= limit);
+ static if (clockSupported(ct))
+ {
+ auto value1 = Clock.currStdTime!ct;
+ auto value2 = Clock.currStdTime!ct;
+ assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct));
+ assert(abs(value1 - value2) <= limit);
+ }
}
}
@@ -9489,7 +9569,7 @@ afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length);
}
// year
- auto found = value[2 .. value.length].find!(not!(std.ascii.isDigit))();
+ auto found = value[2 .. value.length].find!(not!(isDigit))();
size_t yearLen = value.length - found.length;
if (found.length == 0)
throw new DateTimeException("Invalid year");
@@ -9579,7 +9659,7 @@ afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length);
case "J": case "j": throw new DateTimeException("Invalid timezone");
default:
{
- if (all!(std.ascii.isAlpha)(value[0 .. tzLen]))
+ if (all!(isAlpha)(value[0 .. tzLen]))
{
tz = new immutable SimpleTimeZone(Duration.zero);
break;
diff --git a/libphobos/src/std/datetime/timezone.d b/libphobos/src/std/datetime/timezone.d
index 7ae1902..9b744ff 100644
--- a/libphobos/src/std/datetime/timezone.d
+++ b/libphobos/src/std/datetime/timezone.d
@@ -14,6 +14,15 @@ import std.exception : enforce;
import std.range.primitives;
import std.traits : isIntegral, isSomeString, Unqual;
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
version (Windows)
{
import core.stdc.time : time_t;
@@ -296,7 +305,7 @@ public:
else version (NetBSD) enum utcZone = "UTC";
else version (DragonFlyBSD) enum utcZone = "UTC";
else version (linux) enum utcZone = "UTC";
- else version (OSX) enum utcZone = "UTC";
+ else version (Darwin) enum utcZone = "UTC";
else version (Solaris) enum utcZone = "UTC";
else static assert(0, "The location of the UTC timezone file on this Posix platform must be set.");
@@ -671,7 +680,11 @@ public:
@safe unittest
{
- assert(LocalTime().dstName !is null);
+ // tzname, called from dstName, isn't set by default for Musl.
+ version (CRuntime_Musl)
+ assert(LocalTime().dstName is null);
+ else
+ assert(LocalTime().dstName !is null);
version (Posix)
{
diff --git a/libphobos/src/std/exception.d b/libphobos/src/std/exception.d
index 73afadc..56133c9 100644
--- a/libphobos/src/std/exception.d
+++ b/libphobos/src/std/exception.d
@@ -1478,10 +1478,13 @@ private bool isUnionAliasedImpl(T)(size_t offset)
static assert( isUnionAliased!(S.A5, 1)); //a5.b1;
}
+version (CRuntime_Glibc) version = GNU_STRERROR;
+version (CRuntime_UClibc) version = GNU_STRERROR;
+
package string errnoString(int errno) nothrow @trusted
{
import core.stdc.string : strlen;
- version (CRuntime_Glibc)
+ version (GNU_STRERROR)
{
import core.stdc.string : strerror_r;
char[1024] buf = void;
diff --git a/libphobos/src/std/experimental/allocator/building_blocks/region.d b/libphobos/src/std/experimental/allocator/building_blocks/region.d
index 835d093..53f5ef9 100644
--- a/libphobos/src/std/experimental/allocator/building_blocks/region.d
+++ b/libphobos/src/std/experimental/allocator/building_blocks/region.d
@@ -5,6 +5,15 @@ import std.experimental.allocator.building_blocks.null_allocator;
import std.experimental.allocator.common;
import std.typecons : Flag, Yes, No;
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
/**
A $(D Region) allocator allocates memory straight from one contiguous chunk.
There is no deallocation, and once the region is full, allocation requests
@@ -580,14 +589,26 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
assert(a.length == 2001);
}
-version(CRuntime_Musl)
+version (CRuntime_Musl)
{
// sbrk and brk are disabled in Musl:
// https://git.musl-libc.org/cgit/musl/commit/?id=7a995fe706e519a4f55399776ef0df9596101f93
// https://git.musl-libc.org/cgit/musl/commit/?id=863d628d93ea341b6a32661a1654320ce69f6a07
-} else:
-private extern(C) void* sbrk(long);
-private extern(C) int brk(shared void*);
+}
+version (DragonFlyBSD)
+{
+ // sbrk is deprecated in favor of mmap (we could implement a mmap + MAP_NORESERVE + PROT_NONE version)
+ // brk has been removed
+ // https://www.dragonflydigest.com/2019/02/22/22586.html
+ // http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/dc676eaefa61b0f47bbea1c53eab86fd5ccd78c6
+ // http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/4b5665564ef37dc939a3a9ffbafaab9894c18885
+ // http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/8618d94a0e2ff8303ad93c123a3fa598c26a116e
+}
+else
+{
+ private extern(C) void* sbrk(long) nothrow @nogc;
+ private extern(C) int brk(shared void*) nothrow @nogc;
+}
/**
@@ -599,11 +620,14 @@ that uncontrolled calls to $(D brk) and $(D sbrk) may affect the workings of $(D
SbrkRegion) adversely.
*/
+version (CRuntime_Musl) {} else
+version (DragonFlyBSD) {} else
version (Posix) struct SbrkRegion(uint minAlign = platformAlignment)
{
import core.sys.posix.pthread : pthread_mutex_init, pthread_mutex_destroy,
pthread_mutex_t, pthread_mutex_lock, pthread_mutex_unlock,
- PTHREAD_MUTEX_INITIALIZER;
+
+ PTHREAD_MUTEX_INITIALIZER;
private static shared pthread_mutex_t sbrkMutex = PTHREAD_MUTEX_INITIALIZER;
import std.typecons : Ternary;
@@ -763,7 +787,9 @@ version (Posix) struct SbrkRegion(uint minAlign = platformAlignment)
}
}
-version (Posix) @system unittest
+version (CRuntime_Musl) {} else
+version (DragonFlyBSD) {} else
+version (Posix) @system nothrow @nogc unittest
{
// Let's test the assumption that sbrk(n) returns the old address
const p1 = sbrk(0);
@@ -775,7 +801,9 @@ version (Posix) @system unittest
sbrk(-4096);
}
-version (Posix) @system unittest
+version (CRuntime_Musl) {} else
+version (DragonFlyBSD) {} else
+version (Posix) @system nothrow @nogc unittest
{
import std.typecons : Ternary;
alias alloc = SbrkRegion!(8).instance;
@@ -786,7 +814,7 @@ version (Posix) @system unittest
assert(alloc.owns(a) == Ternary.yes);
assert(alloc.owns(b) == Ternary.yes);
// reducing the brk does not work on OSX
- version (OSX) {} else
+ version (Darwin) {} else
{
assert(alloc.deallocate(b));
assert(alloc.deallocateAll);
diff --git a/libphobos/src/std/experimental/allocator/mmap_allocator.d b/libphobos/src/std/experimental/allocator/mmap_allocator.d
index 945859b..e07d444 100644
--- a/libphobos/src/std/experimental/allocator/mmap_allocator.d
+++ b/libphobos/src/std/experimental/allocator/mmap_allocator.d
@@ -46,6 +46,21 @@ struct MmapAllocator
if (b.ptr) munmap(b.ptr, b.length) == 0 || assert(0);
return true;
}
+
+ // Anonymous mmap might be zero-filled on all Posix systems but
+ // not all commit to this in the documentation.
+ version (linux)
+ // http://man7.org/linux/man-pages/man2/mmap.2.html
+ package alias allocateZeroed = allocate;
+ else version (NetBSD)
+ // http://netbsd.gw.com/cgi-bin/man-cgi?mmap+2+NetBSD-current
+ package alias allocateZeroed = allocate;
+ else version (Solaris)
+ // https://docs.oracle.com/cd/E88353_01/html/E37841/mmap-2.html
+ package alias allocateZeroed = allocate;
+ else version (AIX)
+ // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.basetrf1/mmap.htm
+ package alias allocateZeroed = allocate;
}
else version (Windows)
{
@@ -67,6 +82,8 @@ struct MmapAllocator
{
return b.ptr is null || VirtualFree(b.ptr, 0, MEM_RELEASE) != 0;
}
+
+ package alias allocateZeroed = allocate;
}
}
diff --git a/libphobos/src/std/experimental/logger/nulllogger.d b/libphobos/src/std/experimental/logger/nulllogger.d
index fa511be..0c55377 100644
--- a/libphobos/src/std/experimental/logger/nulllogger.d
+++ b/libphobos/src/std/experimental/logger/nulllogger.d
@@ -31,7 +31,7 @@ class NullLogger : Logger
///
@safe unittest
{
- import std.experimental.logger.nulllogger : LogLevel;
+ import std.experimental.logger.core : LogLevel;
auto nl1 = new NullLogger(LogLevel.all);
nl1.info("You will never read this.");
diff --git a/libphobos/src/std/experimental/typecons.d b/libphobos/src/std/experimental/typecons.d
index 6906f05..07eed8f 100644
--- a/libphobos/src/std/experimental/typecons.d
+++ b/libphobos/src/std/experimental/typecons.d
@@ -23,8 +23,7 @@ module std.experimental.typecons;
import std.meta; // : AliasSeq, allSatisfy;
import std.traits;
-import std.typecons : Tuple, tuple, Bind, DerivedFunctionType,
- isImplicitlyConvertible, mixinAll, staticIota,
+import std.typecons : Tuple, tuple, Bind, DerivedFunctionType, mixinAll, staticIota,
GetOverloadedMethods;
private
@@ -113,7 +112,8 @@ if (Targets.length >= 1 && allSatisfy!(isMutable, Targets))
else
{
enum foundFunc = findCovariantFunction!(TargetMembers[i], Source, SourceMembers);
- debug
+ version (unittest) {}
+ else debug
{
static if (foundFunc == -1)
pragma(msg, "Could not locate matching function for: ",
diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d
index 9ba9929..99530cb 100644
--- a/libphobos/src/std/file.d
+++ b/libphobos/src/std/file.d
@@ -164,6 +164,16 @@ class FileException : Exception
+/
immutable uint errno;
+ private this(in char[] name, in char[] msg, string file, size_t line, uint errno) @safe pure
+ {
+ if (msg.empty)
+ super(name.idup, file, line);
+ else
+ super(text(name, ": ", msg), file, line);
+
+ this.errno = errno;
+ }
+
/++
Constructor which takes an error message.
@@ -175,12 +185,7 @@ class FileException : Exception
+/
this(in char[] name, in char[] msg, string file = __FILE__, size_t line = __LINE__) @safe pure
{
- if (msg.empty)
- super(name.idup, file, line);
- else
- super(text(name, ": ", msg), file, line);
-
- errno = 0;
+ this(name, msg, file, line, 0);
}
/++
@@ -200,8 +205,7 @@ class FileException : Exception
string file = __FILE__,
size_t line = __LINE__) @safe
{
- this(name, sysErrorString(errno), file, line);
- this.errno = errno;
+ this(name, sysErrorString(errno), file, line, errno);
}
else version (Posix) this(in char[] name,
uint errno = .errno,
@@ -209,8 +213,7 @@ class FileException : Exception
size_t line = __LINE__) @trusted
{
import std.exception : errnoString;
- this(name, errnoString(errno), file, line);
- this.errno = errno;
+ this(name, errnoString(errno), file, line, errno);
}
}
@@ -1487,6 +1490,15 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R))
// vfs.timestamp_precision sysctl to a value greater than zero.
// - OS X, where the native filesystem (HFS+) stores filesystem
// timestamps with 1-second precision.
+//
+// Note: on linux systems, although in theory a change to a file date
+// can be tracked with precision of 4 msecs, this test waits 20 msecs
+// to prevent possible problems relative to the CI services the dlang uses,
+// as they may have the HZ setting that controls the software clock set to 100
+// (instead of the more common 250).
+// see https://man7.org/linux/man-pages/man7/time.7.html
+// https://stackoverflow.com/a/14393315,
+// https://issues.dlang.org/show_bug.cgi?id=21148
version (FreeBSD) {} else
version (DragonFlyBSD) {} else
version (OSX) {} else
@@ -1505,7 +1517,7 @@ version (OSX) {} else
remove(deleteme);
assert(time != lastTime);
lastTime = time;
- Thread.sleep(10.msecs);
+ Thread.sleep(20.msecs);
}
}
@@ -2289,7 +2301,7 @@ if (isConvertibleToString!R)
@safe unittest
{
- import std.path : mkdir;
+ import std.file : mkdir;
static assert(__traits(compiles, mkdir(TestAliasedString(null))));
}
@@ -2754,15 +2766,27 @@ else version (NetBSD)
buffer.length *= 2;
}
}
+ else version (DragonFlyBSD)
+ {
+ import core.sys.dragonflybsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME;
+ import std.exception : errnoEnforce, assumeUnique;
+
+ int[4] mib = [CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1];
+ size_t len;
+
+ auto result = sysctl(mib.ptr, mib.length, null, &len, null, 0); // get the length of the path
+ errnoEnforce(result == 0);
+
+ auto buffer = new char[len - 1];
+ result = sysctl(mib.ptr, mib.length, buffer.ptr, &len, null, 0);
+ errnoEnforce(result == 0);
+
+ return buffer.assumeUnique;
+ }
else version (FreeBSD)
{
+ import core.sys.freebsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME;
import std.exception : errnoEnforce, assumeUnique;
- enum
- {
- CTL_KERN = 1,
- KERN_PROC = 14,
- KERN_PROC_PATHNAME = 12
- }
int[4] mib = [CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1];
size_t len;
@@ -2778,11 +2802,58 @@ else version (NetBSD)
}
else version (NetBSD)
{
- return readLink("/proc/self/exe");
+ import core.sys.netbsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC_ARGS, KERN_PROC_PATHNAME;
+ import std.exception : errnoEnforce, assumeUnique;
+
+ int[4] mib = [CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME];
+ size_t len;
+
+ auto result = sysctl(mib.ptr, mib.length, null, &len, null, 0); // get the length of the path
+ errnoEnforce(result == 0);
+
+ auto buffer = new char[len - 1];
+ result = sysctl(mib.ptr, mib.length, buffer.ptr, &len, null, 0);
+ errnoEnforce(result == 0);
+
+ return buffer.assumeUnique;
}
- else version (DragonFlyBSD)
+ else version (OpenBSD)
{
- return readLink("/proc/curproc/file");
+ import core.sys.openbsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC_ARGS, KERN_PROC_ARGV;
+ import core.sys.posix.unistd : getpid;
+ import std.conv : to;
+ import std.exception : enforce, errnoEnforce;
+ import std.process : searchPathFor;
+
+ int[4] mib = [CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV];
+ size_t len;
+
+ auto result = sysctl(mib.ptr, mib.length, null, &len, null, 0);
+ errnoEnforce(result == 0);
+
+ auto argv = new char*[len - 1];
+ result = sysctl(mib.ptr, mib.length, argv.ptr, &len, null, 0);
+ errnoEnforce(result == 0);
+
+ auto argv0 = argv[0];
+ if (*argv0 == '/' || *argv0 == '.')
+ {
+ import core.sys.posix.stdlib : realpath;
+ auto absolutePath = realpath(argv0, null);
+ scope (exit)
+ {
+ if (absolutePath)
+ free(absolutePath);
+ }
+ errnoEnforce(absolutePath);
+ return to!(string)(absolutePath);
+ }
+ else
+ {
+ auto absolutePath = searchPathFor(to!string(argv0));
+ errnoEnforce(absolutePath);
+ return absolutePath;
+ }
}
else version (Solaris)
{
@@ -4041,7 +4112,8 @@ auto dirEntries(string path, SpanMode mode, bool followSymlink = true)
import std.algorithm.searching : startsWith;
import std.array : array;
import std.conv : to;
- import std.path : dirEntries, buildPath, absolutePath;
+ import std.path : buildPath, absolutePath;
+ import std.file : dirEntries;
import std.process : thisProcessID;
import std.range.primitives : walkLength;
diff --git a/libphobos/src/std/format.d b/libphobos/src/std/format.d
index 64b1bd3..17e5906 100644
--- a/libphobos/src/std/format.d
+++ b/libphobos/src/std/format.d
@@ -5199,7 +5199,7 @@ body
}
debug (unformatRange) printf("\t");
debug (unformatRange) if (!input.empty) printf("input.front = %c, ", input.front);
- debug (unformatRange) printf("cont = %.*s\n", cont);
+ debug (unformatRange) printf("cont = %.*s\n", cast(int) cont.length, cont.ptr);
bool checkEnd()
{
@@ -5246,7 +5246,7 @@ body
auto sep = spec.sep !is null ? spec.sep
: fmt.trailing;
debug (unformatRange) {
- if (!sep.empty && !input.empty) printf("-> %c, sep = %.*s\n", input.front, sep);
+ if (!sep.empty && !input.empty) printf("-> %c, sep = %.*s\n", input.front, cast(int) sep.length, sep.ptr);
else printf("\n");
}
diff --git a/libphobos/src/std/internal/math/biguintcore.d b/libphobos/src/std/internal/math/biguintcore.d
index f5cd769..6fc2d16 100644
--- a/libphobos/src/std/internal/math/biguintcore.d
+++ b/libphobos/src/std/internal/math/biguintcore.d
@@ -2503,13 +2503,13 @@ pure nothrow
void printBiguint(const uint [] data)
{
char [] buff = biguintToHex(new char[data.length*9], data, '_');
- printf("%.*s\n", buff.length, buff.ptr);
+ printf("%.*s\n", cast(int) buff.length, buff.ptr);
}
void printDecimalBigUint(BigUint data)
{
auto str = data.toDecimalString(0);
- printf("%.*s\n", str.length, str.ptr);
+ printf("%.*s\n", cast(int) str.length, str.ptr);
}
uint [] a, b;
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index 3d18cfa..336c11a 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -167,19 +167,14 @@ version (SystemZ) version = IBMZ_Any;
version (RISCV32) version = RISCV_Any;
version (RISCV64) version = RISCV_Any;
-version (D_InlineAsm_X86)
-{
- version = InlineAsm_X86_Any;
-}
-else version (D_InlineAsm_X86_64)
-{
- version = InlineAsm_X86_Any;
-}
+version (D_InlineAsm_X86) version = InlineAsm_X86_Any;
+version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any;
-version (CRuntime_Microsoft)
+version (InlineAsm_X86_Any) version = InlineAsm_X87;
+version (InlineAsm_X87)
{
- version (InlineAsm_X86_Any)
- version = MSVC_InlineAsm;
+ static assert(real.mant_dig == 64);
+ version (CRuntime_Microsoft) version = InlineAsm_X87_MSVC;
}
version (X86_64) version = StaticallyHaveSSE;
@@ -268,8 +263,8 @@ version (unittest)
alias real_t = double;
else
alias real_t = real;
- ix = sprintf(bufx.ptr, "%.*Lg", ndigits, cast(real_t) x);
- iy = sprintf(bufy.ptr, "%.*Lg", ndigits, cast(real_t) y);
+ ix = sprintf(bufx.ptr, is(real_t == real) ? "%.*Lg" : "%.*g", ndigits, cast(real_t) x);
+ iy = sprintf(bufy.ptr, is(real_t == real) ? "%.*Lg" : "%.*g", ndigits, cast(real_t) y);
assert(ix < bufx.length && ix > 0);
assert(ix < bufy.length && ix > 0);
@@ -3610,7 +3605,7 @@ real log1p(real x) @safe pure nothrow @nogc
real log2(real x) @safe pure nothrow @nogc
{
version (INLINE_YL2X)
- return core.math.yl2x(x, 1);
+ return core.math.yl2x(x, 1.0L);
else
{
// Special cases are the same as for log.
@@ -4586,19 +4581,21 @@ real round(real x) @trusted nothrow @nogc
* If the fractional part of x is exactly 0.5, the return value is rounded
* away from zero.
*
- * $(BLUE This function is Posix-Only.)
+ * $(BLUE This function is not implemented for Digital Mars C runtime.)
*/
long lround(real x) @trusted nothrow @nogc
{
- version (Posix)
- return core.stdc.math.llroundl(x);
- else
+ version (CRuntime_DigitalMars)
assert(0, "lround not implemented");
+ else
+ return core.stdc.math.llroundl(x);
}
-version (Posix)
+///
+@safe nothrow @nogc unittest
{
- @safe nothrow @nogc unittest
+ version (CRuntime_DigitalMars) {}
+ else
{
assert(lround(0.49) == 0);
assert(lround(0.5) == 1);
diff --git a/libphobos/src/std/parallelism.d b/libphobos/src/std/parallelism.d
index 64fa2f9..61d5cea 100644
--- a/libphobos/src/std/parallelism.d
+++ b/libphobos/src/std/parallelism.d
@@ -40,6 +40,15 @@ License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
*/
module std.parallelism;
+version (OSX)
+ version = Darwin;
+else version (iOS)
+ version = Darwin;
+else version (TVOS)
+ version = Darwin;
+else version (WatchOS)
+ version = Darwin;
+
///
@system unittest
{
@@ -86,107 +95,82 @@ import std.meta;
import std.range.primitives;
import std.traits;
-version (OSX)
-{
- version = useSysctlbyname;
-}
-else version (FreeBSD)
-{
- version = useSysctlbyname;
-}
-else version (DragonFlyBSD)
-{
- version = useSysctlbyname;
-}
-else version (NetBSD)
-{
- version = useSysctlbyname;
-}
+/*
+(For now public undocumented with reserved name.)
+A lazily initialized global constant. The underlying value is a shared global
+statically initialized to `outOfBandValue` which must not be a legit value of
+the constant. Upon the first call the situation is detected and the global is
+initialized by calling `initializer`. The initializer is assumed to be pure
+(even if not marked as such), i.e. return the same value upon repeated calls.
+For that reason, no special precautions are taken so `initializer` may be called
+more than one time leading to benign races on the cached value.
-version (Windows)
-{
- // BUGS: Only works on Windows 2000 and above.
- shared static this()
- {
- import core.sys.windows.windows : SYSTEM_INFO, GetSystemInfo;
- import std.algorithm.comparison : max;
+In the quiescent state the cost of the function is an atomic load from a global.
- SYSTEM_INFO si;
- GetSystemInfo(&si);
- totalCPUs = max(1, cast(uint) si.dwNumberOfProcessors);
- }
+Params:
+ T = The type of the pseudo-constant (may be qualified)
+ outOfBandValue = A value that cannot be valid, it is used for initialization
+ initializer = The function performing initialization; must be `nothrow`
-}
-else version (linux)
-{
- shared static this()
- {
- import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;
- totalCPUs = cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
- }
-}
-else version (Solaris)
-{
- shared static this()
- {
- import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;
- totalCPUs = cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
- }
-}
-else version (useSysctlbyname)
+Returns:
+ The lazily initialized value
+*/
+@property pure
+T __lazilyInitializedConstant(T, alias outOfBandValue, alias initializer)()
+if (is(Unqual!T : T)
+ && is(typeof(initializer()) : T)
+ && is(typeof(outOfBandValue) : T))
{
- extern(C) int sysctlbyname(
- const char *, void *, size_t *, void *, size_t
- );
-
- shared static this()
- {
- version (OSX)
- {
- auto nameStr = "machdep.cpu.core_count\0".ptr;
- }
- else version (FreeBSD)
+ static T impl() nothrow
+ {
+ // Thread-local cache
+ static Unqual!T tls = outOfBandValue;
+ auto local = tls;
+ // Shortest path, no atomic operations
+ if (local != outOfBandValue) return local;
+ // Process-level cache
+ static shared Unqual!T result = outOfBandValue;
+ // Initialize both process-level cache and tls
+ local = atomicLoad(result);
+ if (local == outOfBandValue)
{
- auto nameStr = "hw.ncpu\0".ptr;
+ local = initializer();
+ atomicStore(result, local);
}
- else version (DragonFlyBSD)
- {
- auto nameStr = "hw.ncpu\0".ptr;
- }
- else version (NetBSD)
- {
- auto nameStr = "hw.ncpu\0".ptr;
- }
-
- uint ans;
- size_t len = uint.sizeof;
- sysctlbyname(nameStr, &ans, &len, null, 0);
- totalCPUs = ans;
+ tls = local;
+ return local;
}
+ import std.traits : SetFunctionAttributes;
+ alias Fun = SetFunctionAttributes!(typeof(&impl), "D",
+ functionAttributes!(typeof(&impl)) | FunctionAttribute.pure_);
+ auto purified = (() @trusted => cast(Fun) &impl)();
+ return purified();
}
-else
-{
- static assert(0, "Don't know how to get N CPUs on this OS.");
-}
-immutable size_t cacheLineSize;
-shared static this()
+// Returns the size of a cache line.
+alias cacheLineSize =
+ __lazilyInitializedConstant!(immutable(size_t), size_t.max, cacheLineSizeImpl);
+
+private size_t cacheLineSizeImpl() @nogc nothrow @trusted
{
+ size_t result = 0;
import core.cpuid : datacache;
- size_t lineSize = 0;
- foreach (cachelevel; datacache)
+ foreach (ref const cachelevel; datacache)
{
- if (cachelevel.lineSize > lineSize && cachelevel.lineSize < uint.max)
+ if (cachelevel.lineSize > result && cachelevel.lineSize < uint.max)
{
- lineSize = cachelevel.lineSize;
+ result = cachelevel.lineSize;
}
}
-
- cacheLineSize = lineSize;
+ return result;
}
+@nogc @safe nothrow unittest
+{
+ assert(cacheLineSize == cacheLineSizeImpl);
+}
/* Atomics code. These forward to core.atomic, but are written like this
for two reasons:
@@ -957,7 +941,81 @@ if (is(typeof(fun(args))) && isSafeTask!F)
The total number of CPU cores available on the current machine, as reported by
the operating system.
*/
-immutable uint totalCPUs;
+alias totalCPUs =
+ __lazilyInitializedConstant!(immutable(uint), uint.max, totalCPUsImpl);
+
+uint totalCPUsImpl() @nogc nothrow @trusted
+{
+ version (Windows)
+ {
+ // BUGS: Only works on Windows 2000 and above.
+ import core.sys.windows.winbase : SYSTEM_INFO, GetSystemInfo;
+ import std.algorithm.comparison : max;
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ return max(1, cast(uint) si.dwNumberOfProcessors);
+ }
+ else version (linux)
+ {
+ import core.sys.linux.sched : CPU_COUNT, cpu_set_t, sched_getaffinity;
+ import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;
+
+ cpu_set_t set = void;
+ if (sched_getaffinity(0, cpu_set_t.sizeof, &set) == 0)
+ {
+ int count = CPU_COUNT(&set);
+ if (count > 0)
+ return cast(uint) count;
+ }
+ return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
+ }
+ else version (Darwin)
+ {
+ import core.sys.darwin.sys.sysctl : sysctlbyname;
+ uint result;
+ size_t len = result.sizeof;
+ sysctlbyname("hw.physicalcpu", &result, &len, null, 0);
+ return result;
+ }
+ else version (DragonFlyBSD)
+ {
+ import core.sys.dragonflybsd.sys.sysctl : sysctlbyname;
+ uint result;
+ size_t len = result.sizeof;
+ sysctlbyname("hw.ncpu", &result, &len, null, 0);
+ return result;
+ }
+ else version (FreeBSD)
+ {
+ import core.sys.freebsd.sys.sysctl : sysctlbyname;
+ uint result;
+ size_t len = result.sizeof;
+ sysctlbyname("hw.ncpu", &result, &len, null, 0);
+ return result;
+ }
+ else version (NetBSD)
+ {
+ import core.sys.netbsd.sys.sysctl : sysctlbyname;
+ uint result;
+ size_t len = result.sizeof;
+ sysctlbyname("hw.ncpu", &result, &len, null, 0);
+ return result;
+ }
+ else version (Solaris)
+ {
+ import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;
+ return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
+ }
+ else version (OpenBSD)
+ {
+ import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;
+ return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);
+ }
+ else
+ {
+ static assert(0, "Don't know how to get N CPUs on this OS.");
+ }
+}
/*
This class serves two purposes:
@@ -3302,11 +3360,7 @@ terminating the main thread.
}());
}
-private shared uint _defaultPoolThreads;
-shared static this()
-{
- atomicStore(_defaultPoolThreads, totalCPUs - 1);
-}
+private shared uint _defaultPoolThreads = uint.max;
/**
These properties get and set the number of worker threads in the $(D TaskPool)
@@ -3316,7 +3370,8 @@ number of worker threads in the instance returned by $(D taskPool).
*/
@property uint defaultPoolThreads() @trusted
{
- return atomicLoad(_defaultPoolThreads);
+ const local = atomicLoad(_defaultPoolThreads);
+ return local < uint.max ? local : totalCPUs - 1;
}
/// Ditto
@@ -3945,7 +4000,7 @@ version (unittest)
import std.array : split;
import std.conv : text;
import std.exception : assertThrown;
- import std.math : approxEqual, sqrt, log;
+ import std.math : approxEqual, sqrt, log, abs;
import std.range : indexed, iota, join;
import std.typecons : Tuple, tuple;
@@ -4274,7 +4329,7 @@ version (unittest)
assert(equal(iota(1_000_000), bufTrickTest));
- auto myTask = task!(std.math.abs)(-1);
+ auto myTask = task!(abs)(-1);
taskPool.put(myTask);
assert(myTask.spinForce == 1);
diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d
index b0310a8..1e977aa 100644
--- a/libphobos/src/std/process.d
+++ b/libphobos/src/std/process.d
@@ -887,7 +887,7 @@ version (Windows) @system unittest
// Searches the PATH variable for the given executable file,
// (checking that it is in fact executable).
version (Posix)
-private string searchPathFor(in char[] executable)
+package(std) string searchPathFor(in char[] executable)
@trusted //TODO: @safe nothrow
{
import std.algorithm.iteration : splitter;
@@ -1358,7 +1358,8 @@ version (Windows)
/**
-Flags that control the behaviour of $(LREF spawnProcess) and
+Flags that control the behaviour of process creation functions in this
+module. Most flags only apply to $(LREF spawnProcess) and
$(LREF spawnShell).
Use bitwise OR to combine flags.
@@ -1433,6 +1434,21 @@ enum Config
Calling $(LREF wait) or $(LREF kill) with the resulting $(D Pid) is invalid.
*/
detached = 64,
+
+ /**
+ By default, the $(LREF execute) and $(LREF executeShell) functions
+ will capture child processes' both stdout and stderr. This can be
+ undesirable if the standard output is to be processed or otherwise
+ used by the invoking program, as `execute`'s result would then
+ contain a mix of output and warning/error messages.
+
+ Specify this flag when calling `execute` or `executeShell` to
+ cause invoked processes' stderr stream to be sent to $(REF stderr,
+ std,stdio), and only capture and return standard output.
+
+ This flag has no effect on $(LREF spawnProcess) or $(LREF spawnShell).
+ */
+ stderrPassThrough = 128,
}
@@ -2487,7 +2503,11 @@ private auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)(
import std.array : appender;
import std.typecons : Tuple;
- auto p = pipeFunc(commandLine, Redirect.stdout | Redirect.stderrToStdout,
+ auto redirect = (config & Config.stderrPassThrough)
+ ? Redirect.stdout
+ : Redirect.stdout | Redirect.stderrToStdout;
+
+ auto p = pipeFunc(commandLine, redirect,
env, config, workDir, extraArgs);
auto a = appender!(ubyte[])();
@@ -2551,6 +2571,31 @@ private auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)(
assert(r3.output.empty);
}
+@system unittest
+{
+ // Temporarily disable output to stderr so as to not spam the build log.
+ import std.stdio : stderr;
+ import std.typecons : Tuple;
+ import std.file : readText;
+ import std.traits : ReturnType;
+
+ ReturnType!executeShell r;
+ auto tmpname = uniqueTempPath;
+ scope(exit) if (exists(tmpname)) remove(tmpname);
+ auto t = stderr;
+ // Open a new scope to minimize code ran with stderr redirected.
+ {
+ stderr.open(tmpname, "w");
+ scope(exit) stderr = t;
+ r = executeShell("echo D rox>&2", null, Config.stderrPassThrough);
+ }
+ assert(r.status == 0);
+ assert(r.output.empty);
+ auto witness = readText(tmpname);
+ import std.ascii : newline;
+ assert(witness == "D rox" ~ newline, "'" ~ witness ~ "'");
+}
+
@safe unittest
{
import std.typecons : Tuple;
@@ -2750,8 +2795,7 @@ private struct TestScript
string path;
}
-version (unittest)
-private string uniqueTempPath() @safe
+package(std) string uniqueTempPath() @safe
{
import std.file : tempDir;
import std.path : buildPath;
diff --git a/libphobos/src/std/range/package.d b/libphobos/src/std/range/package.d
index 13601cb..deedb68 100644
--- a/libphobos/src/std/range/package.d
+++ b/libphobos/src/std/range/package.d
@@ -11379,7 +11379,6 @@ if (isInputRange!R && isIntegral!(ElementType!R))
bw.popFront();
assert(bw[2 * bitsNum - 3] == true);
- import core.exception : Error;
import std.exception : assertThrown;
// Check out of bounds error
diff --git a/libphobos/src/std/regex/internal/tests.d b/libphobos/src/std/regex/internal/tests.d
index 1c4f295..fe75ce0 100644
--- a/libphobos/src/std/regex/internal/tests.d
+++ b/libphobos/src/std/regex/internal/tests.d
@@ -8,7 +8,7 @@ package(std.regex):
import std.conv, std.exception, std.meta, std.range,
std.typecons, std.regex;
-import std.regex.internal.parser : Escapables; // characters that need escaping
+import std.regex.internal.ir : Escapables; // characters that need escaping
alias Sequence(int B, int E) = staticIota!(B, E);
@@ -467,654 +467,3 @@ alias Sequence(int B, int E) = staticIota!(B, E);
run_tests!match(); //thompson VM
}
-@safe unittest
-{
- auto cr = ctRegex!("abc");
- assert(bmatch("abc",cr).hit == "abc");
- auto cr2 = ctRegex!("ab*c");
- assert(bmatch("abbbbc",cr2).hit == "abbbbc");
-}
-@safe unittest
-{
- auto cr3 = ctRegex!("^abc$");
- assert(bmatch("abc",cr3).hit == "abc");
- auto cr4 = ctRegex!(`\b(a\B[a-z]b)\b`);
- assert(array(match("azb",cr4).captures) == ["azb", "azb"]);
-}
-
-@safe unittest
-{
- auto cr5 = ctRegex!("(?:a{2,4}b{1,3}){1,2}");
- assert(bmatch("aaabaaaabbb", cr5).hit == "aaabaaaabbb");
- auto cr6 = ctRegex!("(?:a{2,4}b{1,3}){1,2}?"w);
- assert(bmatch("aaabaaaabbb"w, cr6).hit == "aaab"w);
-}
-
-@safe unittest
-{
- auto cr7 = ctRegex!(`\r.*?$`,"sm");
- assert(bmatch("abc\r\nxy", cr7).hit == "\r\nxy");
- auto greed = ctRegex!("<packet.*?/packet>");
- assert(bmatch("<packet>text</packet><packet>text</packet>", greed).hit
- == "<packet>text</packet>");
-}
-
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- auto cr8 = ctRegex!("^(a)(b)?(c*)");
- auto m8 = bmatch("abcc",cr8);
- assert(m8);
- assert(m8.captures[1] == "a");
- assert(m8.captures[2] == "b");
- assert(m8.captures[3] == "cc");
- auto cr9 = ctRegex!("q(a|b)*q");
- auto m9 = match("xxqababqyy",cr9);
- assert(m9);
- assert(equal(bmatch("xxqababqyy",cr9).captures, ["qababq", "b"]));
-}
-
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- auto rtr = regex("a|b|c");
- enum ctr = regex("a|b|c");
- assert(equal(rtr.ir,ctr.ir));
- //CTFE parser BUG is triggered by group
- //in the middle of alternation (at least not first and not last)
- enum testCT = regex(`abc|(edf)|xyz`);
- auto testRT = regex(`abc|(edf)|xyz`);
- assert(equal(testCT.ir,testRT.ir));
-}
-
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- import std.algorithm.iteration : map;
- enum cx = ctRegex!"(A|B|C)";
- auto mx = match("B",cx);
- assert(mx);
- assert(equal(mx.captures, [ "B", "B"]));
- enum cx2 = ctRegex!"(A|B)*";
- assert(match("BAAA",cx2));
-
- enum cx3 = ctRegex!("a{3,4}","i");
- auto mx3 = match("AaA",cx3);
- assert(mx3);
- assert(mx3.captures[0] == "AaA");
- enum cx4 = ctRegex!(`^a{3,4}?[a-zA-Z0-9~]{1,2}`,"i");
- auto mx4 = match("aaaabc", cx4);
- assert(mx4);
- assert(mx4.captures[0] == "aaaab");
- auto cr8 = ctRegex!("(a)(b)?(c*)");
- auto m8 = bmatch("abcc",cr8);
- assert(m8);
- assert(m8.captures[1] == "a");
- assert(m8.captures[2] == "b");
- assert(m8.captures[3] == "cc");
- auto cr9 = ctRegex!(".*$", "gm");
- auto m9 = match("First\rSecond", cr9);
- assert(m9);
- assert(equal(map!"a.hit"(m9), ["First", "", "Second"]));
-}
-
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- import std.algorithm.iteration : map;
-//global matching
- void test_body(alias matchFn)()
- {
- string s = "a quick brown fox jumps over a lazy dog";
- auto r1 = regex("\\b[a-z]+\\b","g");
- string[] test;
- foreach (m; matchFn(s, r1))
- test ~= m.hit;
- assert(equal(test, [ "a", "quick", "brown", "fox", "jumps", "over", "a", "lazy", "dog"]));
- auto free_reg = regex(`
-
- abc
- \s+
- "
- (
- [^"]+
- | \\ "
- )+
- "
- z
- `, "x");
- auto m = match(`abc "quoted string with \" inside"z`,free_reg);
- assert(m);
- string mails = " hey@you.com no@spam.net ";
- auto rm = regex(`@(?<=\S+@)\S+`,"g");
- assert(equal(map!"a[0]"(matchFn(mails, rm)), ["@you.com", "@spam.net"]));
- auto m2 = matchFn("First line\nSecond line",regex(".*$","gm"));
- assert(equal(map!"a[0]"(m2), ["First line", "", "Second line"]));
- auto m2a = matchFn("First line\nSecond line",regex(".+$","gm"));
- assert(equal(map!"a[0]"(m2a), ["First line", "Second line"]));
- auto m2b = matchFn("First line\nSecond line",regex(".+?$","gm"));
- assert(equal(map!"a[0]"(m2b), ["First line", "Second line"]));
- debug(std_regex_test) writeln("!!! FReD FLAGS test done "~matchFn.stringof~" !!!");
- }
- test_body!bmatch();
- test_body!match();
-}
-
-//tests for accumulated std.regex issues and other regressions
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- import std.algorithm.iteration : map;
- void test_body(alias matchFn)()
- {
- //issue 5857
- //matching goes out of control if ... in (...){x} has .*/.+
- auto c = matchFn("axxxzayyyyyzd",regex("(a.*z){2}d")).captures;
- assert(c[0] == "axxxzayyyyyzd");
- assert(c[1] == "ayyyyyz");
- auto c2 = matchFn("axxxayyyyyd",regex("(a.*){2}d")).captures;
- assert(c2[0] == "axxxayyyyyd");
- assert(c2[1] == "ayyyyy");
- //issue 2108
- //greedy vs non-greedy
- auto nogreed = regex("<packet.*?/packet>");
- assert(matchFn("<packet>text</packet><packet>text</packet>", nogreed).hit
- == "<packet>text</packet>");
- auto greed = regex("<packet.*/packet>");
- assert(matchFn("<packet>text</packet><packet>text</packet>", greed).hit
- == "<packet>text</packet><packet>text</packet>");
- //issue 4574
- //empty successful match still advances the input
- string[] pres, posts, hits;
- foreach (m; matchFn("abcabc", regex("","g")))
- {
- pres ~= m.pre;
- posts ~= m.post;
- assert(m.hit.empty);
-
- }
- auto heads = [
- "abcabc",
- "abcab",
- "abca",
- "abc",
- "ab",
- "a",
- ""
- ];
- auto tails = [
- "abcabc",
- "bcabc",
- "cabc",
- "abc",
- "bc",
- "c",
- ""
- ];
- assert(pres == array(retro(heads)));
- assert(posts == tails);
- //issue 6076
- //regression on .*
- auto re = regex("c.*|d");
- auto m = matchFn("mm", re);
- assert(!m);
- debug(std_regex_test) writeln("!!! FReD REGRESSION test done "~matchFn.stringof~" !!!");
- auto rprealloc = regex(`((.){5}.{1,10}){5}`);
- auto arr = array(repeat('0',100));
- auto m2 = matchFn(arr, rprealloc);
- assert(m2);
- assert(collectException(
- regex(r"^(import|file|binary|config)\s+([^\(]+)\(?([^\)]*)\)?\s*$")
- ) is null);
- foreach (ch; [Escapables])
- {
- assert(match(to!string(ch),regex(`[\`~ch~`]`)));
- assert(!match(to!string(ch),regex(`[^\`~ch~`]`)));
- assert(match(to!string(ch),regex(`[\`~ch~`-\`~ch~`]`)));
- }
- //bugzilla 7718
- string strcmd = "./myApp.rb -os OSX -path \"/GIT/Ruby Apps/sec\" -conf 'notimer'";
- auto reStrCmd = regex (`(".*")|('.*')`, "g");
- assert(equal(map!"a[0]"(matchFn(strcmd, reStrCmd)),
- [`"/GIT/Ruby Apps/sec"`, `'notimer'`]));
- }
- test_body!bmatch();
- test_body!match();
-}
-
-// tests for replace
-@safe unittest
-{
- void test(alias matchFn)()
- {
- import std.uni : toUpper;
-
- foreach (i, v; AliasSeq!(string, wstring, dstring))
- {
- auto baz(Cap)(Cap m)
- if (is(Cap == Captures!(Cap.String)))
- {
- return toUpper(m.hit);
- }
- alias String = v;
- assert(std.regex.replace!(matchFn)(to!String("ark rapacity"), regex(to!String("r")), to!String("c"))
- == to!String("ack rapacity"));
- assert(std.regex.replace!(matchFn)(to!String("ark rapacity"), regex(to!String("r"), "g"), to!String("c"))
- == to!String("ack capacity"));
- assert(std.regex.replace!(matchFn)(to!String("noon"), regex(to!String("^n")), to!String("[$&]"))
- == to!String("[n]oon"));
- assert(std.regex.replace!(matchFn)(
- to!String("test1 test2"), regex(to!String(`\w+`),"g"), to!String("$`:$'")
- ) == to!String(": test2 test1 :"));
- auto s = std.regex.replace!(baz!(Captures!(String)))(to!String("Strap a rocket engine on a chicken."),
- regex(to!String("[ar]"), "g"));
- assert(s == "StRAp A Rocket engine on A chicken.");
- }
- debug(std_regex_test) writeln("!!! Replace test done "~matchFn.stringof~" !!!");
- }
- test!(bmatch)();
- test!(match)();
-}
-
-// tests for splitter
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- auto s1 = ", abc, de, fg, hi, ";
- auto sp1 = splitter(s1, regex(", *"));
- auto w1 = ["", "abc", "de", "fg", "hi", ""];
- assert(equal(sp1, w1));
-
- auto s2 = ", abc, de, fg, hi";
- auto sp2 = splitter(s2, regex(", *"));
- auto w2 = ["", "abc", "de", "fg", "hi"];
-
- uint cnt;
- foreach (e; sp2)
- {
- assert(w2[cnt++] == e);
- }
- assert(equal(sp2, w2));
-}
-
-@safe unittest
-{
- char[] s1 = ", abc, de, fg, hi, ".dup;
- auto sp2 = splitter(s1, regex(", *"));
-}
-
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- auto s1 = ", abc, de, fg, hi, ";
- auto w1 = ["", "abc", "de", "fg", "hi", ""];
- assert(equal(split(s1, regex(", *")), w1[]));
-}
-
-@safe unittest
-{ // bugzilla 7141
- string pattern = `[a\--b]`;
- assert(match("-", pattern));
- assert(match("b", pattern));
- string pattern2 = `[&-z]`;
- assert(match("b", pattern2));
-}
-@safe unittest
-{//bugzilla 7111
- assert(match("", regex("^")));
-}
-@safe unittest
-{//bugzilla 7300
- assert(!match("a"d, "aa"d));
-}
-
-// bugzilla 7551
-@safe unittest
-{
- auto r = regex("[]abc]*");
- assert("]ab".matchFirst(r).hit == "]ab");
- assertThrown(regex("[]"));
- auto r2 = regex("[]abc--ab]*");
- assert("]ac".matchFirst(r2).hit == "]");
-}
-
-@safe unittest
-{//bugzilla 7674
- assert("1234".replace(regex("^"), "$$") == "$1234");
- assert("hello?".replace(regex(r"\?", "g"), r"\?") == r"hello\?");
- assert("hello?".replace(regex(r"\?", "g"), r"\\?") != r"hello\?");
-}
-@safe unittest
-{// bugzilla 7679
- import std.algorithm.comparison : equal;
- foreach (S; AliasSeq!(string, wstring, dstring))
- (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
- enum re = ctRegex!(to!S(r"\."));
- auto str = to!S("a.b");
- assert(equal(std.regex.splitter(str, re), [to!S("a"), to!S("b")]));
- assert(split(str, re) == [to!S("a"), to!S("b")]);
- }();
-}
-@safe unittest
-{//bugzilla 8203
- string data = "
- NAME = XPAW01_STA:STATION
- NAME = XPAW01_STA
- ";
- auto uniFileOld = data;
- auto r = regex(
- r"^NAME = (?P<comp>[a-zA-Z0-9_]+):*(?P<blk>[a-zA-Z0-9_]*)","gm");
- auto uniCapturesNew = match(uniFileOld, r);
- for (int i = 0; i < 20; i++)
- foreach (matchNew; uniCapturesNew) {}
- //a second issue with same symptoms
- auto r2 = regex(`([а-яА-Я\-_]+\s*)+(?<=[\s\.,\^])`);
- match("аллея Театральная", r2);
-}
-@safe unittest
-{// bugzilla 8637 purity of enforce
- auto m = match("hello world", regex("world"));
- enforce(m);
-}
-
-// bugzilla 8725
-@safe unittest
-{
- static italic = regex( r"\*
- (?!\s+)
- (.*?)
- (?!\s+)
- \*", "gx" );
- string input = "this * is* interesting, *very* interesting";
- assert(replace(input, italic, "<i>$1</i>") ==
- "this * is* interesting, <i>very</i> interesting");
-}
-
-// bugzilla 8349
-@safe unittest
-{
- enum peakRegexStr = r"\>(wgEncode.*Tfbs.*\.(?:narrow)|(?:broad)Peak.gz)</a>";
- enum peakRegex = ctRegex!(peakRegexStr);
- //note that the regex pattern itself is probably bogus
- assert(match(r"\>wgEncode-blah-Tfbs.narrow</a>", peakRegex));
-}
-
-// bugzilla 9211
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- auto rx_1 = regex(r"^(\w)*(\d)");
- auto m = match("1234", rx_1);
- assert(equal(m.front, ["1234", "3", "4"]));
- auto rx_2 = regex(r"^([0-9])*(\d)");
- auto m2 = match("1234", rx_2);
- assert(equal(m2.front, ["1234", "3", "4"]));
-}
-
-// bugzilla 9280
-@safe unittest
-{
- string tomatch = "a!b@c";
- static r = regex(r"^(?P<nick>.*?)!(?P<ident>.*?)@(?P<host>.*?)$");
- auto nm = match(tomatch, r);
- assert(nm);
- auto c = nm.captures;
- assert(c[1] == "a");
- assert(c["nick"] == "a");
-}
-
-
-// bugzilla 9579
-@safe unittest
-{
- char[] input = ['a', 'b', 'c'];
- string format = "($1)";
- // used to give a compile error:
- auto re = regex(`(a)`, "g");
- auto r = replace(input, re, format);
- assert(r == "(a)bc");
-}
-
-// bugzilla 9634
-@safe unittest
-{
- auto re = ctRegex!"(?:a+)";
- assert(match("aaaa", re).hit == "aaaa");
-}
-
-//bugzilla 10798
-@safe unittest
-{
- auto cr = ctRegex!("[abcd--c]*");
- auto m = "abc".match(cr);
- assert(m);
- assert(m.hit == "ab");
-}
-
-// bugzilla 10913
-@system unittest
-{
- @system static string foo(const(char)[] s)
- {
- return s.dup;
- }
- @safe static string bar(const(char)[] s)
- {
- return s.dup;
- }
- () @system {
- replace!((a) => foo(a.hit))("blah", regex(`a`));
- }();
- () @safe {
- replace!((a) => bar(a.hit))("blah", regex(`a`));
- }();
-}
-
-// bugzilla 11262
-@safe unittest
-{
- enum reg = ctRegex!(r",", "g");
- auto str = "This,List";
- str = str.replace(reg, "-");
- assert(str == "This-List");
-}
-
-// bugzilla 11775
-@safe unittest
-{
- assert(collectException(regex("a{1,0}")));
-}
-
-// bugzilla 11839
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- assert(regex(`(?P<var1>\w+)`).namedCaptures.equal(["var1"]));
- assert(collectException(regex(`(?P<1>\w+)`)));
- assert(regex(`(?P<v1>\w+)`).namedCaptures.equal(["v1"]));
- assert(regex(`(?P<__>\w+)`).namedCaptures.equal(["__"]));
- assert(regex(`(?P<я>\w+)`).namedCaptures.equal(["я"]));
-}
-
-// bugzilla 12076
-@safe unittest
-{
- auto RE = ctRegex!(r"(?<!x[a-z]+)\s([a-z]+)");
- string s = "one two";
- auto m = match(s, RE);
-}
-
-// bugzilla 12105
-@safe unittest
-{
- auto r = ctRegex!`.*?(?!a)`;
- assert("aaab".matchFirst(r).hit == "aaa");
- auto r2 = ctRegex!`.*(?!a)`;
- assert("aaab".matchFirst(r2).hit == "aaab");
-}
-
-//bugzilla 11784
-@safe unittest
-{
- assert("abcdefghijklmnopqrstuvwxyz"
- .matchFirst("[a-z&&[^aeiuo]]").hit == "b");
-}
-
-//bugzilla 12366
-@safe unittest
-{
- auto re = ctRegex!(`^((?=(xx+?)\2+$)((?=\2+$)(?=(x+)(\4+$))\5){2})*x?$`);
- assert("xxxxxxxx".match(re).empty);
- assert(!"xxxx".match(re).empty);
-}
-
-// bugzilla 12582
-@safe unittest
-{
- auto r = regex(`(?P<a>abc)`);
- assert(collectException("abc".matchFirst(r)["b"]));
-}
-
-// bugzilla 12691
-@safe unittest
-{
- assert(bmatch("e@", "^([a-z]|)*$").empty);
- assert(bmatch("e@", ctRegex!`^([a-z]|)*$`).empty);
-}
-
-//bugzilla 12713
-@safe unittest
-{
- assertThrown(regex("[[a-z]([a-z]|(([[a-z])))"));
-}
-
-//bugzilla 12747
-@safe unittest
-{
- assertThrown(regex(`^x(\1)`));
- assertThrown(regex(`^(x(\1))`));
- assertThrown(regex(`^((x)(?=\1))`));
-}
-
-// bugzilla 14504
-@safe unittest
-{
- auto p = ctRegex!("a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?" ~
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
-}
-
-// bugzilla 14529
-@safe unittest
-{
- auto ctPat2 = regex(r"^[CDF]$", "i");
- foreach (v; ["C", "c", "D", "d", "F", "f"])
- assert(matchAll(v, ctPat2).front.hit == v);
-}
-
-// bugzilla 14615
-@safe unittest
-{
- import std.array : appender;
- import std.regex : replaceFirst, replaceFirstInto, regex;
- import std.stdio : writeln;
-
- auto example = "Hello, world!";
- auto pattern = regex("^Hello, (bug)"); // won't find this one
- auto result = replaceFirst(example, pattern, "$1 Sponge Bob");
- assert(result == "Hello, world!"); // Ok.
-
- auto sink = appender!string;
- replaceFirstInto(sink, example, pattern, "$1 Sponge Bob");
- assert(sink.data == "Hello, world!");
- replaceAllInto(sink, example, pattern, "$1 Sponge Bob");
- assert(sink.data == "Hello, world!Hello, world!");
-}
-
-// bugzilla 15573
-@safe unittest
-{
- auto rx = regex("[c d]", "x");
- assert("a b".matchFirst(rx));
-}
-
-// bugzilla 15864
-@safe unittest
-{
- regex(`(<a (?:(?:\w+=\"[^"]*\")?\s*)*href="\.\.?)"`);
-}
-
-@safe unittest
-{
- auto r = regex("(?# comment)abc(?# comment2)");
- assert("abc".matchFirst(r));
- assertThrown(regex("(?#..."));
-}
-
-// bugzilla 17075
-@safe unittest
-{
- enum titlePattern = `<title>(.+)</title>`;
- static titleRegex = ctRegex!titlePattern;
- string input = "<title>" ~ "<".repeat(100_000).join;
- assert(input.matchFirst(titleRegex).empty);
-}
-
-// bugzilla 17212
-@safe unittest
-{
- auto r = regex(" [a] ", "x");
- assert("a".matchFirst(r));
-}
-
-// bugzilla 17157
-@safe unittest
-{
- import std.algorithm.comparison : equal;
- auto ctr = ctRegex!"(a)|(b)|(c)|(d)";
- auto r = regex("(a)|(b)|(c)|(d)", "g");
- auto s = "--a--b--c--d--";
- auto outcomes = [
- ["a", "a", "", "", ""],
- ["b", "", "b", "", ""],
- ["c", "", "", "c", ""],
- ["d", "", "", "", "d"]
- ];
- assert(equal!equal(s.matchAll(ctr), outcomes));
- assert(equal!equal(s.bmatch(r), outcomes));
-}
-
-// bugzilla 17667
-@safe unittest
-{
- import std.algorithm.searching : canFind;
- void willThrow(T, size_t line = __LINE__)(T arg, string msg)
- {
- auto e = collectException(regex(arg));
- assert(e.msg.canFind(msg), to!string(line) ~ ": " ~ e.msg);
- }
- willThrow([r".", r"[\(\{[\]\}\)]"], "no matching ']' found while parsing character class");
- willThrow([r"[\", r"123"], "no matching ']' found while parsing character class");
- willThrow([r"[a-", r"123"], "no matching ']' found while parsing character class");
- willThrow([r"[a-\", r"123"], "invalid escape sequence");
- willThrow([r"\", r"123"], "invalid escape sequence");
-}
-
-// bugzilla 17668
-@safe unittest
-{
- import std.algorithm.searching;
- auto e = collectException!RegexException(regex(q"<[^]>"));
- assert(e.msg.canFind("no operand for '^'"));
-}
-
-// bugzilla 17673
-@safe unittest
-{
- string str = `<">`;
- string[] regexps = ["abc", "\"|x"];
- auto regexp = regex(regexps);
- auto c = matchFirst(str, regexp);
- assert(c);
- assert(c.whichPattern == 2);
-}
-
diff --git a/libphobos/src/std/regex/internal/tests2.d b/libphobos/src/std/regex/internal/tests2.d
new file mode 100644
index 0000000..420f8d3
--- /dev/null
+++ b/libphobos/src/std/regex/internal/tests2.d
@@ -0,0 +1,662 @@
+// Split-up due to DMD's enormous memory consumption
+
+module std.regex.internal.tests2;
+
+package(std.regex):
+
+import std.conv, std.exception, std.meta, std.range,
+ std.typecons, std.regex;
+
+import std.regex.internal.ir : Escapables; // characters that need escaping
+
+@safe unittest
+{
+ auto cr = ctRegex!("abc");
+ assert(bmatch("abc",cr).hit == "abc");
+ auto cr2 = ctRegex!("ab*c");
+ assert(bmatch("abbbbc",cr2).hit == "abbbbc");
+}
+@safe unittest
+{
+ auto cr3 = ctRegex!("^abc$");
+ assert(bmatch("abc",cr3).hit == "abc");
+ auto cr4 = ctRegex!(`\b(a\B[a-z]b)\b`);
+ assert(array(match("azb",cr4).captures) == ["azb", "azb"]);
+}
+
+@safe unittest
+{
+ auto cr5 = ctRegex!("(?:a{2,4}b{1,3}){1,2}");
+ assert(bmatch("aaabaaaabbb", cr5).hit == "aaabaaaabbb");
+ auto cr6 = ctRegex!("(?:a{2,4}b{1,3}){1,2}?"w);
+ assert(bmatch("aaabaaaabbb"w, cr6).hit == "aaab"w);
+}
+
+@safe unittest
+{
+ auto cr7 = ctRegex!(`\r.*?$`,"sm");
+ assert(bmatch("abc\r\nxy", cr7).hit == "\r\nxy");
+ auto greed = ctRegex!("<packet.*?/packet>");
+ assert(bmatch("<packet>text</packet><packet>text</packet>", greed).hit
+ == "<packet>text</packet>");
+}
+
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ auto cr8 = ctRegex!("^(a)(b)?(c*)");
+ auto m8 = bmatch("abcc",cr8);
+ assert(m8);
+ assert(m8.captures[1] == "a");
+ assert(m8.captures[2] == "b");
+ assert(m8.captures[3] == "cc");
+ auto cr9 = ctRegex!("q(a|b)*q");
+ auto m9 = match("xxqababqyy",cr9);
+ assert(m9);
+ assert(equal(bmatch("xxqababqyy",cr9).captures, ["qababq", "b"]));
+}
+
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ auto rtr = regex("a|b|c");
+ enum ctr = regex("a|b|c");
+ assert(equal(rtr.ir,ctr.ir));
+ //CTFE parser BUG is triggered by group
+ //in the middle of alternation (at least not first and not last)
+ enum testCT = regex(`abc|(edf)|xyz`);
+ auto testRT = regex(`abc|(edf)|xyz`);
+ assert(equal(testCT.ir,testRT.ir));
+}
+
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ import std.algorithm.iteration : map;
+ enum cx = ctRegex!"(A|B|C)";
+ auto mx = match("B",cx);
+ assert(mx);
+ assert(equal(mx.captures, [ "B", "B"]));
+ enum cx2 = ctRegex!"(A|B)*";
+ assert(match("BAAA",cx2));
+
+ enum cx3 = ctRegex!("a{3,4}","i");
+ auto mx3 = match("AaA",cx3);
+ assert(mx3);
+ assert(mx3.captures[0] == "AaA");
+ enum cx4 = ctRegex!(`^a{3,4}?[a-zA-Z0-9~]{1,2}`,"i");
+ auto mx4 = match("aaaabc", cx4);
+ assert(mx4);
+ assert(mx4.captures[0] == "aaaab");
+ auto cr8 = ctRegex!("(a)(b)?(c*)");
+ auto m8 = bmatch("abcc",cr8);
+ assert(m8);
+ assert(m8.captures[1] == "a");
+ assert(m8.captures[2] == "b");
+ assert(m8.captures[3] == "cc");
+ auto cr9 = ctRegex!(".*$", "gm");
+ auto m9 = match("First\rSecond", cr9);
+ assert(m9);
+ assert(equal(map!"a.hit"(m9), ["First", "", "Second"]));
+}
+
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ import std.algorithm.iteration : map;
+//global matching
+ void test_body(alias matchFn)()
+ {
+ string s = "a quick brown fox jumps over a lazy dog";
+ auto r1 = regex("\\b[a-z]+\\b","g");
+ string[] test;
+ foreach (m; matchFn(s, r1))
+ test ~= m.hit;
+ assert(equal(test, [ "a", "quick", "brown", "fox", "jumps", "over", "a", "lazy", "dog"]));
+ auto free_reg = regex(`
+
+ abc
+ \s+
+ "
+ (
+ [^"]+
+ | \\ "
+ )+
+ "
+ z
+ `, "x");
+ auto m = match(`abc "quoted string with \" inside"z`,free_reg);
+ assert(m);
+ string mails = " hey@you.com no@spam.net ";
+ auto rm = regex(`@(?<=\S+@)\S+`,"g");
+ assert(equal(map!"a[0]"(matchFn(mails, rm)), ["@you.com", "@spam.net"]));
+ auto m2 = matchFn("First line\nSecond line",regex(".*$","gm"));
+ assert(equal(map!"a[0]"(m2), ["First line", "", "Second line"]));
+ auto m2a = matchFn("First line\nSecond line",regex(".+$","gm"));
+ assert(equal(map!"a[0]"(m2a), ["First line", "Second line"]));
+ auto m2b = matchFn("First line\nSecond line",regex(".+?$","gm"));
+ assert(equal(map!"a[0]"(m2b), ["First line", "Second line"]));
+ debug(std_regex_test) writeln("!!! FReD FLAGS test done "~matchFn.stringof~" !!!");
+ }
+ test_body!bmatch();
+ test_body!match();
+}
+
+//tests for accumulated std.regex issues and other regressions
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ import std.algorithm.iteration : map;
+ void test_body(alias matchFn)()
+ {
+ //issue 5857
+ //matching goes out of control if ... in (...){x} has .*/.+
+ auto c = matchFn("axxxzayyyyyzd",regex("(a.*z){2}d")).captures;
+ assert(c[0] == "axxxzayyyyyzd");
+ assert(c[1] == "ayyyyyz");
+ auto c2 = matchFn("axxxayyyyyd",regex("(a.*){2}d")).captures;
+ assert(c2[0] == "axxxayyyyyd");
+ assert(c2[1] == "ayyyyy");
+ //issue 2108
+ //greedy vs non-greedy
+ auto nogreed = regex("<packet.*?/packet>");
+ assert(matchFn("<packet>text</packet><packet>text</packet>", nogreed).hit
+ == "<packet>text</packet>");
+ auto greed = regex("<packet.*/packet>");
+ assert(matchFn("<packet>text</packet><packet>text</packet>", greed).hit
+ == "<packet>text</packet><packet>text</packet>");
+ //issue 4574
+ //empty successful match still advances the input
+ string[] pres, posts, hits;
+ foreach (m; matchFn("abcabc", regex("","g")))
+ {
+ pres ~= m.pre;
+ posts ~= m.post;
+ assert(m.hit.empty);
+
+ }
+ auto heads = [
+ "abcabc",
+ "abcab",
+ "abca",
+ "abc",
+ "ab",
+ "a",
+ ""
+ ];
+ auto tails = [
+ "abcabc",
+ "bcabc",
+ "cabc",
+ "abc",
+ "bc",
+ "c",
+ ""
+ ];
+ assert(pres == array(retro(heads)));
+ assert(posts == tails);
+ //issue 6076
+ //regression on .*
+ auto re = regex("c.*|d");
+ auto m = matchFn("mm", re);
+ assert(!m);
+ debug(std_regex_test) writeln("!!! FReD REGRESSION test done "~matchFn.stringof~" !!!");
+ auto rprealloc = regex(`((.){5}.{1,10}){5}`);
+ auto arr = array(repeat('0',100));
+ auto m2 = matchFn(arr, rprealloc);
+ assert(m2);
+ assert(collectException(
+ regex(r"^(import|file|binary|config)\s+([^\(]+)\(?([^\)]*)\)?\s*$")
+ ) is null);
+ foreach (ch; [Escapables])
+ {
+ assert(match(to!string(ch),regex(`[\`~ch~`]`)));
+ assert(!match(to!string(ch),regex(`[^\`~ch~`]`)));
+ assert(match(to!string(ch),regex(`[\`~ch~`-\`~ch~`]`)));
+ }
+ //bugzilla 7718
+ string strcmd = "./myApp.rb -os OSX -path \"/GIT/Ruby Apps/sec\" -conf 'notimer'";
+ auto reStrCmd = regex (`(".*")|('.*')`, "g");
+ assert(equal(map!"a[0]"(matchFn(strcmd, reStrCmd)),
+ [`"/GIT/Ruby Apps/sec"`, `'notimer'`]));
+ }
+ test_body!bmatch();
+ test_body!match();
+}
+
+// tests for replace
+@safe unittest
+{
+ void test(alias matchFn)()
+ {
+ import std.uni : toUpper;
+
+ foreach (i, v; AliasSeq!(string, wstring, dstring))
+ {
+ auto baz(Cap)(Cap m)
+ if (is(Cap == Captures!(Cap.String)))
+ {
+ return toUpper(m.hit);
+ }
+ alias String = v;
+ assert(std.regex.replace!(matchFn)(to!String("ark rapacity"), regex(to!String("r")), to!String("c"))
+ == to!String("ack rapacity"));
+ assert(std.regex.replace!(matchFn)(to!String("ark rapacity"), regex(to!String("r"), "g"), to!String("c"))
+ == to!String("ack capacity"));
+ assert(std.regex.replace!(matchFn)(to!String("noon"), regex(to!String("^n")), to!String("[$&]"))
+ == to!String("[n]oon"));
+ assert(std.regex.replace!(matchFn)(
+ to!String("test1 test2"), regex(to!String(`\w+`),"g"), to!String("$`:$'")
+ ) == to!String(": test2 test1 :"));
+ auto s = std.regex.replace!(baz!(Captures!(String)))(to!String("Strap a rocket engine on a chicken."),
+ regex(to!String("[ar]"), "g"));
+ assert(s == "StRAp A Rocket engine on A chicken.");
+ }
+ debug(std_regex_test) writeln("!!! Replace test done "~matchFn.stringof~" !!!");
+ }
+ test!(bmatch)();
+ test!(match)();
+}
+
+// tests for splitter
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ auto s1 = ", abc, de, fg, hi, ";
+ auto sp1 = splitter(s1, regex(", *"));
+ auto w1 = ["", "abc", "de", "fg", "hi", ""];
+ assert(equal(sp1, w1));
+
+ auto s2 = ", abc, de, fg, hi";
+ auto sp2 = splitter(s2, regex(", *"));
+ auto w2 = ["", "abc", "de", "fg", "hi"];
+
+ uint cnt;
+ foreach (e; sp2)
+ {
+ assert(w2[cnt++] == e);
+ }
+ assert(equal(sp2, w2));
+}
+
+@safe unittest
+{
+ char[] s1 = ", abc, de, fg, hi, ".dup;
+ auto sp2 = splitter(s1, regex(", *"));
+}
+
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ auto s1 = ", abc, de, fg, hi, ";
+ auto w1 = ["", "abc", "de", "fg", "hi", ""];
+ assert(equal(split(s1, regex(", *")), w1[]));
+}
+
+@safe unittest
+{ // bugzilla 7141
+ string pattern = `[a\--b]`;
+ assert(match("-", pattern));
+ assert(match("b", pattern));
+ string pattern2 = `[&-z]`;
+ assert(match("b", pattern2));
+}
+@safe unittest
+{//bugzilla 7111
+ assert(match("", regex("^")));
+}
+@safe unittest
+{//bugzilla 7300
+ assert(!match("a"d, "aa"d));
+}
+
+// bugzilla 7551
+@safe unittest
+{
+ auto r = regex("[]abc]*");
+ assert("]ab".matchFirst(r).hit == "]ab");
+ assertThrown(regex("[]"));
+ auto r2 = regex("[]abc--ab]*");
+ assert("]ac".matchFirst(r2).hit == "]");
+}
+
+@safe unittest
+{//bugzilla 7674
+ assert("1234".replace(regex("^"), "$$") == "$1234");
+ assert("hello?".replace(regex(r"\?", "g"), r"\?") == r"hello\?");
+ assert("hello?".replace(regex(r"\?", "g"), r"\\?") != r"hello\?");
+}
+@safe unittest
+{// bugzilla 7679
+ import std.algorithm.comparison : equal;
+ foreach (S; AliasSeq!(string, wstring, dstring))
+ (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
+ enum re = ctRegex!(to!S(r"\."));
+ auto str = to!S("a.b");
+ assert(equal(std.regex.splitter(str, re), [to!S("a"), to!S("b")]));
+ assert(split(str, re) == [to!S("a"), to!S("b")]);
+ }();
+}
+@safe unittest
+{//bugzilla 8203
+ string data = "
+ NAME = XPAW01_STA:STATION
+ NAME = XPAW01_STA
+ ";
+ auto uniFileOld = data;
+ auto r = regex(
+ r"^NAME = (?P<comp>[a-zA-Z0-9_]+):*(?P<blk>[a-zA-Z0-9_]*)","gm");
+ auto uniCapturesNew = match(uniFileOld, r);
+ for (int i = 0; i < 20; i++)
+ foreach (matchNew; uniCapturesNew) {}
+ //a second issue with same symptoms
+ auto r2 = regex(`([а-яА-Я\-_]+\s*)+(?<=[\s\.,\^])`);
+ match("аллея Театральная", r2);
+}
+@safe unittest
+{// bugzilla 8637 purity of enforce
+ auto m = match("hello world", regex("world"));
+ enforce(m);
+}
+
+// bugzilla 8725
+@safe unittest
+{
+ static italic = regex( r"\*
+ (?!\s+)
+ (.*?)
+ (?!\s+)
+ \*", "gx" );
+ string input = "this * is* interesting, *very* interesting";
+ assert(replace(input, italic, "<i>$1</i>") ==
+ "this * is* interesting, <i>very</i> interesting");
+}
+
+// bugzilla 8349
+@safe unittest
+{
+ enum peakRegexStr = r"\>(wgEncode.*Tfbs.*\.(?:narrow)|(?:broad)Peak.gz)</a>";
+ enum peakRegex = ctRegex!(peakRegexStr);
+ //note that the regex pattern itself is probably bogus
+ assert(match(r"\>wgEncode-blah-Tfbs.narrow</a>", peakRegex));
+}
+
+// bugzilla 9211
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ auto rx_1 = regex(r"^(\w)*(\d)");
+ auto m = match("1234", rx_1);
+ assert(equal(m.front, ["1234", "3", "4"]));
+ auto rx_2 = regex(r"^([0-9])*(\d)");
+ auto m2 = match("1234", rx_2);
+ assert(equal(m2.front, ["1234", "3", "4"]));
+}
+
+// bugzilla 9280
+@safe unittest
+{
+ string tomatch = "a!b@c";
+ static r = regex(r"^(?P<nick>.*?)!(?P<ident>.*?)@(?P<host>.*?)$");
+ auto nm = match(tomatch, r);
+ assert(nm);
+ auto c = nm.captures;
+ assert(c[1] == "a");
+ assert(c["nick"] == "a");
+}
+
+
+// bugzilla 9579
+@safe unittest
+{
+ char[] input = ['a', 'b', 'c'];
+ string format = "($1)";
+ // used to give a compile error:
+ auto re = regex(`(a)`, "g");
+ auto r = replace(input, re, format);
+ assert(r == "(a)bc");
+}
+
+// bugzilla 9634
+@safe unittest
+{
+ auto re = ctRegex!"(?:a+)";
+ assert(match("aaaa", re).hit == "aaaa");
+}
+
+//bugzilla 10798
+@safe unittest
+{
+ auto cr = ctRegex!("[abcd--c]*");
+ auto m = "abc".match(cr);
+ assert(m);
+ assert(m.hit == "ab");
+}
+
+// bugzilla 10913
+@system unittest
+{
+ @system static string foo(const(char)[] s)
+ {
+ return s.dup;
+ }
+ @safe static string bar(const(char)[] s)
+ {
+ return s.dup;
+ }
+ () @system {
+ replace!((a) => foo(a.hit))("blah", regex(`a`));
+ }();
+ () @safe {
+ replace!((a) => bar(a.hit))("blah", regex(`a`));
+ }();
+}
+
+// bugzilla 11262
+@safe unittest
+{
+ enum reg = ctRegex!(r",", "g");
+ auto str = "This,List";
+ str = str.replace(reg, "-");
+ assert(str == "This-List");
+}
+
+// bugzilla 11775
+@safe unittest
+{
+ assert(collectException(regex("a{1,0}")));
+}
+
+// bugzilla 11839
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ assert(regex(`(?P<var1>\w+)`).namedCaptures.equal(["var1"]));
+ assert(collectException(regex(`(?P<1>\w+)`)));
+ assert(regex(`(?P<v1>\w+)`).namedCaptures.equal(["v1"]));
+ assert(regex(`(?P<__>\w+)`).namedCaptures.equal(["__"]));
+ assert(regex(`(?P<я>\w+)`).namedCaptures.equal(["я"]));
+}
+
+// bugzilla 12076
+@safe unittest
+{
+ auto RE = ctRegex!(r"(?<!x[a-z]+)\s([a-z]+)");
+ string s = "one two";
+ auto m = match(s, RE);
+}
+
+// bugzilla 12105
+@safe unittest
+{
+ auto r = ctRegex!`.*?(?!a)`;
+ assert("aaab".matchFirst(r).hit == "aaa");
+ auto r2 = ctRegex!`.*(?!a)`;
+ assert("aaab".matchFirst(r2).hit == "aaab");
+}
+
+//bugzilla 11784
+@safe unittest
+{
+ assert("abcdefghijklmnopqrstuvwxyz"
+ .matchFirst("[a-z&&[^aeiuo]]").hit == "b");
+}
+
+//bugzilla 12366
+@safe unittest
+{
+ auto re = ctRegex!(`^((?=(xx+?)\2+$)((?=\2+$)(?=(x+)(\4+$))\5){2})*x?$`);
+ assert("xxxxxxxx".match(re).empty);
+ assert(!"xxxx".match(re).empty);
+}
+
+// bugzilla 12582
+@safe unittest
+{
+ auto r = regex(`(?P<a>abc)`);
+ assert(collectException("abc".matchFirst(r)["b"]));
+}
+
+// bugzilla 12691
+@safe unittest
+{
+ assert(bmatch("e@", "^([a-z]|)*$").empty);
+ assert(bmatch("e@", ctRegex!`^([a-z]|)*$`).empty);
+}
+
+//bugzilla 12713
+@safe unittest
+{
+ assertThrown(regex("[[a-z]([a-z]|(([[a-z])))"));
+}
+
+//bugzilla 12747
+@safe unittest
+{
+ assertThrown(regex(`^x(\1)`));
+ assertThrown(regex(`^(x(\1))`));
+ assertThrown(regex(`^((x)(?=\1))`));
+}
+
+// bugzilla 14504
+@safe unittest
+{
+ auto p = ctRegex!("a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?" ~
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+}
+
+// bugzilla 14529
+@safe unittest
+{
+ auto ctPat2 = regex(r"^[CDF]$", "i");
+ foreach (v; ["C", "c", "D", "d", "F", "f"])
+ assert(matchAll(v, ctPat2).front.hit == v);
+}
+
+// bugzilla 14615
+@safe unittest
+{
+ import std.array : appender;
+ import std.regex : replaceFirst, replaceFirstInto, regex;
+ import std.stdio : writeln;
+
+ auto example = "Hello, world!";
+ auto pattern = regex("^Hello, (bug)"); // won't find this one
+ auto result = replaceFirst(example, pattern, "$1 Sponge Bob");
+ assert(result == "Hello, world!"); // Ok.
+
+ auto sink = appender!string;
+ replaceFirstInto(sink, example, pattern, "$1 Sponge Bob");
+ assert(sink.data == "Hello, world!");
+ replaceAllInto(sink, example, pattern, "$1 Sponge Bob");
+ assert(sink.data == "Hello, world!Hello, world!");
+}
+
+// bugzilla 15573
+@safe unittest
+{
+ auto rx = regex("[c d]", "x");
+ assert("a b".matchFirst(rx));
+}
+
+// bugzilla 15864
+@safe unittest
+{
+ regex(`(<a (?:(?:\w+=\"[^"]*\")?\s*)*href="\.\.?)"`);
+}
+
+@safe unittest
+{
+ auto r = regex("(?# comment)abc(?# comment2)");
+ assert("abc".matchFirst(r));
+ assertThrown(regex("(?#..."));
+}
+
+// bugzilla 17075
+@safe unittest
+{
+ enum titlePattern = `<title>(.+)</title>`;
+ static titleRegex = ctRegex!titlePattern;
+ string input = "<title>" ~ "<".repeat(100_000).join;
+ assert(input.matchFirst(titleRegex).empty);
+}
+
+// bugzilla 17212
+@safe unittest
+{
+ auto r = regex(" [a] ", "x");
+ assert("a".matchFirst(r));
+}
+
+// bugzilla 17157
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ auto ctr = ctRegex!"(a)|(b)|(c)|(d)";
+ auto r = regex("(a)|(b)|(c)|(d)", "g");
+ auto s = "--a--b--c--d--";
+ auto outcomes = [
+ ["a", "a", "", "", ""],
+ ["b", "", "b", "", ""],
+ ["c", "", "", "c", ""],
+ ["d", "", "", "", "d"]
+ ];
+ assert(equal!equal(s.matchAll(ctr), outcomes));
+ assert(equal!equal(s.bmatch(r), outcomes));
+}
+
+// bugzilla 17667
+@safe unittest
+{
+ import std.algorithm.searching : canFind;
+ void willThrow(T, size_t line = __LINE__)(T arg, string msg)
+ {
+ auto e = collectException(regex(arg));
+ assert(e.msg.canFind(msg), to!string(line) ~ ": " ~ e.msg);
+ }
+ willThrow([r".", r"[\(\{[\]\}\)]"], "no matching ']' found while parsing character class");
+ willThrow([r"[\", r"123"], "no matching ']' found while parsing character class");
+ willThrow([r"[a-", r"123"], "no matching ']' found while parsing character class");
+ willThrow([r"[a-\", r"123"], "invalid escape sequence");
+ willThrow([r"\", r"123"], "invalid escape sequence");
+}
+
+// bugzilla 17668
+@safe unittest
+{
+ import std.algorithm.searching;
+ auto e = collectException!RegexException(regex(q"<[^]>"));
+ assert(e.msg.canFind("no operand for '^'"));
+}
+
+// bugzilla 17673
+@safe unittest
+{
+ string str = `<">`;
+ string[] regexps = ["abc", "\"|x"];
+ auto regexp = regex(regexps);
+ auto c = matchFirst(str, regexp);
+ assert(c);
+ assert(c.whichPattern == 2);
+}
+
diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d
index a4ba39c..d7de153 100644
--- a/libphobos/src/std/socket.d
+++ b/libphobos/src/std/socket.d
@@ -85,10 +85,10 @@ else version (Posix)
}
}
+ public import core.sys.posix.netinet.in_;
import core.sys.posix.arpa.inet;
import core.sys.posix.fcntl;
import core.sys.posix.netdb;
- import core.sys.posix.netinet.in_;
import core.sys.posix.netinet.tcp;
import core.sys.posix.sys.select;
import core.sys.posix.sys.socket;
@@ -146,6 +146,8 @@ class SocketException: Exception
mixin basicExceptionCtors;
}
+version (CRuntime_Glibc) version = GNU_STRERROR;
+version (CRuntime_UClibc) version = GNU_STRERROR;
/*
* Needs to be public so that SocketOSException can be thrown outside of
@@ -159,7 +161,7 @@ string formatSocketError(int err) @trusted
{
char[80] buf;
const(char)* cs;
- version (CRuntime_Glibc)
+ version (GNU_STRERROR)
{
cs = strerror_r(err, buf.ptr, buf.length);
}
diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d
index 4c1ad0b..bbf7857 100644
--- a/libphobos/src/std/stdio.d
+++ b/libphobos/src/std/stdio.d
@@ -37,48 +37,59 @@ else version (CRuntime_DigitalMars)
// Specific to the way Digital Mars C does stdio
version = DIGITAL_MARS_STDIO;
}
-
-version (CRuntime_Glibc)
+else version (CRuntime_Glibc)
{
// Specific to the way Gnu C does stdio
version = GCC_IO;
- version = HAS_GETDELIM;
}
else version (CRuntime_Bionic)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (CRuntime_Musl)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
-
-version (OSX)
+else version (CRuntime_UClibc)
+{
+ // uClibc supports GCC IO
+ version = GCC_IO;
+}
+else version (OSX)
+{
+ version = GENERIC_IO;
+}
+else version (iOS)
+{
+ version = GENERIC_IO;
+}
+else version (TVOS)
+{
+ version = GENERIC_IO;
+}
+else version (WatchOS)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (FreeBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (NetBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
+}
+else version (OpenBSD)
+{
+ version = GENERIC_IO;
}
else version (DragonFlyBSD)
{
version = GENERIC_IO;
- version = HAS_GETDELIM;
}
else version (Solaris)
{
version = GENERIC_IO;
- version = NO_GETDELIM;
}
// Character type used for operating system filesystem APIs
@@ -86,12 +97,11 @@ version (Windows)
{
private alias FSChar = wchar;
}
-else version (Posix)
+else
{
private alias FSChar = char;
}
-else
- static assert(0);
+
version (Windows)
{
@@ -105,6 +115,11 @@ version (Windows)
import core.sys.windows.windows : HANDLE;
}
+version (Posix)
+{
+ static import core.sys.posix.stdio; // getdelim
+}
+
version (DIGITAL_MARS_STDIO)
{
extern (C)
@@ -244,11 +259,19 @@ else
static assert(0, "unsupported C I/O system");
}
-version (HAS_GETDELIM) extern(C) nothrow @nogc
+static if (__traits(compiles, core.sys.posix.stdio.getdelim))
{
- ptrdiff_t getdelim(char**, size_t*, int, FILE*);
- // getline() always comes together with getdelim()
- ptrdiff_t getline(char**, size_t*, FILE*);
+ extern(C) nothrow @nogc
+ {
+ // @@@DEPRECATED_2.104@@@
+ deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getdelim instead.")
+ ptrdiff_t getdelim(char**, size_t*, int, FILE*);
+
+ // @@@DEPRECATED_2.104@@@
+ // getline() always comes together with getdelim()
+ deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getline instead.")
+ ptrdiff_t getline(char**, size_t*, FILE*);
+ }
}
//------------------------------------------------------------------------------
@@ -4718,59 +4741,142 @@ private struct ReadlnAppender
}
// Private implementation of readln
-version (DIGITAL_MARS_STDIO)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation /*ignored*/)
+private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
{
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
+ version (DIGITAL_MARS_STDIO)
+ {
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
- /* Since fps is now locked, we can create an "unshared" version
- * of fp.
- */
- auto fp = cast(_iobuf*) fps;
+ /* Since fps is now locked, we can create an "unshared" version
+ * of fp.
+ */
+ auto fp = cast(_iobuf*) fps;
- ReadlnAppender app;
- app.initialize(buf);
+ ReadlnAppender app;
+ app.initialize(buf);
- if (__fhnd_info[fp._file] & FHND_WCHAR)
- { /* Stream is in wide characters.
- * Read them and convert to chars.
- */
- static assert(wchar_t.sizeof == 2);
- for (int c = void; (c = FGETWC(fp)) != -1; )
+ if (__fhnd_info[fp._file] & FHND_WCHAR)
+ { /* Stream is in wide characters.
+ * Read them and convert to chars.
+ */
+ static assert(wchar_t.sizeof == 2);
+ for (int c = void; (c = FGETWC(fp)) != -1; )
+ {
+ if ((c & ~0x7F) == 0)
+ {
+ app.putchar(cast(char) c);
+ if (c == terminator)
+ break;
+ }
+ else
+ {
+ if (c >= 0xD800 && c <= 0xDBFF)
+ {
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ }
+ app.putdchar(cast(dchar) c);
+ }
+ }
+ if (ferror(fps))
+ StdioException();
+ }
+
+ else if (fp._flag & _IONBF)
{
- if ((c & ~0x7F) == 0)
+ /* Use this for unbuffered I/O, when running
+ * across buffer boundaries, or for any but the common
+ * cases.
+ */
+ L1:
+ int c;
+ while ((c = FGETC(fp)) != -1)
{
app.putchar(cast(char) c);
if (c == terminator)
- break;
+ {
+ buf = app.data;
+ return buf.length;
+ }
+
}
- else
- {
- if (c >= 0xD800 && c <= 0xDBFF)
+
+ if (ferror(fps))
+ StdioException();
+ }
+ else
+ {
+ int u = fp._cnt;
+ char* p = fp._ptr;
+ int i;
+ if (fp._flag & _IOTRAN)
+ { /* Translated mode ignores \r and treats ^Z as end-of-file
+ */
+ char c;
+ while (1)
{
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
+ if (i == u) // if end of buffer
+ goto L1; // give up
+ c = p[i];
+ i++;
+ if (c != '\r')
{
- StdioException("unpaired UTF-16 surrogate");
+ if (c == terminator)
+ break;
+ if (c != 0x1A)
+ continue;
+ goto L1;
+ }
+ else
+ { if (i != u && p[i] == terminator)
+ break;
+ goto L1;
}
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
}
- app.putdchar(cast(dchar) c);
+ app.putonly(p[0 .. i]);
+ app.buf[i - 1] = cast(char) terminator;
+ if (terminator == '\n' && c == '\r')
+ i++;
}
+ else
+ {
+ while (1)
+ {
+ if (i == u) // if end of buffer
+ goto L1; // give up
+ auto c = p[i];
+ i++;
+ if (c == terminator)
+ break;
+ }
+ app.putonly(p[0 .. i]);
+ }
+ fp._cnt -= i;
+ fp._ptr += i;
}
- if (ferror(fps))
- StdioException();
- }
- else if (fp._flag & _IONBF)
+ buf = app.data;
+ return buf.length;
+ }
+ else version (MICROSOFT_STDIO)
{
- /* Use this for unbuffered I/O, when running
- * across buffer boundaries, or for any but the common
- * cases.
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
+
+ /* Since fps is now locked, we can create an "unshared" version
+ * of fp.
*/
- L1:
+ auto fp = cast(_iobuf*) fps;
+
+ ReadlnAppender app;
+ app.initialize(buf);
+
int c;
while ((c = FGETC(fp)) != -1)
{
@@ -4785,295 +4891,208 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
if (ferror(fps))
StdioException();
+ buf = app.data;
+ return buf.length;
}
- else
+ else static if (__traits(compiles, core.sys.posix.stdio.getdelim))
{
- int u = fp._cnt;
- char* p = fp._ptr;
- int i;
- if (fp._flag & _IOTRAN)
- { /* Translated mode ignores \r and treats ^Z as end-of-file
+ import core.stdc.stdlib : free;
+ import core.stdc.wchar_ : fwide;
+
+ if (orientation == File.Orientation.wide)
+ {
+ /* Stream is in wide characters.
+ * Read them and convert to chars.
*/
- char c;
- while (1)
+ FLOCK(fps);
+ scope(exit) FUNLOCK(fps);
+ auto fp = cast(_iobuf*) fps;
+ version (Windows)
{
- if (i == u) // if end of buffer
- goto L1; // give up
- c = p[i];
- i++;
- if (c != '\r')
+ buf.length = 0;
+ for (int c = void; (c = FGETWC(fp)) != -1; )
{
- if (c == terminator)
- break;
- if (c != 0x1A)
- continue;
- goto L1;
+ if ((c & ~0x7F) == 0)
+ { buf ~= c;
+ if (c == terminator)
+ break;
+ }
+ else
+ {
+ if (c >= 0xD800 && c <= 0xDBFF)
+ {
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ }
+ import std.utf : encode;
+ encode(buf, c);
+ }
}
- else
- { if (i != u && p[i] == terminator)
+ if (ferror(fp))
+ StdioException();
+ return buf.length;
+ }
+ else version (Posix)
+ {
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
+ {
+ import std.utf : encode;
+
+ if ((c & ~0x7F) == 0)
+ buf ~= cast(char) c;
+ else
+ encode(buf, cast(dchar) c);
+ if (c == terminator)
break;
- goto L1;
}
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
+ }
+ else
+ {
+ static assert(0);
}
- app.putonly(p[0 .. i]);
- app.buf[i - 1] = cast(char) terminator;
- if (terminator == '\n' && c == '\r')
- i++;
}
- else
+
+ static char *lineptr = null;
+ static size_t n = 0;
+ scope(exit)
{
- while (1)
+ if (n > 128 * 1024)
{
- if (i == u) // if end of buffer
- goto L1; // give up
- auto c = p[i];
- i++;
- if (c == terminator)
- break;
+ // Bound memory used by readln
+ free(lineptr);
+ lineptr = null;
+ n = 0;
}
- app.putonly(p[0 .. i]);
}
- fp._cnt -= i;
- fp._ptr += i;
- }
-
- buf = app.data;
- return buf.length;
-}
-version (MICROSOFT_STDIO)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation /*ignored*/)
-{
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
-
- /* Since fps is now locked, we can create an "unshared" version
- * of fp.
- */
- auto fp = cast(_iobuf*) fps;
-
- ReadlnAppender app;
- app.initialize(buf);
-
- int c;
- while ((c = FGETC(fp)) != -1)
- {
- app.putchar(cast(char) c);
- if (c == terminator)
+ auto s = core.sys.posix.stdio.getdelim(&lineptr, &n, terminator, fps);
+ if (s < 0)
{
- buf = app.data;
- return buf.length;
+ if (ferror(fps))
+ StdioException();
+ buf.length = 0; // end of file
+ return 0;
}
+ if (s <= buf.length)
+ {
+ buf = buf[0 .. s];
+ buf[] = lineptr[0 .. s];
+ }
+ else
+ {
+ buf = lineptr[0 .. s].dup;
+ }
+ return s;
}
-
- if (ferror(fps))
- StdioException();
- buf = app.data;
- return buf.length;
-}
-
-version (HAS_GETDELIM)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
-{
- import core.stdc.stdlib : free;
- import core.stdc.wchar_ : fwide;
-
- if (orientation == File.Orientation.wide)
+ else // version (NO_GETDELIM)
{
- /* Stream is in wide characters.
- * Read them and convert to chars.
- */
+ import core.stdc.wchar_ : fwide;
+
FLOCK(fps);
scope(exit) FUNLOCK(fps);
auto fp = cast(_iobuf*) fps;
- version (Windows)
+ if (orientation == File.Orientation.wide)
{
- buf.length = 0;
- for (int c = void; (c = FGETWC(fp)) != -1; )
+ /* Stream is in wide characters.
+ * Read them and convert to chars.
+ */
+ version (Windows)
{
- if ((c & ~0x7F) == 0)
- { buf ~= c;
- if (c == terminator)
- break;
- }
- else
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
{
- if (c >= 0xD800 && c <= 0xDBFF)
+ if ((c & ~0x7F) == 0)
+ { buf ~= c;
+ if (c == terminator)
+ break;
+ }
+ else
{
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
+ if (c >= 0xD800 && c <= 0xDBFF)
{
- StdioException("unpaired UTF-16 surrogate");
+ int c2 = void;
+ if ((c2 = FGETWC(fp)) != -1 ||
+ c2 < 0xDC00 && c2 > 0xDFFF)
+ {
+ StdioException("unpaired UTF-16 surrogate");
+ }
+ c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
}
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
+ import std.utf : encode;
+ encode(buf, c);
}
- import std.utf : encode;
- encode(buf, c);
}
+ if (ferror(fp))
+ StdioException();
+ return buf.length;
}
- if (ferror(fp))
- StdioException();
- return buf.length;
- }
- else version (Posix)
- {
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
+ else version (Posix)
{
import std.utf : encode;
-
- if ((c & ~0x7F) == 0)
- buf ~= cast(char) c;
- else
- encode(buf, cast(dchar) c);
- if (c == terminator)
- break;
- }
- if (ferror(fps))
- StdioException();
- return buf.length;
- }
- else
- {
- static assert(0);
- }
- }
-
- static char *lineptr = null;
- static size_t n = 0;
- scope(exit)
- {
- if (n > 128 * 1024)
- {
- // Bound memory used by readln
- free(lineptr);
- lineptr = null;
- n = 0;
- }
- }
-
- auto s = getdelim(&lineptr, &n, terminator, fps);
- if (s < 0)
- {
- if (ferror(fps))
- StdioException();
- buf.length = 0; // end of file
- return 0;
- }
-
- if (s <= buf.length)
- {
- buf = buf[0 .. s];
- buf[] = lineptr[0 .. s];
- }
- else
- {
- buf = lineptr[0 .. s].dup;
- }
- return s;
-}
-
-version (NO_GETDELIM)
-private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)
-{
- import core.stdc.wchar_ : fwide;
-
- FLOCK(fps);
- scope(exit) FUNLOCK(fps);
- auto fp = cast(_iobuf*) fps;
- if (orientation == File.Orientation.wide)
- {
- /* Stream is in wide characters.
- * Read them and convert to chars.
- */
- version (Windows)
- {
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
- {
- if ((c & ~0x7F) == 0)
- { buf ~= c;
+ buf.length = 0;
+ for (int c; (c = FGETWC(fp)) != -1; )
+ {
+ if ((c & ~0x7F) == 0)
+ buf ~= cast(char) c;
+ else
+ encode(buf, cast(dchar) c);
if (c == terminator)
break;
}
- else
- {
- if (c >= 0xD800 && c <= 0xDBFF)
- {
- int c2 = void;
- if ((c2 = FGETWC(fp)) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
- {
- StdioException("unpaired UTF-16 surrogate");
- }
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
- }
- import std.utf : encode;
- encode(buf, c);
- }
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
}
- if (ferror(fp))
- StdioException();
- return buf.length;
- }
- else version (Posix)
- {
- import std.utf : encode;
- buf.length = 0;
- for (int c; (c = FGETWC(fp)) != -1; )
+ else
{
- if ((c & ~0x7F) == 0)
- buf ~= cast(char) c;
- else
- encode(buf, cast(dchar) c);
- if (c == terminator)
- break;
+ static assert(0);
}
- if (ferror(fps))
- StdioException();
- return buf.length;
- }
- else
- {
- static assert(0);
}
- }
- // Narrow stream
- // First, fill the existing buffer
- for (size_t bufPos = 0; bufPos < buf.length; )
- {
- immutable c = FGETC(fp);
- if (c == -1)
- {
- buf.length = bufPos;
- goto endGame;
- }
- buf[bufPos++] = cast(char) c;
- if (c == terminator)
+ // Narrow stream
+ // First, fill the existing buffer
+ for (size_t bufPos = 0; bufPos < buf.length; )
{
- // No need to test for errors in file
- buf.length = bufPos;
- return bufPos;
+ immutable c = FGETC(fp);
+ if (c == -1)
+ {
+ buf.length = bufPos;
+ goto endGame;
+ }
+ buf[bufPos++] = cast(char) c;
+ if (c == terminator)
+ {
+ // No need to test for errors in file
+ buf.length = bufPos;
+ return bufPos;
+ }
}
- }
- // Then, append to it
- for (int c; (c = FGETC(fp)) != -1; )
- {
- buf ~= cast(char) c;
- if (c == terminator)
+ // Then, append to it
+ for (int c; (c = FGETC(fp)) != -1; )
{
- // No need to test for errors in file
- return buf.length;
+ buf ~= cast(char) c;
+ if (c == terminator)
+ {
+ // No need to test for errors in file
+ return buf.length;
+ }
}
- }
- endGame:
- if (ferror(fps))
- StdioException();
- return buf.length;
+ endGame:
+ if (ferror(fps))
+ StdioException();
+ return buf.length;
+ }
}
@system unittest
diff --git a/libphobos/src/std/system.d b/libphobos/src/std/system.d
index e0b3dee..353d692 100644
--- a/libphobos/src/std/system.d
+++ b/libphobos/src/std/system.d
@@ -30,6 +30,9 @@ immutable
win64, /// Microsoft 64 bit Windows systems
linux, /// All Linux Systems, except for Android
osx, /// Mac OS X
+ iOS, /// iOS
+ tvOS, /// tvOS
+ watchOS, /// watchOS
freeBSD, /// FreeBSD
netBSD, /// NetBSD
dragonFlyBSD, /// DragonFlyBSD
@@ -44,6 +47,9 @@ immutable
else version (Android) OS os = OS.android;
else version (linux) OS os = OS.linux;
else version (OSX) OS os = OS.osx;
+ else version (iOS) OS os = OS.iOS;
+ else version (tvOS) OS os = OS.tvOS;
+ else version (watchOS) OS os = OS.watchOS;
else version (FreeBSD) OS os = OS.freeBSD;
else version (NetBSD) OS os = OS.netBSD;
else version (DragonFlyBSD) OS os = OS.dragonFlyBSD;
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index a63227c..84e876f 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -4204,10 +4204,11 @@ package template OverloadSet(string nam, T...)
/*
Used by MemberFunctionGenerator.
*/
-package template FuncInfo(alias func, /+[BUG 4217 ?]+/ T = typeof(&func))
+package template FuncInfo(alias func)
+if (is(typeof(&func)))
{
- alias RT = ReturnType!T;
- alias PT = Parameters!T;
+ alias RT = ReturnType!(typeof(&func));
+ alias PT = Parameters!(typeof(&func));
}
package template FuncInfo(Func)
{
@@ -4248,6 +4249,7 @@ private static:
// Internal stuffs
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
import std.format;
+ alias format = std.format.format;
enum CONSTRUCTOR_NAME = "__ctor";
@@ -5024,7 +5026,7 @@ package template GetOverloadedMethods(T)
enum isMethod = false;
}
alias follows = AliasSeq!(
- std.meta.Filter!(isMethod, __traits(getOverloads, T, name)),
+ Filter!(isMethod, __traits(getOverloads, T, name)),
follows!(i + 1));
}
}
@@ -5933,13 +5935,7 @@ mixin template Proxy(alias a)
// built-in type field, manifest constant, and static non-mutable field
enum opDispatch = mixin("a."~name);
}
- else static if (is(typeof(mixin("a."~name))) || __traits(getOverloads, a, name).length != 0)
- {
- // field or property function
- @property auto ref opDispatch(this X)() { return mixin("a."~name); }
- @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); }
- }
- else
+ else static if (__traits(isTemplate, mixin("a."~name)))
{
// member template
template opDispatch(T...)
@@ -5948,6 +5944,13 @@ mixin template Proxy(alias a)
auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin("a."~name~targs~"(args)"); }
}
}
+ else
+ {
+ // field or property function
+ @property auto ref opDispatch(this X)() { return mixin("a."~name); }
+ @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); }
+ }
+
}
import std.traits : isArray;
diff --git a/libphobos/src/std/zip.d b/libphobos/src/std/zip.d
index 8b130ea..9e55d19 100644
--- a/libphobos/src/std/zip.d
+++ b/libphobos/src/std/zip.d
@@ -263,8 +263,8 @@ final class ArchiveMember
{
void print()
{
- printf("name = '%.*s'\n", name.length, name.ptr);
- printf("\tcomment = '%.*s'\n", comment.length, comment.ptr);
+ printf("name = '%.*s'\n", cast(int) name.length, name.ptr);
+ printf("\tcomment = '%.*s'\n", cast(int) comment.length, comment.ptr);
printf("\tmadeVersion = x%04x\n", _madeVersion);
printf("\textractVersion = x%04x\n", extractVersion);
printf("\tflags = x%04x\n", flags);
@@ -348,7 +348,7 @@ final class ZipArchive
printf("\tdiskStartDir = %u\n", diskStartDir);
printf("\tnumEntries = %u\n", numEntries);
printf("\ttotalEntries = %u\n", totalEntries);
- printf("\tcomment = '%.*s'\n", comment.length, comment.ptr);
+ printf("\tcomment = '%.*s'\n", cast(int) comment.length, comment.ptr);
}
}
diff --git a/libphobos/testsuite/Makefile.am b/libphobos/testsuite/Makefile.am
index c3a91a6..535c73f 100644
--- a/libphobos/testsuite/Makefile.am
+++ b/libphobos/testsuite/Makefile.am
@@ -1,5 +1,5 @@
## Makefile for the testsuite subdirectory of the D Standard library.
-## Copyright (C) 2016-2020 Free Software Foundation, Inc.
+## Copyright (C) 2016-2021 Free Software Foundation, Inc.
##
## GCC is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/Makefile.in b/libphobos/testsuite/Makefile.in
index c38a468..8855480 100644
--- a/libphobos/testsuite/Makefile.in
+++ b/libphobos/testsuite/Makefile.in
@@ -215,6 +215,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
+SECTION_FLAGS = @SECTION_FLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -242,6 +243,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -271,6 +274,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
diff --git a/libphobos/testsuite/config/default.exp b/libphobos/testsuite/config/default.exp
index 3b1fce2..62f3148 100644
--- a/libphobos/testsuite/config/default.exp
+++ b/libphobos/testsuite/config/default.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/lib/libphobos-dg.exp b/libphobos/testsuite/lib/libphobos-dg.exp
index 9497c63..e9b542e 100644
--- a/libphobos/testsuite/lib/libphobos-dg.exp
+++ b/libphobos/testsuite/lib/libphobos-dg.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/lib/libphobos.exp b/libphobos/testsuite/lib/libphobos.exp
index 790480b..3be2092 100644
--- a/libphobos/testsuite/lib/libphobos.exp
+++ b/libphobos/testsuite/lib/libphobos.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.aa/aa.exp b/libphobos/testsuite/libphobos.aa/aa.exp
index 55b8bd6..ccece10 100644
--- a/libphobos/testsuite/libphobos.aa/aa.exp
+++ b/libphobos/testsuite/libphobos.aa/aa.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2018-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.allocations/allocations.exp b/libphobos/testsuite/libphobos.allocations/allocations.exp
index 663bb3c..75fd7ab 100644
--- a/libphobos/testsuite/libphobos.allocations/allocations.exp
+++ b/libphobos/testsuite/libphobos.allocations/allocations.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.allocations/tls_gc_integration.d b/libphobos/testsuite/libphobos.allocations/tls_gc_integration.d
index 44eb40c..7c084ab 100644
--- a/libphobos/testsuite/libphobos.allocations/tls_gc_integration.d
+++ b/libphobos/testsuite/libphobos.allocations/tls_gc_integration.d
@@ -1,4 +1,4 @@
-import core.memory, core.thread, core.bitop;
+import core.memory, core.thread, core.volatile;
/*
* This test repeatedly performs operations on GC-allocated objects which
diff --git a/libphobos/testsuite/libphobos.cycles/cycles.exp b/libphobos/testsuite/libphobos.cycles/cycles.exp
index 90eeef0..a4e868e 100644
--- a/libphobos/testsuite/libphobos.cycles/cycles.exp
+++ b/libphobos/testsuite/libphobos.cycles/cycles.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.druntime/druntime.exp b/libphobos/testsuite/libphobos.druntime/druntime.exp
index 7072ebb..daedfd7 100644
--- a/libphobos/testsuite/libphobos.druntime/druntime.exp
+++ b/libphobos/testsuite/libphobos.druntime/druntime.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2019-2020 Free Software Foundation, Inc.
+# Copyright (C) 2019-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
@@ -34,7 +34,8 @@ dg-init
# Main loop.
foreach test $tests {
set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../libdruntime $test]"
- dg-runtest $test "" "-fmain -fbuilding-libphobos-tests $version_flags"
+ dg-runtest $test "-static-libphobos" \
+ "-fmain -fbuilding-libphobos-tests $version_flags"
set libphobos_test_name ""
}
diff --git a/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp b/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp
index 2d92051..51f9c2c 100644
--- a/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp
+++ b/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2019-2020 Free Software Foundation, Inc.
+# Copyright (C) 2019-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@ dg-init
# Main loop.
foreach test $tests {
set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../libdruntime $test]"
- dg-runtest $test "-fversion=Shared -shared-libphobos" \
+ dg-runtest $test "-shared-libphobos" \
"-fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags"
set libphobos_test_name ""
}
diff --git a/libphobos/testsuite/libphobos.exceptions/chain.d b/libphobos/testsuite/libphobos.exceptions/chain.d
index 462ba24..0305707 100644
--- a/libphobos/testsuite/libphobos.exceptions/chain.d
+++ b/libphobos/testsuite/libphobos.exceptions/chain.d
@@ -65,14 +65,14 @@ void main()
string prefix = "";
for ({ size_t i; Throwable ex = original; } ex; ex = ex.next, ++i)
{
- printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr);
+ printf("%.*s%.*s\n", cast(int)prefix.length, prefix.ptr, cast(int)ex.msg.length, ex.msg.ptr);
prefix = prefix~" ";
}
printf("Bypassed chain was:\n");
prefix = "";
for ({ size_t i; Throwable ex = original.bypassedException; } ex; ex = ex.next, ++i)
{
- printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr);
+ printf("%.*s%.*s\n", cast(int)prefix.length, prefix.ptr, cast(int)ex.msg.length, ex.msg.ptr);
prefix = prefix~" ";
}
}
diff --git a/libphobos/testsuite/libphobos.exceptions/exceptions.exp b/libphobos/testsuite/libphobos.exceptions/exceptions.exp
index 663bb3c..75fd7ab 100644
--- a/libphobos/testsuite/libphobos.exceptions/exceptions.exp
+++ b/libphobos/testsuite/libphobos.exceptions/exceptions.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.exceptions/line_trace.d b/libphobos/testsuite/libphobos.exceptions/line_trace.d
index 7b75d3a..70762ff 100644
--- a/libphobos/testsuite/libphobos.exceptions/line_trace.d
+++ b/libphobos/testsuite/libphobos.exceptions/line_trace.d
@@ -9,7 +9,7 @@ void main()
{
import core.stdc.stdio;
auto str = e.toString();
- printf("%.*s\n", str.length, str.ptr);
+ printf("%.*s\n", cast(int)str.length, str.ptr);
}
}
diff --git a/libphobos/testsuite/libphobos.hash/hash.exp b/libphobos/testsuite/libphobos.hash/hash.exp
index 55b8bd6..ccece10 100644
--- a/libphobos/testsuite/libphobos.hash/hash.exp
+++ b/libphobos/testsuite/libphobos.hash/hash.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2018-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.init_fini/init_fini.exp b/libphobos/testsuite/libphobos.init_fini/init_fini.exp
index 4bbc8ba..13f70d5 100644
--- a/libphobos/testsuite/libphobos.init_fini/init_fini.exp
+++ b/libphobos/testsuite/libphobos.init_fini/init_fini.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp
index aad877c..937849e 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2019-2020 Free Software Foundation, Inc.
+# Copyright (C) 2019-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
# <http://www.gnu.org/licenses/>.
# Immediately exit if we can't run target executables.
-if { ![isnative] || ![is-effective-target static] } {
+if { ![isnative] } {
return
}
@@ -27,6 +27,12 @@ if { ![is-effective-target d_runtime_has_std_library] } {
# Gather a list of all tests.
set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
+set version_flags ""
+
+if { [is-effective-target linux_pre_2639] } {
+ lappend version_flags "-fversion=Linux_Pre_2639"
+}
+
set libphobos_skip_tests {
# Skip curl tests if library is not available
{ libphobos.phobos/etc/c/curl.d { ! libcurl_available } }
@@ -39,7 +45,8 @@ dg-init
# Main loop.
foreach test $tests {
set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]"
- dg-runtest $test "" "-fmain -fbuilding-libphobos-tests"
+ dg-runtest $test "-static-libphobos" \
+ "-fmain -fbuilding-libphobos-tests $version_flags"
set libphobos_test_name ""
}
diff --git a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
index a00ecf11..8498522 100644
--- a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
+++ b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2019-2020 Free Software Foundation, Inc.
+# Copyright (C) 2019-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -27,6 +27,12 @@ if { ![is-effective-target d_runtime_has_std_library] } {
# Gather a list of all tests.
set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
+set version_flags ""
+
+if { [is-effective-target linux_pre_2639] } {
+ lappend version_flags "-fversion=Linux_Pre_2639"
+}
+
set libphobos_skip_tests {
# Skip curl tests if library is not available
{ libphobos.phobos_shared/etc/c/curl.d { ! libcurl_available } }
@@ -39,8 +45,8 @@ dg-init
# Main loop.
foreach test $tests {
set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]"
- dg-runtest $test "-fversion=Shared -shared-libphobos" \
- "-fmain -fbuilding-libphobos-tests -fno-moduleinfo"
+ dg-runtest $test "-shared-libphobos" \
+ "-fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags"
set libphobos_test_name ""
}
diff --git a/libphobos/testsuite/libphobos.shared/shared.exp b/libphobos/testsuite/libphobos.shared/shared.exp
index 5a01f52..80c7f53 100644
--- a/libphobos/testsuite/libphobos.shared/shared.exp
+++ b/libphobos/testsuite/libphobos.shared/shared.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.thread/fiber_guard_page.d b/libphobos/testsuite/libphobos.thread/fiber_guard_page.d
index 61a616a..ca54a19 100644
--- a/libphobos/testsuite/libphobos.thread/fiber_guard_page.d
+++ b/libphobos/testsuite/libphobos.thread/fiber_guard_page.d
@@ -1,13 +1,15 @@
// { dg-options "-O0" }
// { dg-shouldfail "segv or bus error" }
import core.thread;
+import core.sys.posix.signal;
import core.sys.posix.sys.mman;
// this should be true for most architectures
// (taken from core.thread)
-version = StackGrowsDown;
+version (GNU_StackGrowsDown)
+ version = StackGrowsDown;
-enum stackSize = 4096;
+enum stackSize = MINSIGSTKSZ;
// Simple method that causes a stack overflow
void stackMethod()
@@ -23,18 +25,15 @@ void main()
// allocate a page below (above) the fiber's stack to make stack overflows possible (w/o segfaulting)
version (StackGrowsDown)
{
- static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem");
- auto stackBottom = test_fiber.tupleof[8];
+ auto stackBottom = __traits(getMember, test_fiber, "m_pmem");
auto p = mmap(stackBottom - 8 * stackSize, 8 * stackSize,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
assert(p !is null, "failed to allocate page");
}
else
{
- auto m_sz = test_fiber.tupleof[7];
- auto m_pmem = test_fiber.tupleof[8];
- static assert(__traits(identifier, test_fiber.tupleof[7]) == "m_size");
- static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem");
+ auto m_sz = __traits(getMember, test_fiber, "m_sz");
+ auto m_pmem = __traits(getMember, test_fiber, "m_pmem");
auto stackTop = m_pmem + m_sz;
auto p = mmap(stackTop, 8 * stackSize,
diff --git a/libphobos/testsuite/libphobos.thread/thread.exp b/libphobos/testsuite/libphobos.thread/thread.exp
index 663bb3c..75fd7ab 100644
--- a/libphobos/testsuite/libphobos.thread/thread.exp
+++ b/libphobos/testsuite/libphobos.thread/thread.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/libphobos.typeinfo/typeinfo.exp b/libphobos/testsuite/libphobos.typeinfo/typeinfo.exp
index 4bbc8ba..13f70d5 100644
--- a/libphobos/testsuite/libphobos.typeinfo/typeinfo.exp
+++ b/libphobos/testsuite/libphobos.typeinfo/typeinfo.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+# Copyright (C) 2017-2021 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libphobos/testsuite/testsuite_flags.in b/libphobos/testsuite/testsuite_flags.in
index 6a2d79f..bafd5ad4 100755
--- a/libphobos/testsuite/testsuite_flags.in
+++ b/libphobos/testsuite/testsuite_flags.in
@@ -28,7 +28,8 @@ case ${query} in
;;
--gdcflags)
GDCFLAGS_default="-fmessage-length=0 -fno-show-column"
- GDCFLAGS_config="@WARN_DFLAGS@ @GDCFLAGS@ @CET_DFLAGS@ -fno-release -funittest"
+ GDCFLAGS_config="@WARN_DFLAGS@ @GDCFLAGS@ @CET_DFLAGS@
+ @phobos_compiler_shared_flag@ -fno-release -funittest"
echo ${GDCFLAGS_default} ${GDCFLAGS_config}
;;
--gdcpaths)