Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/core/stdc/assert_.d
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ else version (CRuntime_Glibc)
void __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);
///
void __assert_perror_fail(int errnum, const(char)* file, uint line, const(char)* func);
}
else version (CRuntime_Musl)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that hitting static assert(0) can be annoying at the beginning when you just want see how far you can go, but to get your changes to into merge-able state, you need to fill out all empty else version (CRuntime_Musl) { } blocks that you added.

In this case, looking at include/assert.h (from git.musl-libc.org) and the glibc version above, you need to add:

    /***
     * Assert failure function in the Musl C library.
     */
    void __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or alternately, just leave empty blocks out of this pull for now, except for those that assert without them. In this case, you could just add a TODO comment here, as this is only needed for the betterC support. I don't know that adding __assert_fail alone does much, as dmd likely only calls __assert.

{

}
else
{
Expand Down
22 changes: 22 additions & 0 deletions src/core/stdc/fenv.d
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,25 @@ else version( Solaris )

alias int fexcept_t;
}
else version( CRuntime_Musl )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historically, druntime was written in a different code-style, but for all new code we try to follow https://dlang.org/dstyle.
-> use else version (CRuntime_Musl)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Druntime uses both styles, I'm guessing he just copy-pasted this style from above. No need to nitpick this, can always change it later.

{
struct fenv_t {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct, since fenv_t has architecture dependent implementation. I strongly suggest you follow the GNUFP code above as a good example, in other words:

else version (CRuntime_Musl)
{
    // http://git.musl-libc.org/cgit/musl/tree/arch/i386/bits/fenv.h
    version (X86)
    {
        struct fenv_t
        {
            ushort __control_word;
            ushort __unused1;
            ushort __status_word;
            ushort __unused2;
            ushort __tags;
            ushort __unused3;
            uint   __eip;
            ushort __cs_selector;
            ushort __opcode;
            uint   __data_offset;
            ushort __data_selector;
            ushort __unused5;
        }

        alias fexcept_t = ushort;
    }
    // http://git.musl-libc.org/cgit/musl/tree/arch/x86_64/bits/fenv.h
    else version (X86_64)
    {
        struct fenv_t
        {
            ushort __control_word;
            ushort __unused1;
            ushort __status_word;
            ushort __unused2;
            ushort __tags;
            ushort __unused3;
            uint   __eip;
            ushort __cs_selector;
            ushort __opcode;
            uint   __data_offset;
            ushort __data_selector;
            ushort __unused5;
            uint   __mxcsr;
        }

        alias fexcept_t = ushort;
    }
    // http://git.musl-libc.org/cgit/musl/tree/arch/mipsn32/bits/fenv.h
    else version (MIPS32)
    {
        struct fenv_t
        {
            uint   __cw;
        }

        alias fexcept_t = ushort;
    }
    // http://git.musl-libc.org/cgit/musl/tree/arch/mips64/bits/fenv.h
    else version (MIPS64)
    {
        struct fenv_t
        {
            uint   __cw;
        }

        alias fexcept_t = ushort;
    }
    // http://git.musl-libc.org/cgit/musl/tree/arch/aarch64/bits/fenv.h
    else version (AArch64)
    {
        struct fenv_t
        {
            uint __fpcr;
            uint __fpsr;
        }

        alias fexcept_t = uint;
    }
    // http://git.musl-libc.org/cgit/musl/tree/arch/arm/bits/fenv.h
    else version (ARM)
    {
        struct fenv_t
        {
            // FIXME: musl defines this as `unsigned long` - check if
            // this actually is 32-bits in size
            uint __cw;
        }

        // FIXME: musl defines this as `unsigned long` - check if
        // this actually is 32-bits in size
        alias fexcept_t = uint;
    }
    // http://git.musl-libc.org/cgit/musl/tree/arch/powerpc64/bits/fenv.h
    else version (PPC64)
    {
        alias fenv_t = double;
        alias fexcept_t = uint;
    }
    // http://git.musl-libc.org/cgit/musl/tree/arch/s390x/bits/fenv.h
    else version (SystemZ)
    {
        // Note: different from the glibc implementation:
        // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h

        alias fenv_t = uint;
        alias fexcept_t = uint;
    }
    else
    {
        static assert(0, "Unimplemented architecture support for musl libc");
    }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While Petar is right that architecture-dependent code should be versioned like this, you don't have to add any arch that you have not tried, so just adding the version(X86) guard and maybe version(X86_64) should be enough.

ushort __control_word;
ushort __unused1;
ushort __status_word;
ushort __unused2;
ushort __tags;
ushort __unused3;
uint __eip;
ushort __cs_selector;
ushort __opcode;
uint __data_offset;
ushort __data_selector;
ushort __unused5;
uint __mxcsr;
}
alias ushort fexcept_t;
}
else
{
static assert( false, "Unsupported platform" );
Expand Down Expand Up @@ -623,6 +642,9 @@ else version( Solaris )
///
enum FE_DFL_ENV = &__fenv_def_env;
}
else version( CRuntime_Musl )
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    // http://git.musl-libc.org/cgit/musl/tree/arch/generic/bits/fenv.h#n10
    // (implemented the same way for all architectures)
    enum FE_DFL_ENV = cast(fenv_t*)(-1);

}
else
{
static assert( false, "Unsupported platform" );
Expand Down
3 changes: 3 additions & 0 deletions src/core/stdc/locale.d
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ else version(Solaris)
///
enum LC_ALL = 6;
}
else version(CRuntime_Musl)
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else version (CRuntime_Musl)
{
    // http://git.musl-libc.org/cgit/musl/tree/include/locale.h

    ///
    enum LC_CTYPE          = 0;
    ///
    enum LC_NUMERIC        = 1;
    ///
    enum LC_TIME           = 2;
    ///
    enum LC_COLLATE        = 3;
    ///
    enum LC_MONETARY       = 4;
    ///
    enum LC_MESSAGES       = 5;
    ///
    enum LC_ALL            = 6;
}

}
else
{
static assert(false, "Unsupported platform");
Expand Down
130 changes: 130 additions & 0 deletions src/core/stdc/math.d
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,136 @@ else version( CRuntime_Glibc )
}
}
}
else version( CRuntime_Musl )
{
enum
{
///
FP_NAN,
///
FP_INFINITE,
///
FP_ZERO,
///
FP_SUBNORMAL,
///
FP_NORMAL,
}

enum
{
///
FP_FAST_FMA = 0,
///
FP_FAST_FMAF = 0,
///
FP_FAST_FMAL = 0,
}

int __fpclassifyf(float x);
int __fpclassify(double x);
int __fpclassifyl(real x);

int __signbitf(float x);
int __signbit(double x);
int __signbitl(real x);

extern (D)
{
//int fpclassify(real-floating x);
///
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);
}
static uint __FLOAT_BITS(float __f)
{
union __u_t {
float __f;
uint __i;
}
__u_t __u;
__u.__f = __f;
return __u.__i;
}
static ulong __DOUBLE_BITS(double __f)
{
union __u_t {
double __f;
ulong __i;
}
__u_t __u;
__u.__f = __f;
return __u.__i;
}

//int isfinite(real-floating x);
///
int isfinite(float x) { return (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000; }
///
int isfinite(double x) { return (__DOUBLE_BITS(x) & -1UL>>1) < 0x7ffUL<<52; }
///
int isfinite(real x)
{
return (real.sizeof == double.sizeof)
? isfinite(cast(double)x)
: __fpclassifyl(x) > FP_INFINITE;
}

//int isinf(real-floating x);
///
int isinf(float x) { return (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000; }
///
int isinf(double x) { return (__DOUBLE_BITS(x) & -1UL>>1) == 0x7ffUL<<52; }
///
int isinf(real x)
{
return (real.sizeof == double.sizeof)
? isinf(cast(double)x)
: __fpclassifyl(x) == FP_INFINITE;
}

//int isnan(real-floating x);
///
int isnan(float x) { return (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000; }
///
int isnan(double x) { return (__DOUBLE_BITS(x) & -1UL>>1) > 0x7ffUL<<52; }
///
int isnan(real x)
{
return (real.sizeof == double.sizeof)
? isnan(cast(double)x)
: __fpclassifyl(x) == FP_NAN;
}

//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);
///
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
Expand Down
74 changes: 74 additions & 0 deletions src/core/stdc/stdio.d
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,24 @@ else version( CRuntime_Glibc )
L_tmpnam = 20
}
}
else version( CRuntime_Musl )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else version (CRuntime_Musl)

{
enum
{
///
BUFSIZ = 8192,
///
EOF = -1,
///
FOPEN_MAX = 16,
///
FILENAME_MAX = 4095,
///
TMP_MAX = 238328,
///
L_tmpnam = 20
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure where you got those numbers from, but in http://git.musl-libc.org/cgit/musl/tree/include/stdio.h they're defined as:

#define BUFSIZ 1024
#define FILENAME_MAX 4096
#define FOPEN_MAX 1000
#define TMP_MAX 10000
#define L_tmpnam 20

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing he just copy-pasted one of the blocks above. Please don't submit code like this that is just copy-pasted from above without being checked.

}
else version( Darwin )
{
enum
Expand Down Expand Up @@ -292,6 +310,14 @@ else version( CRuntime_Bionic )
int _size;
}
}
else version( CRuntime_Musl )
{
enum
{
EOF = -1,
}

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete

else
{
static assert( false, "Unsupported platform" );
Expand Down Expand Up @@ -383,6 +409,16 @@ else version( CRuntime_Glibc )
///
alias shared(_IO_FILE) FILE;
}
else version( CRuntime_Musl )
{
struct fpos_t {
char[16] __opaque;
double __align;
}
struct _IO_FILE;
alias _IO_FILE _iobuf;
alias shared(_IO_FILE) FILE;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else version (CRuntime_Musl)
{
    // http://git.musl-libc.org/cgit/musl/tree/include/stdio.h
    union fpos_t
    {
        char[16] __opaque;
        double __align;
    }
    struct _IO_FILE;
    alias FILE = shared(_IO_FILE);
}

fpos_t is defined as an union not as a struct. Also I couldn't find a _iobuf definition in http://git.musl-libc.org/cgit/musl/tree/include/stdio.h.

The real _IO_FILE definition is here: http://git.musl-libc.org/cgit/musl/tree/src/internal/stdio_impl.h
@ibuclaw should we include it, or should we keep the implementation details hidden?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking we don't really need to define the structures of any FILE type. But for completion sake, and to match other runtimes it probably should be added.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ZombineDev _iobuf is defined because it's used in phobos.

else version( Darwin )
{
///
Expand Down Expand Up @@ -917,6 +953,20 @@ else version( CRuntime_Bionic )
///
shared stderr = &__sF[2];
}
else version( CRuntime_Musl )
{
/// needs tail const
extern shared FILE* stdin;
///
extern shared FILE* stdout;
///
extern shared FILE* stderr;
enum {
_IOFBF = 0,
_IOLBF = 1,
_IONBF = 2,
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else version (CRuntime_Musl)
{
    // http://git.musl-libc.org/cgit/musl/tree/include/stdio.h

    ///
    extern shared FILE* stdin;
    ///
    extern shared FILE* stdout;
    ///
    extern shared FILE* stderr;

    enum
    {
        _IOFBF = 0,
        _IOLBF = 1,
        _IONBF = 2,
    }
}

else
{
static assert( false, "Unsupported platform" );
Expand Down Expand Up @@ -1416,6 +1466,30 @@ else version( CRuntime_Bionic )
///
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
else version( CRuntime_Musl )
{
import core.sys.posix.sys.types : off_t;
///
int fseeko(FILE *, off_t, int);
@trusted
{
///
void rewind(FILE* stream);
///
pure void clearerr(FILE* stream);
///
pure int feof(FILE* stream);
///
pure int ferror(FILE* stream);
///
int fileno(FILE *);
}

///
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);
}
else
{
static assert( false, "Unsupported platform" );
Expand Down
1 change: 1 addition & 0 deletions src/core/stdc/stdlib.d
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ else version(NetBSD) enum RAND_MAX = 0x7fffffff;
else version(OpenBSD) enum RAND_MAX = 0x7fffffff;
else version(Solaris) enum RAND_MAX = 0x7fff;
else version(CRuntime_Bionic) enum RAND_MAX = 0x7fffffff;
else version(CRuntime_Musl) enum RAND_MAX = 0x7fffffff;
else static assert( false, "Unsupported platform" );

///
Expand Down
5 changes: 5 additions & 0 deletions src/core/stdc/string.d
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ else version (CRuntime_Bionic)
///
int strerror_r(int errnum, scope char* buf, size_t buflen);
}
else version (CRuntime_Musl)
{
///
int strerror_r (int, char *, size_t);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else version (CRuntime_Musl)
{
    ///
    int strerror_r(int errnum, scope char* buf, size_t buflen);
}

///
pure size_t strlen(scope const char* s);
///
Expand Down
7 changes: 7 additions & 0 deletions src/core/stdc/time.d
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ else version( CRuntime_Bionic )
///
extern __gshared const(char)*[2] tzname;
}
else version( CRuntime_Musl )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else version (CRuntime_Musl)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to add the following definition at the start of the file:

else version (CRuntime_Musl)
{
    enum clock_t CLOCKS_PER_SEC = 1_000_000;
}

{
///
void tzset(); // non-standard
///
extern __gshared const(char)*[2] tzname; // non-standard
}
else
{
static assert(false, "Unsupported platform");
Expand Down
25 changes: 25 additions & 0 deletions src/core/sys/posix/arpa/inet.d
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,31 @@ else version( CRuntime_Bionic )
const(char)* inet_ntop(int, in void*, char*, size_t);
int inet_pton(int, in char*, void*);
}
else version( CRuntime_Musl )
{
alias uint16_t in_port_t;
alias uint32_t in_addr_t;

struct in_addr
{
in_addr_t s_addr;
}

enum INET_ADDRSTRLEN = 16;

@trusted pure
{
uint32_t htonl(uint32_t);
uint16_t htons(uint16_t);
uint32_t ntohl(uint32_t);
uint16_t ntohs(uint16_t);
}

in_addr_t inet_addr(in char*);
char* inet_ntoa(in_addr);
const(char)* inet_ntop(int, in void*, char*, socklen_t);
int inet_pton(int, in char*, void*);
}

//
// IPV6 (IP6)
Expand Down
12 changes: 12 additions & 0 deletions src/core/sys/posix/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ version (CRuntime_Glibc)
else
enum __WORDSIZE=32;
}
else version (CRuntime_Musl)
{
enum _FILE_OFFSET_BITS = 64;

enum __REDIRECT = false;

enum __USE_FILE_OFFSET64 = _FILE_OFFSET_BITS == 64;
enum __USE_LARGEFILE = __USE_FILE_OFFSET64 && !__REDIRECT;
enum __USE_LARGEFILE64 = __USE_FILE_OFFSET64 && !__REDIRECT;

enum __WORDSIZE=64;
}
else version (Solaris)
{
enum _FILE_OFFSET_BITS = 64;
Expand Down
Loading