We now, the first time we encounter a foreign exception, throw a C++
exception through a frame that has a custom personality function and
probe the layout of the __cxa_exception structure.
We then use the offsets learned from this along with the public ABI
functions for allocating the structure.
At the same time, add a test that we are correctly setting the count of
uncaught exceptions.
Fixes#146
On Itanium C++ ABI platforms, there are a lot of different variations
that have subtly different structure layouts. This commit adds a
run-time test that throws a C++ exception through a function that has
its personality function replaced with a wrapper so that we can inspect
a C++ exception in controlled conditions.
Initially, this just detects the exception type value used for C++
exceptions.
When passing -T to ask CTest to generate XML output, CTest complains
about a missing TCL file. This causes the build steps to fail. To
avoid that, make sure the ctest invocation is the last line in the
script so that its error status will be reported.
The reworked wrapping of C++ exceptions meant that we were missing a
dereference of the result of __cxa_begin_catch.
Add a test that triggers this issue. It would have occurred in the
non-ARC version if we actually did anything with the exception, but
compiling it in ARC mode makes the compiler insert retain / autorelease
around the exception object to ensure that it remains live.
We need to #include <exception> for this to work, but this brings in the
public definition of `std::type_info` and, unfortunately, that breaks
the private definition that we need in this compilation unit.
Recent versions of libstdc++ appear to have lost the clean layering
between libstdc++ and libsupc++, so use the high-level APIs and some
pointer evilness to fudge the low-level ones...
This was generating a relocation that didn't do the right thing and
didn't raise linker errors. Now it is using GOT-relative addressing.
In combination with the last two commits, this now makes all of the
objc_msgSend tests pass on AArch64.
Fixes#105
If we called into C to find the IMP (e.g. for forwarding), we were then
reloading all of the arguments but failing to adjust the stack pointer
by the correct amount, leaving it around 192 bytes offset from its
correct location. This, unsurprisingly, led to crashing and other
exciting behaviour.
As an optimisation, on load of a weak reference we check if the object
has already been deallocated and, if so, decrement the weak reference
count and zero the pointer to the weak reference structure so that the
next check is faster and doesn't need to hold locks for as long.
Unfortunately, the prior implementation of this instead decremented the
weak reference count and then only zeroed the pointer if the reference
count reached zero. This meant that loading the same __weak pointer
twice after the pointed-to object had been deallocated would decrement
the reference count twice.
When removing a WeakRef from the map, we use its obj field to find the
key, but the obj field has already been zeroed by this point and so we
end up leaving dangling pointers in the map.
This bug is also present in the original version:
When removing a WeakRef from the map, we use its obj field to find the
key, but the obj field has already been zeroed by this point and so we
end up leaving dangling pointers in the map.