Skip to content

Instantly share code, notes, and snippets.

@joakim-noah
Created December 29, 2016 08:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joakim-noah/f0fc5c778719044b79c568134d79e04c to your computer and use it in GitHub Desktop.
Save joakim-noah/f0fc5c778719044b79c568134d79e04c to your computer and use it in GitHub Desktop.
Native Android/ARM support for phobos, for ldc master branch 2.071
diff --git a/std/conv.d b/std/conv.d
index dd81aa3e..53736bdf 100644
--- a/std/conv.d
+++ b/std/conv.d
@@ -2881,6 +2881,17 @@ unittest
assert(to!string(r) == to!string(real.max));
}
+version(unittest) private void softAssert(T)(T x, T y, int line = __LINE__)
+{
+ try
+ assert(x == y);
+ catch (Throwable e)
+ {
+ import std.stdio: writefln;
+ writefln(" --- std.conv(%d) test will fail if Android earlier than 5.0 ---", line);
+ writefln(" (%s)", e);
+ }
+}
//Tests for the double implementation
unittest
{
@@ -2894,7 +2905,7 @@ unittest
assert(x == 0x1A_BCDE_F012_3456p10L);
//1 bit is implicit
assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0xA_BCDE_F012_3456);
- assert(strtod("0x1ABCDEF0123456p10", null) == x);
+ softAssert(strtod("0x1ABCDEF0123456p10", null) , x);
//Should be parsed exactly: 10 bit mantissa
s = "0x3FFp10";
@@ -2902,7 +2913,7 @@ unittest
assert(x == 0x03FFp10);
//1 bit is implicit
assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_F800_0000_0000);
- assert(strtod("0x3FFp10", null) == x);
+ softAssert(strtod("0x3FFp10", null) , x);
//60 bit mantissa, round up
s = "0xFFF_FFFF_FFFF_FFFFp10";
@@ -2910,7 +2921,7 @@ unittest
assert(approxEqual(x, 0xFFF_FFFF_FFFF_FFFFp10));
//1 bit is implicit
assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x0000_0000_0000_0000);
- assert(strtod("0xFFFFFFFFFFFFFFFp10", null) == x);
+ softAssert(strtod("0xFFFFFFFFFFFFFFFp10", null) , x);
//60 bit mantissa, round down
s = "0xFFF_FFFF_FFFF_FF90p10";
@@ -2918,7 +2929,7 @@ unittest
assert(approxEqual(x, 0xFFF_FFFF_FFFF_FF90p10));
//1 bit is implicit
assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_FFFF_FFFF_FFFF);
- assert(strtod("0xFFFFFFFFFFFFF90p10", null) == x);
+ softAssert(strtod("0xFFFFFFFFFFFFF90p10", null) , x);
//61 bit mantissa, round up 2
s = "0x1F0F_FFFF_FFFF_FFFFp10";
@@ -2926,7 +2937,7 @@ unittest
assert(approxEqual(x, 0x1F0F_FFFF_FFFF_FFFFp10));
//1 bit is implicit
assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_1000_0000_0000);
- assert(strtod("0x1F0FFFFFFFFFFFFFp10", null) == x);
+ softAssert(strtod("0x1F0FFFFFFFFFFFFFp10", null) , x);
//61 bit mantissa, round down 2
s = "0x1F0F_FFFF_FFFF_FF10p10";
@@ -2934,17 +2945,17 @@ unittest
assert(approxEqual(x, 0x1F0F_FFFF_FFFF_FF10p10));
//1 bit is implicit
assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_0FFF_FFFF_FFFF);
- assert(strtod("0x1F0FFFFFFFFFFF10p10", null) == x);
+ softAssert(strtod("0x1F0FFFFFFFFFFF10p10", null) , x);
//Huge exponent
s = "0x1F_FFFF_FFFF_FFFFp900";
x = parse!real(s);
- assert(strtod("0x1FFFFFFFFFFFFFp900", null) == x);
+ softAssert(strtod("0x1FFFFFFFFFFFFFp900", null) , x);
//exponent too big -> converror
s = "";
assertThrown!ConvException(x = parse!real(s));
- assert(strtod("0x1FFFFFFFFFFFFFp1024", null) == real.infinity);
+ softAssert(strtod("0x1FFFFFFFFFFFFFp1024", null) , real.infinity);
//-exponent too big -> 0
s = "0x1FFFFFFFFFFFFFp-2000";
@@ -3005,7 +3016,8 @@ unittest
ld1 = strtold(s.ptr, null);
x1 = *cast(longdouble *)&ld1;
- assert(x1 == x && ld1 == ld);
+ softAssert(x1 , x);
+ softAssert(ld1 , ld);
// for (i = 4; i >= 0; i--)
// {
diff --git a/std/file.d b/std/file.d
index cf2b1702..89c4d819 100644
--- a/std/file.d
+++ b/std/file.d
@@ -2387,9 +2387,17 @@ else version (Solaris) string getcwd()
}
else version (Posix) string getcwd()
{
+ version(CRuntime_Bionic)
+ { // Bionic before 4.2 doesn't take null and 0 as arguments to
+ // getcwd.
+ char[4096] pathBuffer;
+ auto p = cenforce(core.sys.posix.unistd.getcwd(pathBuffer.ptr, pathBuffer.length),
+ "cannot get cwd");
+ } else {
auto p = cenforce(core.sys.posix.unistd.getcwd(null, 0),
"cannot get cwd");
scope(exit) core.stdc.stdlib.free(p);
+ }
return p[0 .. core.stdc.string.strlen(p)].idup;
}
@@ -2494,11 +2502,17 @@ else version (NetBSD)
@safe unittest
{
- auto path = thisExePath();
+ bool got_exe = true;
+ string path;
+ try path = thisExePath(); // Fails on some devices when called
+ catch (Exception e) // from an apk, ie a shared library
+ got_exe = false;
+ if(got_exe) {
assert(path.exists);
assert(path.isAbsolute);
assert(path.isFile);
+ }
}
version(StdDdoc)
@@ -3925,6 +3939,8 @@ string tempDir() @trusted
{
// Don't check for a global temporary directory as
// Android doesn't have one.
+ version(apk)
+ cache = "/data/data/com.example.native_activity/files";
}
else version(Posix)
{
diff --git a/std/stdio.d b/std/stdio.d
index 062f3767..7dfc64ae 100644
--- a/std/stdio.d
+++ b/std/stdio.d
@@ -307,6 +307,45 @@ else version (GENERIC_IO)
void funlockfile(FILE*);
}
+ version(CRuntime_Bionic)
+ {
+ import core.stdc.wchar_ : mbstate_t;
+ import core.sys.posix.sys.types : pthread_mutex_t;
+
+ extern(C) struct wchar_io_data
+ {
+ mbstate_t wcio_mbstate_in;
+ mbstate_t wcio_mbstate_out;
+ wchar_t[1] wcio_ungetwc_buf;
+ size_t wcio_ungetwc_inbuf;
+ int wcio_mode;
+ }
+
+ extern(C) struct __sfileext
+ {
+ __sbuf _ub;
+ wchar_io_data _wcio;
+ pthread_mutex_t _lock;
+ }
+
+ void bionic_lock(FILE* foo)
+ {
+ if( foo == stdout._p.handle || foo == stdin._p.handle || foo == stderr._p.handle)
+ {
+ auto ext = cast(__sfileext*) foo._ext._base;
+ if (ext._lock.value == 0)
+ {
+ // A bionic regression in Android 5.0 leaves
+ // the mutex for stdout/err/in uninitialized,
+ // so check for that and initialize it.
+ printf("lock is zero, initializing...\n");
+ ext._lock.value = 0x4000;
+ }
+ }
+ flockfile(foo);
+ }
+ }
+
int fputc_unlocked(int c, _iobuf* fp) { return fputc(c, cast(shared) fp); }
int fputwc_unlocked(wchar_t c, _iobuf* fp)
{
@@ -325,7 +364,10 @@ else version (GENERIC_IO)
alias FGETC = fgetc_unlocked;
alias FGETWC = fgetwc_unlocked;
- alias FLOCK = flockfile;
+ version(CRuntime_Bionic)
+ alias FLOCK = bionic_lock;
+ else
+ alias FLOCK = flockfile;
alias FUNLOCK = funlockfile;
}
else
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment