Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e7af49c
Don't copy llvm-libc headers in update_libcxx.py
aheejin Jul 18, 2026
5a8c446
Update libcxx from LLVM 21.1.8 to 22.1.8
aheejin Jul 18, 2026
8e1099b
Add new files to libcxx
aheejin Jul 18, 2026
adda6ed
Update libcxxabi from LLVM 21.1.8 to 22.1.8
aheejin Jul 18, 2026
b119c87
Define _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
aheejin Jul 3, 2026
eb90d7d
Add copy_file_range syscall stub
aheejin Jul 28, 2026
638d0e1
Make __cxa_thread_atexit available for Emscripten
aheejin Jul 28, 2026
86d64e4
ChangeLog
aheejin Jul 28, 2026
f29828c
Automatic rebaseline of codesize expectations. NFC
aheejin Jul 28, 2026
c7d4b0b
Fix incorrect signature for copy_file_range
aheejin Jul 28, 2026
f46ce47
Merge branch 'main' into update_libcxx_libcxxabi_22
aheejin Jul 28, 2026
c818aa2
Increase size expectations of test_malloc_size*
aheejin Jul 28, 2026
e81407b
Don't copy llvm-libc's LICENSE.txt
aheejin Jul 28, 2026
be1f0a7
Create module.modulemap from module.modulemap.in
aheejin Jul 28, 2026
c3d7df5
Automatic rebaseline of codesize expectations. NFC
aheejin Jul 28, 2026
547432f
Copy default_assertion_handler.in to __assertion_handler
aheejin Jul 28, 2026
dfe69d6
ruff fix
aheejin Jul 28, 2026
f90f0a4
Merge branch 'main' into update_libcxx_libcxxabi_22
aheejin Jul 28, 2026
7d7f510
Merge branch 'main' into update_libcxx_libcxxabi_22
aheejin Jul 28, 2026
9c131aa
Automatic rebaseline of codesize expectations. NFC
aheejin Jul 28, 2026
95f5110
Revert "Fix incorrect signature for copy_file_range"
aheejin Jul 29, 2026
1e57e6f
Revert "Add copy_file_range syscall stub"
aheejin Jul 29, 2026
e9f7296
Undefine _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
aheejin Jul 29, 2026
7abedc5
Merge branch 'main' into update_libcxx_libcxxabi_22
aheejin Jul 29, 2026
488d97c
ChangeLog conflict fix
aheejin Jul 29, 2026
4662a00
Automatic rebaseline of codesize expectations. NFC
aheejin Jul 29, 2026
fb14792
Merge branch 'main' into update_libcxx_libcxxabi_22
aheejin Jul 29, 2026
27e6a55
ChangeLog conflict fix
aheejin Jul 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions src/lib/libsigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ sigs = {
__syscall_epoll_create1__sig: 'ii',
__syscall_epoll_ctl__sig: 'iiiip',
__syscall_epoll_pwait__sig: 'iipiipp',
__syscall_copy_file_range__sig: 'iipipii',
__syscall_faccessat__sig: 'iipii',
__syscall_fadvise64__sig: 'iijji',
__syscall_fallocate__sig: 'iiijj',
Expand Down
2 changes: 2 additions & 0 deletions src/lib/libsyscall.js
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,8 @@ var SyscallsLibrary = {
__syscall_epoll_ctl: (epfd, op, fd, ev) => -{{{ cDefs.ENOSYS }}},
__syscall_epoll_pwait__nothrow: true,
__syscall_epoll_pwait: (epfd, ev, maxevents, timeout, sigmask, sigsetsize) => -{{{ cDefs.ENOSYS }}},
__syscall_copy_file_range__nothrow: true,
__syscall_copy_file_range: (fd_in, off_in, fd_out, off_out, len, flags) => -{{{ cDefs.ENOSYS }}},
__syscall_getcwd__deps: ['$lengthBytesUTF8', '$stringToUTF8'],
__syscall_getcwd: (buf, size) => {
if (size === 0) return -{{{ cDefs.EINVAL }}};
Expand Down
1 change: 1 addition & 0 deletions system/include/emscripten/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ int __syscall_shutdown(int sockfd, int how, int unused1, int unused2, int unused
int __syscall_epoll_create1(int flags);
int __syscall_epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev);
int __syscall_epoll_pwait(int epfd, struct epoll_event *ev, int maxevents, int timeout, const sigset_t *sigmask, size_t sigsetsize);
ssize_t __syscall_copy_file_range(int fd_in, off_t *off_in, int fd_out, off_t *off_out, size_t len, unsigned flags);

#ifdef __cplusplus
}
Expand Down
1 change: 1 addition & 0 deletions system/lib/libc/musl/arch/emscripten/bits/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,4 @@
#define SYS_epoll_create1 __syscall_epoll_create1
#define SYS_epoll_ctl __syscall_epoll_ctl
#define SYS_epoll_pwait __syscall_epoll_pwait
#define SYS_copy_file_range __syscall_copy_file_range
6 changes: 3 additions & 3 deletions system/lib/libcxx/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
LLVM's libcxx
-------------

These files are from the llvm-project based on release 21.1.8.
These files are from the llvm-project based on release 22.1.8.

We maintain a local fork of llvm-project that contains any Emscripten
specific patches:

https://github.com/emscripten-core/llvm-project

The current patch is based on the emscripten-libs-21 branch.
The current patch is based on the emscripten-libs-22 branch.

Update Instructions
-------------------
Expand All @@ -20,4 +20,4 @@ Modifications

For a list of changes from upstream see the libcxx files that are part of:

https://github.com/llvm/llvm-project/compare/llvmorg-21.1.8...emscripten-core:emscripten-libs-21
https://github.com/llvm/llvm-project/compare/llvmorg-22.1.8...emscripten-core:emscripten-libs-22
16 changes: 11 additions & 5 deletions system/lib/libcxx/include/__algorithm/all_of.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,28 @@
#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
#define _LIBCPP___ALGORITHM_ALL_OF_H

#include <__algorithm/any_of.h>
#include <__config>
#include <__functional/identity.h>
#include <__type_traits/invoke.h>
#include <__utility/forward.h>
#include <__utility/move.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) {
if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
return false;
}
return true;
using _Ref = decltype(std::__invoke(__proj, *__first));
auto __negated_pred = [&__pred](_Ref __arg) -> bool { return !std::__invoke(__pred, std::forward<_Ref>(__arg)); };
return !std::__any_of(std::move(__first), std::move(__last), __negated_pred, __proj);
}

template <class _InputIterator, class _Predicate>
Expand All @@ -39,4 +43,6 @@ all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___ALGORITHM_ALL_OF_H
4 changes: 4 additions & 0 deletions system/lib/libcxx/include/__algorithm/comp.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <__config>
#include <__type_traits/desugars_to.h>
#include <__type_traits/is_generic_transparent_comparator.h>
#include <__type_traits/is_integral.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Expand Down Expand Up @@ -48,6 +49,9 @@ inline const bool __desugars_to_v<__less_tag, __less<>, _Tp, _Tp> = true;
template <class _Tp>
inline const bool __desugars_to_v<__totally_ordered_less_tag, __less<>, _Tp, _Tp> = is_integral<_Tp>::value;

template <>
inline const bool __is_generic_transparent_comparator_v<__less<> > = true;

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___ALGORITHM_COMP_H
175 changes: 28 additions & 147 deletions system/lib/libcxx/include/__algorithm/copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
#include <__algorithm/copy_move_common.h>
#include <__algorithm/for_each_segment.h>
#include <__algorithm/min.h>
#include <__algorithm/specialized_algorithms.h>
#include <__config>
#include <__fwd/bit_reference.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/segmented_iterator.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/common_type.h>
#include <__type_traits/enable_if.h>
#include <__utility/move.h>
Expand All @@ -38,124 +37,14 @@ copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result);
template <class _InIter, class _Sent, class _OutIter>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);

template <class _Cp, bool _IsConst>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned(
__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
using _In = __bit_iterator<_Cp, _IsConst>;
using difference_type = typename _In::difference_type;
using __storage_type = typename _In::__storage_type;

const int __bits_per_word = _In::__bits_per_word;
difference_type __n = __last - __first;
if (__n > 0) {
// do first word
if (__first.__ctz_ != 0) {
unsigned __clz = __bits_per_word - __first.__ctz_;
difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
__n -= __dn;
__storage_type __m = std::__middle_mask<__storage_type>(__clz - __dn, __first.__ctz_);
__storage_type __b = *__first.__seg_ & __m;
*__result.__seg_ &= ~__m;
*__result.__seg_ |= __b;
__result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
__result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
++__first.__seg_;
// __first.__ctz_ = 0;
}
// __first.__ctz_ == 0;
// do middle words
__storage_type __nw = __n / __bits_per_word;
std::copy(std::__to_address(__first.__seg_),
std::__to_address(__first.__seg_ + __nw),
std::__to_address(__result.__seg_));
__n -= __nw * __bits_per_word;
__result.__seg_ += __nw;
// do last word
if (__n > 0) {
__first.__seg_ += __nw;
__storage_type __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
__storage_type __b = *__first.__seg_ & __m;
*__result.__seg_ &= ~__m;
*__result.__seg_ |= __b;
__result.__ctz_ = static_cast<unsigned>(__n);
}
}
return __result;
}

template <class _Cp, bool _IsConst>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned(
__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
using _In = __bit_iterator<_Cp, _IsConst>;
using difference_type = typename _In::difference_type;
using __storage_type = typename _In::__storage_type;

const int __bits_per_word = _In::__bits_per_word;
difference_type __n = __last - __first;
if (__n > 0) {
// do first word
if (__first.__ctz_ != 0) {
unsigned __clz_f = __bits_per_word - __first.__ctz_;
difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
__n -= __dn;
__storage_type __m = std::__middle_mask<__storage_type>(__clz_f - __dn, __first.__ctz_);
__storage_type __b = *__first.__seg_ & __m;
unsigned __clz_r = __bits_per_word - __result.__ctz_;
__storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
__m = std::__middle_mask<__storage_type>(__clz_r - __ddn, __result.__ctz_);
*__result.__seg_ &= ~__m;
if (__result.__ctz_ > __first.__ctz_)
*__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
else
*__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
__result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
__result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
__dn -= __ddn;
if (__dn > 0) {
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __dn);
*__result.__seg_ &= ~__m;
*__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
__result.__ctz_ = static_cast<unsigned>(__dn);
}
++__first.__seg_;
// __first.__ctz_ = 0;
}
// __first.__ctz_ == 0;
// do middle words
unsigned __clz_r = __bits_per_word - __result.__ctz_;
__storage_type __m = std::__leading_mask<__storage_type>(__result.__ctz_);
for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
__storage_type __b = *__first.__seg_;
*__result.__seg_ &= ~__m;
*__result.__seg_ |= __b << __result.__ctz_;
++__result.__seg_;
*__result.__seg_ &= __m;
*__result.__seg_ |= __b >> __clz_r;
}
// do last word
if (__n > 0) {
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
__storage_type __b = *__first.__seg_ & __m;
__storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
__m = std::__middle_mask<__storage_type>(__clz_r - __dn, __result.__ctz_);
*__result.__seg_ &= ~__m;
*__result.__seg_ |= __b << __result.__ctz_;
__result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
__result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
__n -= __dn;
if (__n > 0) {
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
*__result.__seg_ &= ~__m;
*__result.__seg_ |= __b >> __dn;
__result.__ctz_ = static_cast<unsigned>(__n);
}
}
}
return __result;
}

struct __copy_impl {
template <class _InIter, class _Sent, class _OutIter>
template <class _InIter,
class _Sent,
class _OutIter,
__enable_if_t<!__specialized_algorithm<_Algorithm::__copy,
__iterator_pair<_InIter, _Sent>,
__single_iterator<_OutIter> >::__has_algorithm,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
while (__first != __last) {
Expand All @@ -167,37 +56,39 @@ struct __copy_impl {
return std::make_pair(std::move(__first), std::move(__result));
}

template <class _InIter, class _OutIter>
struct _CopySegment {
using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_InIter>;

_OutIter& __result_;

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _CopySegment(_OutIter& __result)
: __result_(__result) {}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
__result_ = std::__copy(__lfirst, __llast, std::move(__result_)).second;
}
};
template <class _InIter,
class _Sent,
class _OutIter,
__enable_if_t<__specialized_algorithm<_Algorithm::__copy,
__iterator_pair<_InIter, _Sent>,
__single_iterator<_OutIter> >::__has_algorithm,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static pair<_InIter, _OutIter>
operator()(_InIter __first, _Sent __last, _OutIter __result) {
return __specialized_algorithm<_Algorithm::__copy, __iterator_pair<_InIter, _Sent>, __single_iterator<_OutIter> >()(
std::move(__first), std::move(__last), std::move(__result));
}

template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
std::__for_each_segment(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
__result = std::__copy(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
});
return std::make_pair(__last, std::move(__result));
}

template <class _InIter,
class _OutIter,
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
!__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_OutIter>;
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
using _DiffT =
typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;

if (__first == __last)
return std::make_pair(std::move(__first), std::move(__result));
Expand All @@ -217,16 +108,6 @@ struct __copy_impl {
}
}

template <class _Cp, bool _IsConst>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false> >
operator()(__bit_iterator<_Cp, _IsConst> __first,
__bit_iterator<_Cp, _IsConst> __last,
__bit_iterator<_Cp, false> __result) const {
if (__first.__ctz_ == __result.__ctz_)
return std::make_pair(__last, std::__copy_aligned(__first, __last, __result));
return std::make_pair(__last, std::__copy_unaligned(__first, __last, __result));
}

// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
Expand Down
33 changes: 9 additions & 24 deletions system/lib/libcxx/include/__algorithm/copy_backward.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <__algorithm/copy_move_common.h>
#include <__algorithm/copy_n.h>
#include <__algorithm/for_each_segment.h>
#include <__algorithm/iterator_operations.h>
#include <__algorithm/min.h>
#include <__config>
Expand Down Expand Up @@ -170,37 +171,20 @@ struct __copy_backward_impl {
return std::make_pair(std::move(__original_last_iter), std::move(__result));
}

template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_InIter>;
auto __sfirst = _Traits::__segment(__first);
auto __slast = _Traits::__segment(__last);
if (__sfirst == __slast) {
auto __iters =
std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
return std::make_pair(__last, __iters.second);
}

__result =
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
.second;
--__slast;
while (__sfirst != __slast) {
__result =
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
.second;
--__slast;
}
__result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
.second;
using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
__result = std::__copy_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
});
return std::make_pair(__last, std::move(__result));
}

template <class _InIter,
class _OutIter,
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
!__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
Expand All @@ -214,7 +198,8 @@ struct __copy_backward_impl {

auto __local_last = _Traits::__local(__result);
while (true) {
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
using _DiffT =
typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;

auto __local_first = _Traits::__begin(__segment_iterator);
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
Expand Down
Loading