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
|
# Runtime checks and exceptions
Part of the [subsystem notes](../SUBSYSTEMS.md). Related: [class lifetime](CLASS_LIFETIME.md).
## Runtime checks (`RuntimeCheck`)
- Array bounds, file misuse, enum ranges, null dereferences and array-parameter bounds
contracts are checked at their emit sites.
- `ArithmeticHandler` calls `emitDivZeroCheck` before `/`, DIV and MOD; the check
accepts integer and floating-point divisors, including both floating-point signed
zeros.
- `emitCheck(Cond, Msg, Args)` splits the block, prints the source line and error reason
to stderr, and calls `ExceptionHandler::emitThrow` on failure. File helper checks
receive the source line as a runtime argument.
## Exceptions (`ExceptionHandler`)
### Handlers and calls
- Holds Context/Builder/Module refs and a map of per-function handler stacks and active
catch depths.
- TRY pushes a catch target and an entry-block alloca for its exception pointer.
- A potentially throwing call with a handler or active catch emits an `invoke` and a
landing pad that finishes catches being left and transfers to the nearest handler, or
resumes unwinding when only cleanup is needed.
- CATCH uses `__cxa_begin_catch` and removes its own TRY target before emitting its
body; normal exit and RETURN call `__cxa_end_catch`.
- Bare THROW always creates a new anonymous integer exception, using `_ZTIi` internally
without exposing a value.
- Generated main owns the final catch target, prints the generic uncaught message, and
returns 1.
### Cleanup and automatic destruction
- User functions enable cleanup support before their first call: loop back edges can
make later DECLARE sites alive at earlier invokes. Without a local handler, cleanup
landing pads end active catches and resume unwinding.
- Returns (before catch cleanup) and cleanup resumes record exit points with their
handler/catch state; CodeGen fills reverse, Alive-guarded destruction only when the
function is fully emitted. Normal-exit destructor calls use that saved state and may
create further cleanup pads.
- During unwind filling, a reentrancy guard emits plain calls; a throwing destructor
propagates and interrupts remaining cleanup instead of terminating.
- Main records only its normal return, leaving its final uncaught-exception handler free
of automatic object destruction.
- Owned STRING values follow class cleanup. Array buffers are freed with their
scope (also when unwinding) and files are not automatically closed.
### Runtime and platforms
- Native binaries require the C++ runtime; EmbeddedRunner defines its statically linked
ABI symbols with ORC `absoluteSymbols`, while LLJIT with JITLink manages unwind frames
(generic EH-frame on Linux, compact-unwind or EH-frame on macOS, COFF SEH registration
on Windows x86_64); see [ARCH/EMBEDDED_RUNNER.md](../ARCH/EMBEDDED_RUNNER.md).
- CI coverage of embedded exception execution: [ARCH/BUILD.md](../ARCH/BUILD.md).
|