This is the same strategy that LLVM's compiler-rt uses to make sure that
each UBSAN error is only reported once, when UBSAN is *not* deadly.
Otherwise, each time we head through a UB codepath, we will log the same
error over and over. That behavior just adds noise to the logs and makes
it nearly impossible to run binaires that have some common code path
with flagged UB in them.
compiler-rt goes the extra step to make sure the "clear" action is
atomic, but we don't really have that many multi-threaded apps gettting
tested with UBSAN yet, so we can add that later.
This will allow us to avoid some potentially expensive type conversion
during lookup, like form String to StringView, which would allocate
memory otherwise.
Instead of checking __linux__ macro directly, the code should check if
this macro is defined. This is already done correctly a couple of lines
above.
I ran into this when trying to build libjs-test262 on MacOS where I got
the following error message
error: "__linux__" is not defined, evaluates to 0 [-Werror=undef]
This is a convenience template that implements reference count
forwarding. This means that an object forwards ref() and unref() to
another object.
We can use this when two ref-counted objects need to keep each other
alive. This situation poses two problems:
- Using 2x RefPtr would cause a ref cycle and leak both objects.
- Using 2x WeakPtr would allow one of them to be destroyed early.
With RefCountForwarder, only one of the objects has a ref count. The
object with the ref count points to the forwarding object by using a
non-counting smart pointer (OwnPtr or NonnullOwnPtr). Thus, both objects
are kept alive by the same ref count, and they can safely point to each
other without worrying about disjoint lifetimes.
Note that the return type for the non-const method error() changed. This
is most likely an accident, hidden by the fact that ErrorType typically
is Error.
This makes it an error to not do something with a returned smart
pointer, which should help prevent mistakes. In cases where you do need
to ignore the value, casting to void will placate the compiler.
I did have to add comments to disable clang-format on a couple of lines,
where it wanted to format the code like this:
```c++
private : NonnullRefPtr() = delete;
```
Previously, Vector::extend for a moved vector would move the other
vector into this vector if this vector was empty, thereby throwing away
existing allocated capacity. Therefore, this commit allows the move to
only happen if this vector's capacity is too small to fit the other
vector. This will also alleviate bugs where callers relied on the
capacity to never shrink with calls to unchecked_append, extend and the
like.
This mirrors the existence of append() for data pointers and is very
useful when the program needs to have a guarantee of no allocations,
as is necessary for real-time audio.
During the build process on macOS, multiple versions of <unistd.h> were
being included (Apple's version and GCC's version). It appears that
all other places #include the version from GCC, but in Platform.h the
Apple header was being used. GCC's <unistd.h> is wrapped in
`extern "C"`, while Apple's is not. This causes a conflicting
declaration, so we need to wrap the #include with extern "C".
Issue has been observed on macOS Mojave.
See https://github.com/microsoft/vcpkg/issues/11320 for a similar issue.
This creates an error that contains the name of the syscall that failed.
This allows error handlers to print out the name of the call if they
want to. :^)
Avoid including a per-translation unit copy of all these functions.
Also, drive-by two clang-tidy fixes for readability-qualified-auto and
readability-implicit-bool-conversion.
Currently TimeManagement wont compile on AARCH64, so it is not included.
This creates a link error since format.cpp now relies on functionality
in TimeManagement.cpp to add timestamps to log lines.
This PR disables that functionality for AARCH64 builds until
TimeManagement will compile.
This is a naive implementation based on the symmetry with `asin`.
Before, I'm not really sure what we were doing, but it was returning
wildly incorrect results.
This isn't a complete conversion to ErrorOr<void>, but a good chunk.
The end goal here is to propagate buffer allocation failures to the
caller, and allow the use of TRY() with formatting functions.
Also add slightly richer parse errors now that we can include a string
literal with returned errors.
This will allow us to use TRY() when working with JSON data.
This feels like it was a refactor transition kind of conversion. The
places that were relying on it can easily be changed to explicitly ask
for the ptr() or a new vaddr() method on Userspace<T*>.
FlatPtr can still implicitly convert to Userspace<T> because the
constructor is not explicit, but there's quite a few more places that
are relying on that conversion.
In AK::Function::CallableWrapper::init_and_swap(), clang-tidy wants us
to mark the destination argument as pointer to const, which doesn't work
because we use placement new to construct a move'd *this into.
cert-dcl50-cpp: No variadic functions, suppressed in RefCounted and
ThreadSafeRefCounted for implementing the magic one_ref_left and
will_be_destroyed functions.
cert-dcl58-cpp: No opening ::std, suppressed in the places we put names
in ::std to aid tools (move, forward, nullptr_t, align_val_t, etc).
Either not returning *this, or in the case of Variant, not checking for
self assignment. In AK::Atomic, we can't return *this due to the wrapper
semantics Atomic implements.
Using `l` for long double causes a clang-tidy warning, so use all caps
suffixes for all of the AK::abs() overloads for consistency. Also, avoid
leaking the internal __DEFINE_GENERIC_ABS macro.
The definition of VERIFY_NOT_REACHED() as `assert(false)` causes the
tool to suggest converting it to a static_assert. Which doesn't make
any sense in context for what the macro is trying to do: crash the
program at runtime.
Add a basic clang-tidy configuration that enables checks from the
following categories:
- bugprone
- cert
- clang-analyzer
- concurrency
- misc
- performance
- portability
- readability
The noisiest rules that have conflicts with the project style guide or
accepted practices have been turned off.
There's absolutely more work to be done here before we could consider
setting any of these warnings as errors and enforcing them in CI, but
committing a project clang-tidy configuration should help the rules
become more visible and let other contributors take a crack at tweaking
rules and/or finding possible bugs.
Sadly the cpp-core-guidelines and modernize categories are very, very
noisy. If we want to enable rules from these categories, they would need
to be on a rule by rule basis.
Previously if code attempted to use the format specifier somewhere
(Ex: "%#4.3Lg"), the specifier would get dropped and we would just
print "g" instead of any value. Now at least we print a value.
Same as Vector, ByteBuffer now also signals allocation failure by
returning an ENOMEM Error instead of a bool, allowing us to use the
TRY() and MUST() patterns.
Instead of signalling allocation failure with a bool return value
(false), we now use ErrorOr<void> and return ENOMEM as appropriate.
This allows us to use TRY() and MUST() with Vector. :^)
All the read-only methods of Bitmap simply defer to BitmapView. Let's
make this relationship official by using class inheritance. This might
even shave off a few instructions, although any sufficiently optimizing
compiler probably already optimized them away.
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace!
This was a slightly tedious refactoring that took a long time, so it's
not unlikely that some bugs crept in.
Nevertheless, it does pass basic functionality testing, and it's just
real nice to finally see the same pattern in all contexts. :^)
This variant returns ErrorOr<NonnullOwnPtr<T>> instead of KResultOr.
Eventually the KResultOr variant should go away once the kernel adopts
Error and ErrorOr<T>.
This is an alternative to ErrorOr<T>::release_value() that can be used
when converting code to signal that we're releasing the value without
error propagation as a way to move forward now.
This makes these cases much easier to find later on, once more paths for
error propagation are available.
The goal with these is to eventually replace AK::Result, KResult and
KResultOr<T> with something that works (and makes sense) in both kernel
and userspace.
This first cut of Error can be made from an errno code, or from a string
literal (StringView)
When I added this code in 1472f6d, I forgot to add tests for it. That's
why I didn't realize that the values were appended to the wrong
FormatBuilder object, so an empty string was returned instead of the
expected "nan"/"inf". This made debugging some FPU issues with the
ScummVM port significantly more difficult.
For some algorithms, such as bloom filters, it's possible to reuse a
hash function (rather than having different hashing functions) if the
seed is different each time the hash function is used.
Modify AK::string_hash() to take a seed parameter, which defaults to 0
(the value the hash value was originally initialized to).
In the long-term, we should probably have a way to signal decoding
failure. For now, it should suffice to at least not crash. This is
particularly relevant because apparently this can be triggered while
parsing a PEM certificate, which happens during every TLS connection.
Found by OSS Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=38979
In particular, we implicitly required that the caller initializes the
returned instances themselves (solved by making
UniformBumpAllocator::allocate call the constructor), and BumpAllocator
itself cannot handle classes that are not trivially deconstructible
(solved by deleting the method).
Co-authored-by: Ali Mohammad Pur <ali.mpfard@gmail.com>
This fixes two bugs:
1. `end_offset` was missing the alignment that might have been
introduced while computing `base_ptr`.
2. Ignoring point 1, `end_offset` computed the offset of the first byte
that is outside the current chunk. However, this might be in the
middle of a (hypothetical) object! The loop treats `end_offset` as if
it points to the first byte beyond the last (valid) object. So if the
last few bytes of the chunk are unused, the loop iterates once too
often.
Found by OSS Fuzz, long-standing issue (since 2021-07-31)
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=38733
(This probably also resolves some other issues that go through
RegexMatcher.)
See also: 0f1425c895
Creating a String object from the formatted data is unnecessary, as it
immediately gets turned into a StringView anyways.
With this change, we will no longer allocate on the heap when printing
`VirtualAddress`, `VirtualRange` and `InodeIdentifier` objects, which is
a step towards stronger OOM hardening.
Forcing the formatting to go through `Formatter<FormatString>` is
completely unnecessary, increases code size, performs a String
allocation and prevents us from using the formatting options available
on that type.
This commit also removes explicit formatters from
`BlockBasedFileSystem::BlockIndex` and `Kernel::InodeIndex`, as those
are already covered by the blanket implementation for all
`DistinctNumeric` types.
There is no need to have a user-defined copy constructor that simply
calls the base class's copy constructor. By having the compiler generate
it for us, Span is made trivially copyable, so it can be passed in
registers.
This function converts a single wide character into its multibyte
representation (UTF-8 in our case). It is called from libc++'s
`std::basic_ostream<wchar_t>::flush`, which gets called at program exit
from a global destructor in order to flush `std::wcout`.
The platform independent Processor.h file includes the shared processor
code and includes the specific platform header file.
All references to the Arch/x86/Processor.h file have been replaced with
a reference to Arch/Processor.h.
Both my approach and the previous approach were wrong for different
cases. I've changed the Iterators index from storage-relative to
queue-relative, and it's much simpler and more obviously correct.
fixes#10383
While I was working on LibWeb, I got a page fault at 0xe0e0e0e4.
This indicates a destroyed RefPtr if compiled with SANITIZE_PTRS
defined. However, the page fault handler didn't print out this
indication.
This makes the page fault handler print out a note if the faulting
address looks like a recently destroyed RefPtr, OwnPtr, NonnullRefPtr,
NonnullOwnPtr, ThreadSafeRefPtr or ThreadSafeNonnullRefPtr. It will
only do this if SANITIZE_PTRS is defined, as smart pointers don't get
scrubbed without it being defined.
Some time ago, automatic locking was added to the AK smart pointers to
paper over various race conditions in the kernel. Until we've actually
solved the issues in the kernel, we're stuck with the locking.
However, we don't need to punish single-threaded userspace programs with
the high cost of locking. This patch moves the thread-safe variants of
RefPtr, NonnullRefPtr, WeakPtr and RefCounted into Kernel/Library/.
Example failure:
IDAllocator.h only pulls in AK/Hashtable.h, so any compilation unit that
includes AK/IDAllocator.h without including AK/Traits.h before it used
to be doomed to fail with the cryptic error message "In instantiation of
'AK::HashTable<T, TraitsForT, IsOrdered>::Iterator AK::HashTable<T,
TraitsForT, IsOrdered>::find(const T&) [with T = int; TraitsForT =
AK::Traits: incomplete type 'AK::Traits<int>' used in nested name
specifier".
This change also applys to to_uint
On i686 u64 == long long but on x86_64 u64 == long. Therefor on either
arch, one of the instantiations is missed. This change makes sure that
all integer types have an instantiation.
It's very common to encounter single-character strings in JavaScript on
the web. We can make such strings significantly lighter by having a
1-character inline capacity on the Vectors.
Until we're confident that RequestServer doesn't need this runtime debug
dump helper, it's much nicer if everyone has it built in, so they can
simply send a SIGINFO if they see it acting up.
Otherwise we'd end up trying to delete the wrong connection if a
connection made before us is deleted.
Fixes _some_ RequestServer spins (though not all...).
This commit also adds a small debug mechanism to RequestServer (which
can be enabled by turning REQUEST_SERVER_DEBUG on), that can dump all
the current active connections in the cache, what they're doing, and how
long they've been doing that by sending it a SIGINFO.
The first argument for LexicalPath::join was a String const&, which
resulted in an unnecessary memory copy when invoked with a StringView.
Changing the type of the parameter to StringView avoids the extra cost.
This was noticed while working on #10230.
We already know the length of these substrings, so there's no need to
check their lengths using strlen in the StringView(char*) constructor.
This patch also removes an accidental 1-byte OOB read that was left over
from when this method received null-terminated char pointers instead of
string views, as well removes the unnecessary lambda call (two of the
checks were impossible, and this was only called in one place, so we can
just inline it)
This was required before commit 5f724b6ca1
when we were building LibC before libstdc++ headers were available in
the sysroot. However as noted in that commit, we never actually needed
to be building LibC before libstdc++, so we can go ahead and remove this
ancient hack.
The only use of this define was removed in commit
5f724b6ca1, over a year ago.
The define was there to prevent the LibC build we built before libstdc++
from complaining about missing libgcc symbols. However, as noted in that
commit, we never actually needed to build LibC at all.
"result" is a tad bit too generic to provide a clash-free experience -
we found instances in LibJS where this breaks already. Essentially this
doesn't work:
auto foo = TRY(bar(result));
Because it expands to the following within the TRY() scope:
{
auto result = bar(result);
...
}
And that of course fails:
error: use of ‘result’ before deduction of ‘auto’
The simple solution here is to use a name that is much less likely to
clash with anything used in the expression ("_temporary_result"). :^)
DisjointChunks<T> provides a nice interface over multiple sequential
Vector<T>'s, allowing the user to iterate over/index into/slice from
said buffers as if they were a single contiguous buffer.
To work with views on such objects, DisjointSpans<T> is provided, which
has the same behaviour but does not own the underlying objects.
These are required in the specification and used by the web's URL
built-in, this commit also removes the Badge<AK::URL> from URLParser
to allow other classes that need to call the parser directly like the
web's URL built-in to do so.
This should:
- Accept const& on both sides
- Not involve implicit conversions on either side
otherwise the argument order would be deemed significant, and trip this
warning.
Serenity has explicit_bzero() in LibC with the same implementation,
however we need to be able to use this from Lagom on all platforms
that we support building serenity on. I've implemented it in AK for
this reason.
This removes the awkward String::replace API which was the only String
API which mutated the String and replaces it with a new immutable
version that returns a new String with the replacements applied. This
also fixes a couple of UAFs that were caused by the use of this API.
As an optimization an equivalent StringView::replace API was also added
to remove an unnecessary String allocations in the format of:
`String { view }.replace(...);`
This was needlessly copying StringView arguments, and was also using
strstr internally, which meant it was doing a bunch of unnecessary
strlen calls on it. This also moves the implementation to StringUtils
to allow API consistency between String and StringView.
This variant of dbgputstr does not lock the global log lock, as it is
called before the current or any other processor was initialized,
meaning that:
A) The $gs base was not setup yet, so we cannot enter into critical
sections, and as a result we cannot use SpinLocks
B) No other processors may try to print at the same time anyway
This bit me because I accidentally made the destructor for a class which
was wrapped in an Optional private. This causes none of the Optional
destructors to be able to be deduced, which when combined with concepts
causes an internal compile error in GCC 10.3.0+. This commit adds a note
here to make sure that future encounters of this bug does not surprise
people.
c27abaabc4 moved this out of the global
namespace, but did not qualify its users.
While this seems to be fine (sometimes, somehow), let's qualify it to
avoid random breakage.
This is in preparation for making KBufferBuilder::append() and friends
return a KResult. Long-term we should come up with a solution that works
for both kernel and userspace clients of the JSON API.
This type is useful, as the sizes will be visible in the compiler error
messages, as they will be part of the template parameters. This is not
possible with a normal static_assert of the sizeof a type.
The way we use classes like Kernel::KResultOr<T> and AK::Result<T, E>
makes checking for errors (and short-circuiting returns) quite verbose.
This patch adds a new TRY(expression) macro that either evaluates to
the released result of the expression if successful, or returns the
error if not.
Before:
auto foo_or_error = get_foo();
if (foo_or_error.is_error())
return foo_or_error.release_error();
auto foo = foo_or_error.release_value();
After:
auto foo = TRY(get_foo());
The macro uses a GNU C++ extension which is supported by GCC, Clang,
Intel C++, and possibly others. It's not *ideal*, but since it makes our
codebase considerably nicer, let's try(!) it out. :^)
Co-authored-by: Ali Mohammad Pur <mpfard@serenityos.org>
This commit moves the KResult and KResultOr objects to Kernel/API to
signify that they may now be freely used by userspace code at points
where a syscall-related error result is to be expected. It also exposes
KResult and KResultOr to the global namespace to make it nicer to use
for userspace code.
This function ensures that a key is present in the HashMap.
If it's not present, it is inserted, and the corresponding value
is initialized with whatever the callback returns.
It allows us to express this:
auto it = map.find(key);
if (it == map.end()) {
map.set(it, make_a_value());
it = map.find(key);
}
auto& value = it->value;
Like this:
auto& value = map.ensure(key, [] { return make_a_value(); });
Note that the callback is only invoked if we have to insert a missing
key into the HashMap. This is important in case constructing the default
value is expensive or otherwise undesirable.
This introduces a new define AK_DONT_REPLACE_STD that disables our own
implementation of std::move and std::forward. Some ports include both
STL and AK headers which causes conflicts when trying to resolve those
functions. The port can define AK_DONT_REPLACE_STD before including
Serenity headers in that case.
This avoids a value copy when calling value() or value_or() on a
temporary Optional. This is very common when using the HashMap::get()
API like this:
auto value = hash_map.get(key).value_or(fallback_value);
Our existing implementation did not check the element type of the other
pointer in the constructors and move assignment operators. This meant
that some operations that would require explicit casting on raw pointers
were done implicitly, such as:
- downcasting a base class to a derived class (e.g. `Kernel::Inode` =>
`Kernel::ProcFSDirectoryInode` in Kernel/ProcFS.cpp),
- casting to an unrelated type (e.g. `Promise<bool>` => `Promise<Empty>`
in LibIMAP/Client.cpp)
This, of course, allows gross violations of the type system, and makes
the need to type-check less obvious before downcasting. Luckily, while
adding the `static_ptr_cast`s, only two truly incorrect usages were
found; in the other instances, our casts just needed to be made
explicit.
And also try_create<T> => try_make_ref_counted<T>.
A global "create" was a bit much. The new name matches make<T> better,
which we've used for making single-owner objects since forever.
When swapping the same object, we could end up with a double-free error.
This was found while quick-sorting a Vector of Variants holding complex
types, reproduced by the new swap_same_complex_object test case.
Static analysis correctly flags that we are missing an implementation
for `operator delete` for all classes which are annotated with
AK_MAKE_ETERNAL. To appease static analysis define an implementation
which asserts to make sure no one ever calls delete on the object.
The assumption that FlatPtr is 64-bit on every platform except i686 is
not correct, and also makes the definition of explode_byte() less nice
to look at.
The IRC Client application made some sense while our main communication
hub was an IRC channel. Now that we've moved on, IRC is just a random
protocol with no particular relevance to this project.
This also has the benefit of removing one major client of the single-
process Web::InProcessWebView class.
This parsing is already duplicated between LibJS and LibRegex, and will
shortly be needed in more places in those libraries. Move it to AK to
prevent further duplication.
This API will consume escaped Unicode code points of the form:
\\u{code point}
\\unnnn (where each n is a hexadecimal digit)
\\unnnn\\unnnn (where the two escaped values are a surrogate pair)
This is primarily to be able to remove the GenericLexer include out of
Format.h as well. A subsequent commit will add AK::Result to
GenericLexer, which will cause naming conflicts with other structures
named Result. This can be avoided (for now) by preventing nearly every
file in the system from implicitly including GenericLexer.
Other changes in this commit are to add the GenericLexer include to
files where it is missing.
If a member is an empty class, the standard normally stats that it needs
to have a size of at least 1 byte in order to guarantee that the
addresses of distinct objects of the same type are always distinct.
However as of c++20, we can use [[no_unique_address]] to instruct the
compiler that if the member has an empty type, it may optimize it to
occupy no space.
This typo / bug in the Traits<T> implementation for StringView caused
AK::HashMap methods to return a `String` when looking up values out of
a hash map of type HashTable<StringView,StringView>.
This change fixes the typo, and fixes the only consumer, the kernel
Commandline class.
This is basically a complement to adopt_nonnull_ref_or_enomem, and
simplifies boilerplate for try_create functions which just return ENOMEM
or the object based on whether it was able to allocate.
Problem:
- `AK::Detail::integer_sequence_generate_array` is published via a
`using` directive in the `Array.h` header, but this is a `Detail`
function.
Solution:
- Remove the `using` declaration.
In the quest of removing as timespec / timeval usage in the Userland as
possible, we need a way to conveniently retrieving the current clock
time from the kernel and storing it in `AK::Time` format.
Problem:
- ToT clang will not build due to casting `nullptr` to `u8*`. This is
redundant because it casts to get a `0` then subtracts it.
Solution:
- Remove it since subtracting `0` doesn't do anything.
Currently, to append a UTF-16 view to a StringBuilder, callers must
first convert the view to UTF-8 and then append the copy. Add a UTF-16
overload so callers do not need to hold an entire copy in memory.
Without this patch, we would end up printing garbage values when we
encountered floating point infinity or NaN values, and also triggered
UBSAN with Clang. This added code models `std::format`'s behavior: the
sign is added the same way as with normal values and the strings 'nan'
and 'inf' are printed.
On x86, the `fprem` and `fmprem1` instructions may produce a 'partial
remainder', for which we should check by reading a FPU flag. If we don't
check for it, we may end up using values that are outside the expected
range of values.
When compiling this code with Clang, both branches of the ternary
operator get evaluated at compile-time, triggering a warning about a
narrowing implicit conversion. We can use `explode_byte` instead.
On i686, reading integers larger than `2^32 - 1` would fail as the
32-bit `size_t` parameter would overflow. This caused us to read too few
bytes in LibDebug's DWARF parser. Making this method templated solves
this issue, as we now can call this API with a `u64` parameter.
This pattern is no good:
kmalloc(elements * sizeof(T));
Since it silently swallows any multiplication overflow.
This patch adds a simple kmalloc_array() that stops the program if
overflow occurs:
kmalloc_array(elements, sizeof(T));
This container is the same as IntrusiveList, except that it allows
modifications to the elements even if the reference to the
IntrusiveList itself is const, by returning mutable iterators. This
represents a use-case where we want to allow modifications to the
elements while keeping the list itself immutable.
This behavior is explicitely opt-in by using IntrusiveListRelaxedConst
instead of IntrusiveList. It will be useful later on when we model
shared/exclusive locks with the help of const and mutable references.
Problem:
- `any_of` is implemented in 2 different ways, one for the entire
container and a different implementation for a partial container
using iterators.
Solution:
- Follow the "don't repeat yourself" (DRY) idiom and implement the
entire container version in terms of the partial version.
Improve the parsing of data urls in URLParser to bring it more up-to-
spec. At the moment, we cannot parse the components of the MIME type
since it is represented as a string, but the spec requires it to be
parsed as a "MIME type record".
`append()` is almost never going to select the overload that is desired.
e.g. it will append chars when you pass it a Vector<size_t>, which is
definitely not the right overload :)
The current method of iterating through the string to access a code
point hurts performance quite badly for very large strings. The test262
test "RegExp/property-escapes/generated/Any.js" previously took 3 hours
to complete; this one change brings it down to under 10 seconds.
Previously we would just print "ASSERTION FAILED: false", which was
kinda cryptic and also didn't make it clear whether this was a TODO or
an unreachable condition. Now, we actually print "ASSERTION FAILED:
TODO", making it crystal clear.
Problem:
- New `all_of` implementation takes the entire container so the user
does not need to pass explicit begin/end iterators. This is unused
except is in tests.
Solution:
- Make use of the new and more user-friendly version where possible.
Previously there was no way to create a MACAddress by passing a direct
address as a string. This will allow programs like the arp utility to
create a MACAddress instance by user-passed addresses.
Problem:
- Now that a generic free-function form of `find_if` is implemented
the code in `all_of` is redundant.
Solution:
- Follow the "don't repeat yourself" mantra and make the code DRY by
implementing `all_of` in terms of `find_if`.
- One tricky part is that since captures are not permitted in
`constexpr` lambdas, the lambda created to negate the predicate
needs to be created by a function which does not capture and takes
the predicate at run-time instead. This allows `all_of` to continue
to work in a `constexpr` context.
To be used as a RegexStringView variant, Utf16View must provide a couple
more helper methods. It must also not default its assignment operators,
because that implicitly deletes move/copy constructors.
This makes it so these algorithms are usable with arbitrary iterators,
as opposed to just instances of AK::SimpleIterator.
This commit also makes the requirement of ::index() in find_index()
explicit, as previously it was accepting any iterator.
This is a generally nicer-to-use version of the existing {any,all}_of()
that doesn't require the user to explicitly provide two iterators.
As a bonus, it also allows arbitrary iterators (as opposed to the hard
requirement of providing SimpleIterators in the iterator version).
This concept describes a type with a begin()/end() pair that can
function as an iterator, given the following criteria:
- The return type of begin() is comparable with the return type of
end(), and the comparison (with operator!=) yields a bool
- The object returned from begin() can be pre-incremented
- The iterator has an operator*() implementation
By replacing MakeUnsigned<Source> in this specific specialization with a
simple negativity check this now works for floating point source types.
Previously it would attempt a comparison of the destination type and
void.
AK's version should see better inlining behaviors, than the LibM one.
We avoid mixed usage for now though.
Also clean up some stale math includes and improper floatingpoint usage.
This is to implement constexpr template based implementations for
mathematical functions
This also changes math.cpp to use these implementations.
Also adds a fastpath for floating point trucation for values smaller
than the signed 64 bit limit.
The state of the formatter for the previous element should be thrown
away for each iteration. This showed up when trying to format a
Vector<String>, since Formatter<StringView> was unhappy about some state
that gets set when it's called. Add a test for Formatter<Vector>.
This is trivial, and makes it easier to get the code point compared to
the previous `.code_points()[index]` (which was not actually checked
for in-bounds length).
There is still an offset to consider, a zero-length view is very
different from a nonexistent string :P
Co-authored-by: Timothy Flynn <trflynn89@pm.me>
This implements a simple bootloader that is capable of loading ELF64
kernel images. It does this by using QEMU/GRUB to load the kernel image
from disk and pass it to our bootloader as a Multiboot module.
The bootloader then parses the ELF image and sets it up appropriately.
The kernel's entry point is a C++ function with architecture-native
code.
Co-authored-by: Liav A <liavalb@gmail.com>
The previous implementation was too generic, and would cause conflicting
operator overload errors when included in certain code paths. Fix this
by restricting the template parameters to types which have the same
member names as `struct timespec`.
This is a much more ergonomic option than getting a
`VERIFY_NOT_REACHED()` failure at run-time. I encountered this issue
with Clang, where sized deallocation is not the default due to ABI
breakage concerns.
Note that we can't simply just not declare these functions, because the
C++ standard states:
> If this function with size parameter is defined, the program shall
> also define the version without the size parameter.
Prior to this, it'd try to stuff them into an i64, which could fail and
give us nothing.
Even though this is an extension we've made to JSON, the parser should
be able to correctly round-trip from whatever our serialiser has
generated.
Note: this exact implementation is needed for __atomic_is_lock_free to
link with both GCC (for the SerenityOS build) and Clang (for the Fuzzer
build). The size argument must be a compile-time constant, otherwise it
fails to link with both compilers. Alternatively, the following
definition links with GCC but fails with Clang:
template<size_t S>
static inline bool atomic_is_lock_free(volatile void* ptr = nullptr)
{
return __atomic_is_lock_free(S, ptr);
}
When repeatedly enqueing and dequeing a single item in a Queue we end
up faulting in all the pages for the underlying Vector. This is a
performance issue - especially where the element type is large.
Previously the Queue class used a SinglyLinkedList to manage its queue
segments. This changes the Queue class to use the IntrusiveList class
instead which saves us one allocation per segment.