1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! Keeping the recursion of the context processing algorithm off the caller's
//! native stack.
//!
//! The algorithm recurses for every remote `@context` it enters (step 5.2.6),
//! for every scoped `@context` it validates (Create Term Definition step 21.3)
//! and for every term a definition depends on. The `async` implementation
//! boxes each recursive call, which moves the callee's *state* to the heap but
//! not its *polling*: a parent polls its child from inside its own `poll`, so
//! the native stack still deepens by one set of poll frames per level. A remote
//! context cycle, which JSON-LD 1.1 reprocesses at the top level until step
//! 5.2.3's context overflow ends it, therefore walks
//! [`MAX_REMOTE_CONTEXTS`](crate::MAX_REMOTE_CONTEXTS) levels deep, and on a
//! thread whose stack the embedder has already partly used, that aborted the
//! process on a stack overflow before the spec-defined error was reached.
//!
//! Every recursion point now runs its callee through [`on_sufficient_stack`]:
//! when less than [`RED_ZONE`] of the current stack is left, the callee runs on
//! a freshly allocated segment of [`SEGMENT`] bytes instead. The depth limits
//! stay what bounds the recursion; this only guarantees they are reached as
//! errors on any thread.
use ;
/// Stack left below which a recursion level moves to a fresh segment.
///
/// It has to exceed the native stack one level uses between two recursion
/// points, which is largest in unoptimized builds.
const RED_ZONE: usize = 128 * 1024;
/// Size of each fresh stack segment.
const SEGMENT: usize = 2 * 1024 * 1024;
/// Runs `callee`, on a fresh stack segment when the current one is nearly used.
pub
/// A recursive call of the `async` algorithm.
///
/// The callee lives on the heap, like the `Box::pin` it replaces, and every
/// poll of it runs through [`on_sufficient_stack`], so polling a chain of
/// nested calls cannot exhaust the native stack.
pub ;