# Understanding the Exception Handler Table During MulleObjC Startup

> Discover how the exception handler table in MulleObjC startup safely catches exceptions during early initialization before the runtime is active. Learn its core purpose and function.

- Repository: [mulle-objc/mulleobjc-startup](https://github.com/mulle-objc/mulleobjc-startup)
- Tags: internals
- Published: 2026-03-07

---

**The exception handler table is a static data structure registered during MulleObjC startup that maps exception classes to handler functions, ensuring that any exceptions thrown during early initialization—before the full Objective-C runtime is active—are caught and processed safely.**

The `mulle-objc/mulleobjc-startup` repository provides the entry point for MulleObjC applications, orchestrating the fragile early initialization phase. Central to this process is the **exception handler table**, which is imported from the core MulleObjC library and installed before any user code executes.

## What Is the Exception Handler Table in MulleObjC?

The exception handler table is defined in the private header [`mulle-objc-exceptionhandlertable-private.h`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/mulle-objc-exceptionhandlertable-private.h) (part of the MulleObjC dependency). It consists of a static array of structures that pair **exception class identifiers** with **handler function pointers**. This design allows the runtime to perform a constant-time lookup when an exception is thrown, determining which unwind routine or cleanup code should execute.

## How the Exception Handler Table Works During Startup

### Static Registration via the Startup Module

The startup sequence begins in `src/MulleObjC-startup.m`, which imports the exception handler table definition:

```objc
#import <MulleObjC/mulle-objc-exceptionhandlertable-private.h>

```

This import makes the table visible to the `bang` function, the internal routine responsible for bootstrapping the MulleObjC universe.

### Early Installation Before Universe Creation

Inside `src/MulleObjC-startup.m`, the static function `bang` invokes `MulleObjCBang` (provided by the core runtime):

```objc
static void bang( struct _mulle_objc_universe *universe, 
                  struct _mulle_objc_universe *owner, 
                  void *args)
{
   MulleObjCBang( universe, owner, args);
}

```

`MulleObjCBang` registers the exception handler table with the runtime. This registration occurs **before** the global universe configuration is finalized and before any `+load` methods or static constructors (registered via `mulle-atinit`) execute. Consequently, if an exception is thrown during these fragile early stages, the runtime can consult the table and route the exception to the appropriate handler rather than aborting the process.

### Runtime Integration and Handler Dispatch

Once installed, the table is consulted by `MulleObjCExceptionHandler` and `MulleObjCExceptionHandlerRegister` (defined in the core MulleObjC library). When an exception is raised, the runtime performs a lookup in the table to find the matching handler for the exception class. This mechanism supports:

- **Stack unwinding** and cleanup of `finally` blocks.
- **Translation** of exceptions between different language domains (e.g., C++ to Objective-C).
- **Deterministic handling** of early initialization failures.

## Source Code References

| File | Repository | Purpose |
|------|------------|---------|
| `src/MulleObjC-startup.m` | `mulle-objc/mulleobjc-startup` | Imports the exception handler table and calls `MulleObjCBang` to register it. |
| [`mulle-objc-exceptionhandlertable-private.h`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/mulle-objc-exceptionhandlertable-private.h) | `mulle-objc/MulleObjC` (dependency) | Defines the table structure and registration macros. |
| `mulle-objc-startup-private.inc` | `mulle-objc/MulleObjC` (dependency) | Contains the implementation of `MulleObjCBang` that installs the table. |

## Practical Implications for Developers

- **Safety for Static Constructors**: You can safely use `@throw` or C++ exceptions inside `mulle-atinit` callbacks or `+load` methods because the handler table is already active.
- **Debugging**: Inspect the table via `nm` or a debugger to verify which handlers are registered before `main()` executes.
- **Mixed-Language Projects**: The table bridges C++ and Objective-C exception models, ensuring that a C++ `throw` propagating into Obj-C code is routed through the correct unwind logic.

## Summary

- The **exception handler table** is a static structure defined in [`mulle-objc-exceptionhandlertable-private.h`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/mulle-objc-exceptionhandlertable-private.h) that maps exception classes to handler functions.
- It is imported and registered in `src/MulleObjC-startup.m` via the `bang` function and `MulleObjCBang` **before** the universe is fully configured.
- Registration ensures that exceptions thrown during early initialization (static constructors, `+load`, `mulle-atinit`) are caught and processed safely.
- The table enables integration between C++ and Objective-C exception handling and provides deterministic cleanup via registered unwind routines.

## Frequently Asked Questions

### What happens if an exception is thrown before the handler table is registered?

If an exception is raised before `MulleObjCBang` installs the table, the runtime lacks the mapping between exception classes and handler functions. Consequently, the program will likely abort with an unhandled exception error because no unwind routine is available to process the throw.

### How does the exception handler table support mixed C++ and Objective-C code?

The table stores function pointers that bridge the two exception models. When a C++ exception propagates into Objective-C territory, the runtime consults the table to find a handler capable of translating or managing the C++ exception through Objective-C’s unwind mechanism, ensuring stack cleanup and `finally` blocks execute correctly.

### Can developers modify the exception handler table after startup?

While the table is technically mutable at runtime via `MulleObjCExceptionHandlerRegister`, the startup sequence in `mulleobjc-startup` initializes it to a safe, static state. After the universe is fully created, modifying the table is possible but rarely necessary unless you are implementing custom exception bridging or runtime plugins.

### Where is the exception handler table defined in the MulleObjC source?

The table structure and registration macros are defined in [`mulle-objc-exceptionhandlertable-private.h`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/mulle-objc-exceptionhandlertable-private.h), which resides in the `mulle-objc/MulleObjC` dependency. The startup repository (`mulle-objc/mulleobjc-startup`) imports this header in `src/MulleObjC-startup.m` to perform the actual registration during the `bang` phase.