This was triggered when upgrading ivars from the pre-2.0 ABI that used
long double - their alignment could not be calculated correctly and we
hit an assertion.
Fixes: #82
__builtin_clz takes an unsigned int, it isn't overloaded for different
types. This meant that we were computing log2 by counting the
leading bits in a 32-bit value and using that result as if it were the
number of bits in a 64-bit value. This meant that our alignment values
were 2^32 times as big as they should be. This mostly didn't matter,
because we then truncated the result to 32 bits and the wrapping gave
the correct answer.
Unfortunately, this was undefined behaviour and, at sufficiently high
optimisation levels, this resulted in the value being optimised away,
leading to odd results.
This change is effectively a no-op (it's impossible to throw an
exception through these trampolines, because they tail call the real
block), but it does prevent the linker from complaining that we're
linking SEH-aware and SEH-unaware code.
On 32-bit Windows, malloc doesn't give us memory with sufficiently
strong alignment for AVX vectors.
Note that Windows also has a family of allocators that provide guarantee
exact misalignment. Using these would simplify the ivar layout logic
slightly, because we wouldn't need to account for the refcount pointer.
It's not clear that it's actually worth doing though, because that logic
already exists.
We weren't correctly sign-extending the value being compared, which was
resulting in objects not being deallocated. For some reason, this only
appeared on Windows, even though the code looked wrong on all platforms.
When removing a hash entry that was in the cell assigned to its hash, we
would clear the first bit in the second maps. If this entry was a
secondary value with the same hash, then this value became unreachable.
This very rarely showed up for two reasons. First, most of the tables
are insert-only and so we never try to remove things from them. Second,
it requires a particular sequence of inserts. It occasionally caused
weak references to be susceptible to use after free.
This implementation of objc_exception_throw constructs a
_CxxThrowException-compatible ThrowInfo based on the runtime type of the
passed-in exception. Everything pertaining to the exception is allocated
on the stack before the call and destroyed when/if the stack frame is
aborted.
The construction of ThrowInfo, CatchableTypes, and TypeDescriptors, as
well as mangling, is compatible with Clang/LLVM's MicrosoftCXXABI
exception generator.
This ties Objective-C exceptions on Windows to the C++ exception model,
which allows us to support (unboxed) foreign exceptions and C++ catch of
Objective-C types.
objc_exception_rethrow recycles MicrosoftCXXABI's rethrow.
Contributing-author: Jordan Saunders <jmsaunde@microsoft.com>
Contributing-author: Shayne Hiet-Block <shaynehi@microsoft.com>