From fc2f021bdd3fd69ff62bfc6ceb5c5264afd4ee7d Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Fri, 29 Mar 2013 18:27:28 +0000 Subject: [PATCH] Bruce Mitchener, Jr.: Port to emscripten. Fixes http://llvm.org/bugs/show_bug.cgi?id=15624. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@178354 91177308-0d34-0410-b5e6-96231b3b80d8 --- CREDITS.TXT | 4 ++++ include/__locale | 12 +++++++----- include/locale | 2 +- src/exception.cpp | 4 +++- src/locale.cpp | 38 ++++++++++++++++++++++++++++++-------- src/thread.cpp | 2 +- 6 files changed, 46 insertions(+), 16 deletions(-) diff --git a/CREDITS.TXT b/CREDITS.TXT index 529485108..c34e21911 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -89,3 +89,7 @@ N: Jeffrey Yasskin 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 15102be2e..24d565b69 100644 --- a/include/__locale +++ b/include/__locale @@ -21,9 +21,9 @@ #include #ifdef _WIN32 # include -#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)) +#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)) || defined(EMSCRIPTEN) # include -#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 @@ public: 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 @@ public: 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 @@ public: #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 1c7156c80..05020e17d 100644 --- a/include/locale +++ b/include/locale @@ -222,7 +222,7 @@ typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; // 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())) diff --git a/src/exception.cpp b/src/exception.cpp index 7db304d8c..1d2f6b259 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -77,6 +77,7 @@ get_terminate() _NOEXCEPT 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 @@ terminate() _NOEXCEPT } #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 90bc77c92..c459bede0 100644 --- a/src/locale.cpp +++ b/src/locale.cpp @@ -786,7 +786,7 @@ ctype::do_toupper(char_type c) const { #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; -#elif defined(__GLIBC__) +#elif defined(__GLIBC__) || defined(EMSCRIPTEN) return isascii(c) ? ctype::__classic_upper_table()[c] : c; #else return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c; @@ -799,7 +799,7 @@ ctype::do_toupper(char_type* low, const char_type* high) const 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::__classic_upper_table()[*low] : *low; #else @@ -813,7 +813,7 @@ ctype::do_tolower(char_type c) const { #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; -#elif defined(__GLIBC__) +#elif defined(__GLIBC__) || defined(EMSCRIPTEN) return isascii(c) ? ctype::__classic_lower_table()[c] : c; #else return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c; @@ -826,7 +826,7 @@ ctype::do_tolower(char_type* low, const char_type* high) const 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::__classic_lower_table()[*low] : *low; #else @@ -893,7 +893,7 @@ ctype::do_toupper(char_type c) const #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE return isascii(c) ? static_cast(_DefaultRuneLocale.__mapupper[static_cast(c)]) : c; -#elif defined(__GLIBC__) +#elif defined(__GLIBC__) || defined(EMSCRIPTEN) return isascii(c) ? static_cast(__classic_upper_table()[static_cast(c)]) : c; #else @@ -908,7 +908,7 @@ ctype::do_toupper(char_type* low, const char_type* high) const #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE *low = isascii(*low) ? static_cast(_DefaultRuneLocale.__mapupper[static_cast(*low)]) : *low; -#elif defined(__GLIBC__) +#elif defined(__GLIBC__) || defined(EMSCRIPTEN) *low = isascii(*low) ? static_cast(__classic_upper_table()[static_cast(*low)]) : *low; #else @@ -923,7 +923,7 @@ ctype::do_tolower(char_type c) const #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE return isascii(c) ? static_cast(_DefaultRuneLocale.__maplower[static_cast(c)]) : c; -#elif defined(__GLIBC__) +#elif defined(__GLIBC__) || defined(EMSCRIPTEN) return isascii(c) ? static_cast(__classic_lower_table()[static_cast(c)]) : c; #else @@ -937,7 +937,7 @@ ctype::do_tolower(char_type* low, const char_type* high) const for (; low != high; ++low) #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE *low = isascii(*low) ? static_cast(_DefaultRuneLocale.__maplower[static_cast(*low)]) : *low; -#elif defined(__GLIBC__) +#elif defined(__GLIBC__) || defined(EMSCRIPTEN) *low = isascii(*low) ? static_cast(__classic_lower_table()[static_cast(*low)]) : *low; #else *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low; @@ -978,6 +978,12 @@ ctype::do_narrow(const char_type* low, const char_type* high, char dfault, 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::mask* ctype::classic_table() _NOEXCEPT { @@ -991,6 +997,8 @@ ctype::classic_table() _NOEXCEPT 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 @@ ctype::__classic_upper_table() _NOEXCEPT } #endif // __GLIBC__ +#if defined(EMSCRIPTEN) +const int* +ctype::__classic_lower_table() _NOEXCEPT +{ + return *__ctype_tolower_loc(); +} + +const int* +ctype::__classic_upper_table() _NOEXCEPT +{ + return *__ctype_toupper_loc(); +} +#endif // EMSCRIPTEN + // template <> class ctype_byname ctype_byname::ctype_byname(const char* name, size_t refs) diff --git a/src/thread.cpp b/src/thread.cpp index 635500292..c6f6748f0 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -67,7 +67,7 @@ thread::hardware_concurrency() _NOEXCEPT 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.