Bruce Mitchener, Jr.: Port to emscripten. Fixes http://llvm.org/bugs/show_bug.cgi?id=15624.
llvm-svn: 178354
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 9cb970074fb76f3507b0b97ef371308f3c384042
diff --git a/CREDITS.TXT b/CREDITS.TXT
index 5294851..c34e219 100644
--- a/CREDITS.TXT
+++ b/CREDITS.TXT
@@ -89,3 +89,7 @@
E: jyasskin@gmail.com
E: jyasskin@google.com
D: Linux fixes.
+
+N: Bruce Mitchener, Jr.
+E: bruce.mitchener@gmail.com
+D: Emscripten-related changes.
diff --git a/include/__locale b/include/__locale
index 15102be..24d565b 100644
--- a/include/__locale
+++ b/include/__locale
@@ -21,9 +21,9 @@
#include <locale.h>
#ifdef _WIN32
# include <support/win32/locale_win32.h>
-#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__))
+#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)) || defined(EMSCRIPTEN)
# include <xlocale.h>
-#endif // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD_
+#endif // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || EMSCRIPTEN
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -339,11 +339,13 @@
static const mask punct = _PUNCT;
static const mask xdigit = _HEX;
static const mask blank = _BLANK;
-#elif (defined(__APPLE__) || defined(__FreeBSD__))
+#elif (defined(__APPLE__) || defined(__FreeBSD__)) || defined(EMSCRIPTEN)
#ifdef __APPLE__
typedef __uint32_t mask;
#elif defined(__FreeBSD__)
typedef unsigned long mask;
+#elif defined(EMSCRIPTEN)
+ typedef unsigned short mask;
#endif
static const mask space = _CTYPE_S;
static const mask print = _CTYPE_R;
@@ -367,7 +369,7 @@
static const mask punct = _ISPUNCT;
static const mask xdigit = _ISXDIGIT;
static const mask blank = _ISBLANK;
-#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __sun__
+#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || EMSCRIPTEN || __sun__
typedef unsigned long mask;
static const mask space = 1<<0;
static const mask print = 1<<1;
@@ -590,7 +592,7 @@
#endif
_LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
static const mask* classic_table() _NOEXCEPT;
-#if defined(__GLIBC__)
+#if defined(__GLIBC__) || defined(EMSCRIPTEN)
static const int* __classic_upper_table() _NOEXCEPT;
static const int* __classic_lower_table() _NOEXCEPT;
#endif
diff --git a/include/locale b/include/locale
index 1c7156c..05020e1 100644
--- a/include/locale
+++ b/include/locale
@@ -222,7 +222,7 @@
// OSX has nice foo_l() functions that let you turn off use of the global
// locale. Linux, not so much. The following functions avoid the locale when
// that's possible and otherwise do the wrong thing. FIXME.
-#ifdef __linux__
+#if defined(__linux__) || defined(EMSCRIPTEN)
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
diff --git a/src/exception.cpp b/src/exception.cpp
index 7db304d..1d2f6b2 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -77,6 +77,7 @@
return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
}
+#ifndef EMSCRIPTEN // We provide this in JS
_LIBCPP_NORETURN
void
terminate() _NOEXCEPT
@@ -97,9 +98,10 @@
}
#endif // _LIBCPP_NO_EXCEPTIONS
}
+#endif // !EMSCRIPTEN
#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
-#if !defined(LIBCXXRT) && !defined(__GLIBCXX__)
+#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(EMSCRIPTEN)
bool uncaught_exception() _NOEXCEPT
{
#if defined(__APPLE__) || defined(_LIBCPPABI_VERSION)
diff --git a/src/locale.cpp b/src/locale.cpp
index 90bc77c..c459bed 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -786,7 +786,7 @@
{
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
#else
return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
@@ -799,7 +799,7 @@
for (; low != high; ++low)
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
*low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
: *low;
#else
@@ -813,7 +813,7 @@
{
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
#else
return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
@@ -826,7 +826,7 @@
for (; low != high; ++low)
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
*low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
: *low;
#else
@@ -893,7 +893,7 @@
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ?
static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
return isascii(c) ?
static_cast<char>(__classic_upper_table()[static_cast<size_t>(c)]) : c;
#else
@@ -908,7 +908,7 @@
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ?
static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
*low = isascii(*low) ?
static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
#else
@@ -923,7 +923,7 @@
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ?
static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
return isascii(c) ?
static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
#else
@@ -937,7 +937,7 @@
for (; low != high; ++low)
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
-#elif defined(__GLIBC__)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
*low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
#else
*low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low;
@@ -978,6 +978,12 @@
return low;
}
+#ifdef EMSCRIPTEN
+extern "C" const unsigned short ** __ctype_b_loc();
+extern "C" const int ** __ctype_tolower_loc();
+extern "C" const int ** __ctype_toupper_loc();
+#endif
+
const ctype<char>::mask*
ctype<char>::classic_table() _NOEXCEPT
{
@@ -991,6 +997,8 @@
return _ctype+1; // internal ctype mask table defined in msvcrt.dll
// This is assumed to be safe, which is a nonsense assumption because we're
// going to end up dereferencing it later...
+#elif defined(EMSCRIPTEN)
+ return *__ctype_b_loc();
#else
// Platform not supported: abort so the person doing the port knows what to
// fix
@@ -1014,6 +1022,20 @@
}
#endif // __GLIBC__
+#if defined(EMSCRIPTEN)
+const int*
+ctype<char>::__classic_lower_table() _NOEXCEPT
+{
+ return *__ctype_tolower_loc();
+}
+
+const int*
+ctype<char>::__classic_upper_table() _NOEXCEPT
+{
+ return *__ctype_toupper_loc();
+}
+#endif // EMSCRIPTEN
+
// template <> class ctype_byname<char>
ctype_byname<char>::ctype_byname(const char* name, size_t refs)
diff --git a/src/thread.cpp b/src/thread.cpp
index 6355002..c6f6748 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -67,7 +67,7 @@
std::size_t s = sizeof(n);
sysctl(mib, 2, &n, &s, 0, 0);
return n;
-#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && defined(_SC_NPROCESSORS_ONLN)
+#elif (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && defined(_SC_NPROCESSORS_ONLN)) || defined(EMSCRIPTEN)
long result = sysconf(_SC_NPROCESSORS_ONLN);
// sysconf returns -1 if the name is invalid, the option does not exist or
// does not have a definite limit.