Our strategy of leaking the Stack to ensure safety is only effective if
the lifetime of the underlying stack memory is controlled by the
destructor of the Stack. We don't add this bound to unsafe_new, so that
users who wish to provide the necessary guarantees themselves can do so.
On hosted platforms, libstd allows safely borrowing values from TLS with
'thread lifetime and without a Sync bound. As a result, we can't
guarantee that sending a generator across threads won't create dangling
references or data races. In freestanding environments, the notion of
thread-safety is likely to be defined by the consumer of libfringe,
so our Send bounds and implementation are unlikely to be meaningful
anyway.
This ensures that gdb is able to generate a correct backtrace when
stopped at any instruction in the inline asm.
It also makes backtraces accessible to tools that only track frame
pointer chains, like perf or dtrace.
close#49
The use case is as follows: let's say I have a scheduler that uses
libfringe for context switching. A single thread may open several
sockets, each of which presents a std::io::Read interface, and
waiting in Read::read requires having a reference to the yielder
inside the socket.
This could be worked around with RefCell in the API consumer, but
there is no real reason to not implement it in libfringe.
close#48
This commit:
* Gets rid of 2nd init trampoline.
* Gets rid of any custom CFI, instead using the standard CFI
for target prologue.
* Makes backtraces accessible to tools that only track frame
pointer chains, like perf or dtrace.
* Keeps the performance at the exact same level.
This reverts a part of 365e40b. While it is not legal to clobber
the output register, it is legal and necessary to do this for inputs,
since we do not preserve them, and LLVM could have decided to
reuse them.
Thanks to @Amanieu for discovering this.
This is not actually legal (although the restriction is not
documented anywhere), and is not caught by LLVM unless the codegen
option -verify-machineinstrs is specified. This option is now used
on Travis.
While not legal, this does not seem to result in invalid output
(although it creates an unnecessary spill); however, under extremely
specific circumstances (e.g. when a register scavenger is run under
severe pressure), this will result in a codegen crash, which is
how I found it.
This makes more sense, because "generate" implies *running*
a generator, not *returning* from a generator. That name was
a vestige of the time when libfringe only really provided a .next()
implementation, which made marginally more sense together with
.generate(), but it doesn't anymore when we have .resume().
The core::intrinsics::unreachable() we used at the end of every naked
function is essentially pointless, as #[naked] implies that intrinsic
at the end of the function. rustc currently does not implement that
behavior (rust-lang/rust#32487), but it is a bug. On top of that,
anything except a single asm!() in naked functions is likely to be
disallowed in the future (rust-lang/rust#32490).
A nice side effect is that we avoid the core_intrinsics feature,
which will be never stabilized, though neither asm nor
naked_functions are likely to be stabilized soon.
Also, remove the Windows OsStack implementation. It will not ever
be useful in libfringe, as even if we add support for Windows
using fibers, the OS allocates stacks for fibers and we needn't
do it manually.