diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2021-09-13 19:49:49 +0200 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2021-09-13 19:49:49 +0200 |
commit | b18a97e5dd0935e1c4a626c230f21457d0aad3d5 (patch) | |
tree | c1818f41af6fe780deafb6cd6a183f32085fe654 /libphobos | |
parent | e76a53644c9d70e998c0d050e9a456af388c6b61 (diff) | |
download | gcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.zip gcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.tar.gz gcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.tar.bz2 |
Merged current trunk to branch.
Diffstat (limited to 'libphobos')
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, ¶m ) == 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, ¶m)) - { - // 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, ¶m)) - { - // 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, ¶m)) - { - // 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, ¶m ) == 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, ¶m)) + { + // 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, ¶m)) + { + // 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, ¶m)) + { + // 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*)®s[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*)®s[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*)®s[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*)®s[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(§ions_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) |