Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  bug-1706949-wasi-workaround.diff   Sprache: unbekannt

 
# Handle WASI lack of support for <thread> and <atomic>.
#
# WASI issue: https://github.com/WebAssembly/wasi-sdk/issues/180

diff --git a/intl/icu/source/common/putilimp.h b/intl/icu/source/common/putilimp.h
index 5b95a68..7097232 100644
--- a/intl/icu/source/common/putilimp.h
+++ b/intl/icu/source/common/putilimp.h
@@ -105,10 +105,12 @@ typedef size_t uintptr_t;
 #endif
 #elif U_PLATFORM == U_PF_OS400
    /* not defined */
 #elif U_PLATFORM == U_PF_HAIKU
    /* not defined */
+#elif defined(__wasi__)
+   /* not defined */
 #else
 #   define U_TZSET tzset
 #endif
 
 #if defined(U_TIMEZONE) || defined(U_HAVE_TIMEZONE)
@@ -130,10 +132,12 @@ typedef size_t uintptr_t;
    /* not defined */
 #elif U_PLATFORM == U_PF_OS400
    /* not defined */
 #elif U_PLATFORM == U_PF_IPHONE
    /* not defined */
+#elif defined(__wasi__)
+   /* not defined */
 #else
 #   define U_TIMEZONE timezone
 #endif
 
 #if defined(U_TZNAME) || defined(U_HAVE_TZNAME)
@@ -145,10 +149,12 @@ typedef size_t uintptr_t;
 #endif
 #elif U_PLATFORM == U_PF_OS400
    /* not defined */
 #elif U_PLATFORM == U_PF_HAIKU
     /* not defined, (well it is but a loop back to icu) */
+#elif defined(__wasi__)
+   /* not defined */
 #else
 #   define U_TZNAME tzname
 #endif
 
 #ifdef U_HAVE_MMAP
diff --git a/intl/icu/source/common/umapfile.h b/intl/icu/source/common/umapfile.h
index 92bd567..4ed1112 100644
--- a/intl/icu/source/common/umapfile.h
+++ b/intl/icu/source/common/umapfile.h
@@ -38,10 +38,12 @@ U_CFUNC void  uprv_unmapFile(UDataMemory *pData);
 #define MAP_POSIX       2
 #define MAP_STDIO       3
 
 #if UCONFIG_NO_FILE_IO
 #   define MAP_IMPLEMENTATION MAP_NONE
+#elif defined(__wasi__)
+#   define MAP_IMPLEMENTATION MAP_STDIO
 #elif U_PLATFORM_USES_ONLY_WIN32_API
 #   define MAP_IMPLEMENTATION MAP_WIN32
 #elif U_HAVE_MMAP || U_PLATFORM == U_PF_OS390
 #   define MAP_IMPLEMENTATION MAP_POSIX
 #else /* unknown platform, no memory map implementation: use stdio.h and uprv_malloc() instead */
diff --git a/intl/icu/source/common/umutex.cpp b/intl/icu/source/common/umutex.cpp
index ccbee99..6c3452c 100644
--- a/intl/icu/source/common/umutex.cpp
+++ b/intl/icu/source/common/umutex.cpp
@@ -43,6 +43,7 @@ U_NAMESPACE_BEGIN
  *
  *************************************************************************************************/
 
+#ifndef __wasi__
 namespace {
 std::mutex *initMutex;
 std::condition_variable *initCondition;
@@ -55,9 +56,11 @@ std::once_flag initFlag;
 std::once_flag *pInitFlag = &initFlag;
 
 }  // Anonymous namespace
+#endif
 
 U_CDECL_BEGIN
 static UBool U_CALLCONV umtx_cleanup() {
+#ifndef __wasi__
     initMutex->~mutex();
     initCondition->~condition_variable();
     UMutex::cleanup();
@@ -66,17 +69,21 @@ static UBool U_CALLCONV umtx_cleanup() {
     // Do not use this trick anywhere else in ICU; use umtx_initOnce, not std::call_once().
     pInitFlag->~once_flag();
     pInitFlag = new(&initFlag) std::once_flag();
+#endif
     return true;
 }
 
 static void U_CALLCONV umtx_init() {
+#ifndef __wasi__
     initMutex = STATIC_NEW(std::mutex);
     initCondition = STATIC_NEW(std::condition_variable);
     ucln_common_registerCleanup(UCLN_COMMON_MUTEX, umtx_cleanup);
+#endif
 }
 U_CDECL_END
 
 
+#ifndef __wasi__
 std::mutex *UMutex::getMutex() {
     std::mutex *retPtr = fMutex.load(std::memory_order_acquire);
     if (retPtr == nullptr) {
@@ -93,14 +100,17 @@ std::mutex *UMutex::getMutex() {
     U_ASSERT(retPtr != nullptr);
     return retPtr;
 }
+#endif
 
 UMutex *UMutex::gListHead = nullptr;
 
 void UMutex::cleanup() {
     UMutex *next = nullptr;
     for (UMutex *m = gListHead; m != nullptr; m = next) {
+#ifndef __wasi__
         (*m->fMutex).~mutex();
         m->fMutex = nullptr;
+#endif
         next = m->fListLink;
         m->fListLink = nullptr;
     }
@@ -110,20 +120,24 @@ void UMutex::cleanup() {
 
 U_CAPI void  U_EXPORT2
 umtx_lock(UMutex *mutex) {
+#ifndef __wasi__
     if (mutex == nullptr) {
         mutex = &globalMutex;
     }
     mutex->lock();
+#endif
 }
 
 
 U_CAPI void  U_EXPORT2
 umtx_unlock(UMutex* mutex)
 {
+#ifndef __wasi__
     if (mutex == nullptr) {
         mutex = &globalMutex;
     }
     mutex->unlock();
+#endif
 }
 
 
@@ -143,18 +157,22 @@ umtx_unlock(UMutex* mutex)
 //
 U_COMMON_API UBool U_EXPORT2
 umtx_initImplPreInit(UInitOnce &uio) {
+#ifndef __wasi__
     std::call_once(*pInitFlag, umtx_init);
     std::unique_lock<std::mutex> lock(*initMutex);
+#endif
     if (umtx_loadAcquire(uio.fState) == 0) {
         umtx_storeRelease(uio.fState, 1);
         return true;      // Caller will next call the init function.
     } else {
+#ifndef __wasi__
         while (umtx_loadAcquire(uio.fState) == 1) {
             // Another thread is currently running the initialization.
             // Wait until it completes.
             initCondition->wait(lock);
         }
         U_ASSERT(uio.fState == 2);
+#endif
         return false;
     }
 }
@@ -168,11 +186,13 @@ umtx_initImplPreInit(UInitOnce &uio) {
 
 U_COMMON_API void U_EXPORT2
 umtx_initImplPostInit(UInitOnce &uio) {
+#ifndef __wasi__
     {
         std::unique_lock<std::mutex> lock(*initMutex);
         umtx_storeRelease(uio.fState, 2);
     }
     initCondition->notify_all();
+#endif
 }
 
 U_NAMESPACE_END
diff --git a/intl/icu/source/common/umutex.h b/intl/icu/source/common/umutex.h
index 8d76b3f..c1a58db 100644
--- a/intl/icu/source/common/umutex.h
+++ b/intl/icu/source/common/umutex.h
@@ -20,9 +20,12 @@
 #ifndef UMUTEX_H
 #define UMUTEX_H
 
+#ifndef __wasi__
 #include <atomic>
 #include <condition_variable>
 #include <mutex>
+#endif
+
 #include <type_traits>
 
 #include "unicode/utypes.h"
@@ -37,6 +40,8 @@
 #error U_USER_ATOMICS and U_USER_MUTEX_H are not supported
 #endif
 
+#ifndef __wasi__
+
 // Export an explicit template instantiation of std::atomic<int32_t>. 
 // When building DLLs for Windows this is required as it is used as a data member of the exported SharedObject class.
 // See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.
@@ -61,6 +66,7 @@ template struct std::atomic<std::mutex *>;
 #endif
 #endif
 
+#endif
 
 U_NAMESPACE_BEGIN
 
@@ -68,10 +68,12 @@ U_NAMESPACE_BEGIN
  *
  *   Low Level Atomic Operations, ICU wrappers for.
  *
  ****************************************************************************/
 
+#ifndef __wasi__
+
 typedef std::atomic<int32_t> u_atomic_int32_t;
 
 inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) {
     return var.load(std::memory_order_acquire);
 }
@@ -86,10 +88,31 @@ inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) {
 
 inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
     return var->fetch_sub(1) - 1;
 }
 
+#else
+
+typedef int32_t u_atomic_int32_t;
+
+inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) {
+    return var;
+}
+
+inline void umtx_storeRelease(u_atomic_int32_t &var, int32_t val) {
+    var = val;
+}
+
+inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) {
+    return ++(*var);
+}
+
+inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
+    return --(*var);
+}
+
+#endif
 
 /*************************************************************************************************
  *
  *  UInitOnce Definitions.
  *
@@ -225,21 +248,29 @@ class U_COMMON_API UMutex {
     UMutex &operator =(const UMutex &other) = delete;
     void *operator new(size_t) = delete;
 
     // requirements for C++ BasicLockable, allows UMutex to work with std::lock_guard
     void lock() {
+#ifndef __wasi__
         std::mutex *m = fMutex.load(std::memory_order_acquire);
         if (m == nullptr) { m = getMutex(); }
         m->lock();
+#endif
+    }
+    void unlock() {
+#ifndef __wasi__
+        fMutex.load(std::memory_order_relaxed)->unlock();
+#endif
     }
-    void unlock() { fMutex.load(std::memory_order_relaxed)->unlock(); }
 
     static void cleanup();
 
 private:
+#ifndef __wasi__
     alignas(std::mutex) char fStorage[sizeof(std::mutex)] {};
     std::atomic<std::mutex *> fMutex { nullptr };
+#endif
 
     /** All initialized UMutexes are kept in a linked list, so that they can be found,
      * and the underlying std::mutex destructed, by u_cleanup().
      */
     UMutex *fListLink { nullptr };
@@ -247,11 +278,13 @@ class U_COMMON_API UMutex {
 
     /** Out-of-line function to lazily initialize a UMutex on first use.
      * Initial fast check is inline, in lock().  The returned value may never
      * be nullptr.
      */
+#ifndef __wasi__
     std::mutex *getMutex();
+#endif
 };
 
 
 /* Lock a mutex.
  * @param mutex The given mutex to be locked.  Pass NULL to specify

diff --git a/intl/icu/source/common/unifiedcache.cpp b/intl/icu/source/common/unifiedcache.cpp
--- a/intl/icu/source/common/unifiedcache.cpp
+++ b/intl/icu/source/common/unifiedcache.cpp
@@ -11,19 +11,23 @@
 */
 
 #include "unifiedcache.h"
 
 #include <algorithm>      // For std::max()
-#include <mutex>
+#ifndef __wasi__
+ #include <mutex>
+#endif
 
 #include "uassert.h"
 #include "uhash.h"
 #include "ucln_cmn.h"
 
 static icu::UnifiedCache *gCache = nullptr;
+#ifndef __wasi__
 static std::mutex *gCacheMutex = nullptr;
 static std::condition_variable *gInProgressValueAddedCond;
+#endif
 static icu::UInitOnce gCacheInitOnce {};
 
 static const int32_t MAX_EVICT_ITERATIONS = 10;
 static const int32_t DEFAULT_MAX_UNUSED = 1000;
 static const int32_t DEFAULT_PERCENTAGE_OF_IN_USE = 100;
@@ -32,14 +36,16 @@ static const int32_t DEFAULT_PERCENTAGE_OF_IN_USE = 100;
 U_CDECL_BEGIN
 static UBool U_CALLCONV unifiedcache_cleanup() {
     gCacheInitOnce.reset();
     delete gCache;
     gCache = nullptr;
+#ifndef __wasi__
     gCacheMutex->~mutex();
     gCacheMutex = nullptr;
     gInProgressValueAddedCond->~condition_variable();
     gInProgressValueAddedCond = nullptr;
+#endif
     return true;
 }
 U_CDECL_END
 
 
@@ -70,12 +76,14 @@ CacheKeyBase::~CacheKeyBase() {
 static void U_CALLCONV cacheInit(UErrorCode &status) {
     U_ASSERT(gCache == nullptr);
     ucln_common_registerCleanup(
             UCLN_COMMON_UNIFIED_CACHE, unifiedcache_cleanup);
 
+#ifndef __wasi__
     gCacheMutex = STATIC_NEW(std::mutex);
     gInProgressValueAddedCond = STATIC_NEW(std::condition_variable);
+#endif
     gCache = new UnifiedCache(status);
     if (gCache == nullptr) {
         status = U_MEMORY_ALLOCATION_ERROR;
     }
     if (U_FAILURE(status)) {
@@ -133,41 +141,53 @@ void UnifiedCache::setEvictionPolicy(
     }
     if (count < 0 || percentageOfInUseItems < 0) {
         status = U_ILLEGAL_ARGUMENT_ERROR;
         return;
     }
+#ifndef __wasi__
     std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
     fMaxUnused = count;
     fMaxPercentageOfInUse = percentageOfInUseItems;
 }
 
 int32_t UnifiedCache::unusedCount() const {
+#ifndef __wasi__
     std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
     return uhash_count(fHashtable) - fNumValuesInUse;
 }
 
 int64_t UnifiedCache::autoEvictedCount() const {
+#ifndef __wasi__
     std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
     return fAutoEvictedCount;
 }
 
 int32_t UnifiedCache::keyCount() const {
+#ifndef __wasi__
     std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
     return uhash_count(fHashtable);
 }
 
 void UnifiedCache::flush() const {
+#ifndef __wasi__
     std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
 
     // Use a loop in case cache items that are flushed held hard references to
     // other cache items making those additional cache items eligible for
     // flushing.
     while (_flush(false));
 }
 
 void UnifiedCache::handleUnreferencedObject() const {
+#ifndef __wasi__
     std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
     --fNumValuesInUse;
     _runEvictionSlice();
 }
 
 #ifdef UNIFIED_CACHE_DEBUG
@@ -182,11 +202,13 @@ void UnifiedCache::dump() {
     }
     cache->dumpContents();
 }
 
 void UnifiedCache::dumpContents() const {
+#ifndef __wasi__
     std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
     _dumpContents();
 }
 
 // Dumps content of cache.
 // On entry, gCacheMutex must be held.
@@ -222,11 +244,13 @@ UnifiedCache::~UnifiedCache() {
     flush();
     {
         // Now all that should be left in the cache are entries that refer to
         // each other and entries with hard references from outside the cache.
         // Nothing we can do about these so proceed to wipe out the cache.
+#ifndef __wasi__
         std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
         _flush(true);
     }
     uhash_close(fHashtable);
     fHashtable = nullptr;
     delete fNoValue;
@@ -323,11 +347,13 @@ void UnifiedCache::_putNew(
 
 void UnifiedCache::_putIfAbsentAndGet(
         const CacheKeyBase &key,
         const SharedObject *&value,
         UErrorCode &status) const {
+#ifndef __wasi__
     std::lock_guard<std::mutex> lock(*gCacheMutex);
+#endif
     const UHashElement *element = uhash_find(fHashtable, &key);
     if (element != nullptr && !_inProgress(element)) {
         _fetch(element, value, status);
         return;
     }
@@ -348,18 +374,22 @@ UBool UnifiedCache::_poll(
         const CacheKeyBase &key,
         const SharedObject *&value,
         UErrorCode &status) const {
     U_ASSERT(value == nullptr);
     U_ASSERT(status == U_ZERO_ERROR);
+#ifndef __wasi__
     std::unique_lock<std::mutex> lock(*gCacheMutex);
+#endif
     const UHashElement *element = uhash_find(fHashtable, &key);
 
     // If the hash table contains an inProgress placeholder entry for this key,
     // this means that another thread is currently constructing the value object.
     // Loop, waiting for that construction to complete.
      while (element != nullptr && _inProgress(element)) {
+#ifndef __wasi__
          gInProgressValueAddedCond->wait(lock);
+#endif
          element = uhash_find(fHashtable, &key);
     }
 
     // If the hash table contains an entry for the key,
     // fetch out the contents and return them.
@@ -426,13 +456,15 @@ void UnifiedCache::_put(
     UHashElement *ptr = const_cast<UHashElement *>(element);
     ptr->value.pointer = (void *) value;
     U_ASSERT(oldValue == fNoValue);
     removeSoftRef(oldValue);
 
+#ifndef __wasi__
     // Tell waiting threads that we replace in-progress status with
     // an error.
     gInProgressValueAddedCond->notify_all();
+#endif
 }
 
 void UnifiedCache::_fetch(
         const UHashElement *element,
         const SharedObject *&value,
diff --git a/intl/icu/source/i18n/decContext.h b/intl/icu/source/i18n/decContext.h
index 59ab65e..20f3526 100644
--- a/intl/icu/source/i18n/decContext.h
+++ b/intl/icu/source/i18n/decContext.h
@@ -61,7 +61,9 @@
 /* #include <stdint.h>   */         /* C99 standard integers           */
   #endif
   #include <stdio.h>               /* for printf, etc.                */
+#ifndef __wasi__
   #include <signal.h>              /* for traps                       */
+#endif
 
   /* Extended flags setting -- set this to 0 to use only IEEE flags   */
   #if !defined(DECEXTFLAG)
diff --git a/intl/icu/source/i18n/decimfmt.cpp b/intl/icu/source/i18n/decimfmt.cpp
index daa1129..c8f1eda 100644
--- a/intl/icu/source/i18n/decimfmt.cpp
+++ b/intl/icu/source/i18n/decimfmt.cpp
@@ -480,8 +480,13 @@ DecimalFormat& DecimalFormat::operator=(const DecimalFormat&&nbsp;rhs) {
 DecimalFormat::~DecimalFormat() {
     if (fields == nullptr) { return; }
 
+#ifndef __wasi__
     delete fields->atomicParser.exchange(nullptr);
     delete fields->atomicCurrencyParser.exchange(nullptr);
+#else
+    delete fields->atomicParser;
+    delete fields->atomicCurrencyParser;
+#endif
     delete fields;
 }
 
@@ -1626,8 +1631,13 @@ void DecimalFormat::touch(UErrorCode& status) {
     setupFastFormat();
 
     // Delete the parsers if they were made previously
+#ifndef __wasi__
     delete fields->atomicParser.exchange(nullptr);
     delete fields->atomicCurrencyParser.exchange(nullptr);
+#else
+    delete fields->atomicParser;
+    delete fields->atomicCurrencyParser;
+#endif
 
     // In order for the getters to work, we need to populate some fields in NumberFormat.
     NumberFormat::setCurrency(fields->exportedProperties.currency.get(status).getISOCurrency(), status);
@@ -1662,7 +1672,11 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getParser(UErrorCode& sta
     }
 
     // First try to get the pre-computed parser
+#ifndef __wasi__
     auto* ptr = fields->atomicParser.load();
+#else
+    auto* ptr = fields->atomicParser;
+#endif
     if (ptr != nullptr) {
         return ptr;
     }
@@ -1681,6 +1695,7 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getParser(UErrorCode& sta
     // it is set to what is actually stored in the atomic
     // if another thread beat us to computing the parser object.
     auto* nonConstThis = const_cast<DecimalFormat*>(this);
+#ifndef __wasi__
     if (!nonConstThis->fields->atomicParser.compare_exchange_strong(ptr, temp)) {
         // Another thread beat us to computing the parser
         delete temp;
@@ -1689,13 +1704,21 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getParser(UErrorCode& sta
         // Our copy of the parser got stored in the atomic
         return temp;
     }
+#else
+    nonConstThis->fields->atomicParser = temp;
+    return temp;
+#endif
 }
 
 const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorCode& status) const {
     if (U_FAILURE(status)) { return nullptr; }
 
     // First try to get the pre-computed parser
+#ifndef __wasi__
     auto* ptr = fields->atomicCurrencyParser.load();
+#else
+    auto* ptr = fields->atomicCurrencyParser;
+#endif
     if (ptr != nullptr) {
         return ptr;
     }
@@ -1710,6 +1733,7 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorC
     // Note: ptr starts as nullptr; during compare_exchange, it is set to what is actually stored in the
     // atomic if another thread beat us to computing the parser object.
     auto* nonConstThis = const_cast<DecimalFormat*>(this);
+#ifndef __wasi__
     if (!nonConstThis->fields->atomicCurrencyParser.compare_exchange_strong(ptr, temp)) {
         // Another thread beat us to computing the parser
         delete temp;
@@ -1718,6 +1742,10 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorC
         // Our copy of the parser got stored in the atomic
         return temp;
     }
+#else
+    nonConstThis->fields->atomicCurrencyParser = temp;
+    return temp;
+#endif
 }
 
 void
diff --git a/intl/icu/source/i18n/number_mapper.h b/intl/icu/source/i18n/number_mapper.h
index 9ecd776..d094289 100644
--- a/intl/icu/source/i18n/number_mapper.h
+++ b/intl/icu/source/i18n/number_mapper.h
@@ -7,7 +7,6 @@
 #ifndef __NUMBER_MAPPER_H__
 #define __NUMBER_MAPPER_H__
 
-#include <atomic>
 #include "number_types.h"
 #include "unicode/currpinf.h"
 #include "standardplural.h"
@@ -15,6 +14,10 @@
 #include "number_currencysymbols.h"
 #include "numparse_impl.h"
 
+#ifndef __wasi__
+#include <atomic>
+#endif
+
 U_NAMESPACE_BEGIN
 namespace number {
 namespace impl {
@@ -193,10 +196,18 @@ struct DecimalFormatFields : public UMemory {
     LocalizedNumberFormatter formatter;
 
     /** The lazy-computed parser for .parse() */
+#ifndef __wasi__
     std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {};
+#else
+    ::icu::numparse::impl::NumberParserImpl* atomicParser = nullptr;
+#endif
 
     /** The lazy-computed parser for .parseCurrency() */
+#ifndef __wasi__
     std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicCurrencyParser = {};
+#else
+    ::icu::numparse::impl::NumberParserImpl* atomicCurrencyParser = {};
+#endif
 
     /** Small object ownership warehouse for the formatter and parser */
     DecimalFormatWarehouse warehouse;
diff --git a/intl/icu/source/i18n/numrange_fluent.cpp b/intl/icu/source/i18n/numrange_fluent.cpp
--- a/intl/icu/source/i18n/numrange_fluent.cpp
+++ b/intl/icu/source/i18n/numrange_fluent.cpp
@@ -246,33 +246,53 @@ LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(LocalizedNumberRang
 
 LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(NFS<LNF>&& src) noexcept
         : NFS<LNF>(std::move(src)) {
     // Steal the compiled formatter
     LNF&& _src = static_cast<LNF&&>(src);
+#ifndef __wasi__
     auto* stolen = _src.fAtomicFormatter.exchange(nullptr);
     delete fAtomicFormatter.exchange(stolen);
+#else
+    delete fAtomicFormatter;
+    fAtomicFormatter = _src.fAtomicFormatter;
+    _src.fAtomicFormatter = nullptr;
+#endif
 }
 
 LocalizedNumberRangeFormatter& LocalizedNumberRangeFormatter::operator=(const LNF& other) {
     if (this == &other) { return *this; }  // self-assignment: no-op
     NFS<LNF>::operator=(static_cast<const NFS<LNF>&>(other));
     // Do not steal; just clear
+#ifndef __wasi__
     delete fAtomicFormatter.exchange(nullptr);
+#else
+    delete fAtomicFormatter;
+#endif
     return *this;
 }
 
 LocalizedNumberRangeFormatter& LocalizedNumberRangeFormatter::operator=(LNF&& src) noexcept {
     NFS<LNF>::operator=(static_cast<NFS<LNF>&&>(src));
     // Steal the compiled formatter
+#ifndef __wasi__
     auto* stolen = src.fAtomicFormatter.exchange(nullptr);
     delete fAtomicFormatter.exchange(stolen);
+#else
+    delete fAtomicFormatter;
+    fAtomicFormatter = src.fAtomicFormatter;
+    src.fAtomicFormatter = nullptr;
+#endif
     return *this;
 }
 
 
 LocalizedNumberRangeFormatter::~LocalizedNumberRangeFormatter() {
+#ifndef __wasi__
     delete fAtomicFormatter.exchange(nullptr);
+#else
+    delete fAtomicFormatter;
+#endif
 }
 
 LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(const RangeMacroProps& macros, const Locale& locale) {
     fMacros = macros;
     fMacros.locale = locale;
@@ -363,11 +383,15 @@ LocalizedNumberRangeFormatter::getFormatter(UErrorCode& status) const {
     if (U_FAILURE(status)) {
         return nullptr;
     }
 
     // First try to get the pre-computed formatter
+#ifndef __wasi__
     auto* ptr = fAtomicFormatter.load();
+#else
+    auto* ptr = fAtomicFormatter;
+#endif
     if (ptr != nullptr) {
         return ptr;
     }
 
     // Try computing the formatter on our own
@@ -378,17 +378,22 @@ LocalizedNumberRangeFormatter::getFormatter(UErrorCode& status) const {
 
     // Note: ptr starts as nullptr; during compare_exchange,
     // it is set to what is actually stored in the atomic
     // if another thread beat us to computing the formatter object.
     auto* nonConstThis = const_cast<LocalizedNumberRangeFormatter*>(this);
+#ifndef __wasi__
     if (!nonConstThis->fAtomicFormatter.compare_exchange_strong(ptr, temp.getAlias())) {
         // Another thread beat us to computing the formatter
         return ptr;
     } else {
         // Our copy of the formatter got stored in the atomic
         return temp.orphan();
     }
+#else
+    nonConstThis->fAtomicFormatter = temp.getAlias();
+    return temp.orphan();
+#endif
 
 }
 
 
 #endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/intl/icu/source/i18n/unicode/numberrangeformatter.h b/intl/icu/source/i18n/unicode/numberrangeformatter.h
index b9a4600..0ba2fa0 100644
--- a/intl/icu/source/i18n/unicode/numberrangeformatter.h
+++ b/intl/icu/source/i18n/unicode/numberrangeformatter.h
@@ -10,7 +10,6 @@
 
 #if !UCONFIG_NO_FORMATTING
 
-#include <atomic>
 #include "unicode/appendable.h"
 #include "unicode/fieldpos.h"
 #include "unicode/formattedvalue.h"
@@ -18,6 +17,10 @@
 #include "unicode/numberformatter.h"
 #include "unicode/unumberrangeformatter.h"
 
+#ifndef __wasi__
+#include <atomic>
+#endif
+
 /**
  * \file
  * \brief C++ API: Library for localized formatting of number, currency, and unit ranges.
@@ -77,7 +80,9 @@ struct UFormattedNumberRangeImpl;
 } // namespace icu::number
 U_NAMESPACE_END
 
+#ifndef __wasi__
 template struct U_I18N_API std::atomic< U_NAMESPACE_QUALIFIER number::impl::NumberRangeFormatterImpl*>;
+#endif
 
 U_NAMESPACE_BEGIN
 namespace number {  // icu::number
@@ -546,7 +551,11 @@ class U_I18N_API LocalizedNumberRangeFormatter
     ~LocalizedNumberRangeFormatter();
 
   private:
+#ifndef __wasi__
     std::atomic<impl::NumberRangeFormatterImpl*> fAtomicFormatter = {};
+#else
+    impl::NumberRangeFormatterImpl* fAtomicFormatter = nullptr;
+#endif
 
     const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const;
 

[ Dauer der Verarbeitung: 0.26 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge