You are getting an answer from the very early implementor of the fully-fledged structured exception mechanism, when it was available in CLU and Ada, but not in C++ or other more popular languages of that time.
For understanding, you need to understand how the general call-return mechanism works, based on the call stack
. If you don't clearly understand it, you will have to learn it; just read about it, as I am not going to explain it here. Anyway, a stack uses some piece of memory allocated per each thread. Anyway, the set of multiple calls and returns creates the array of data on the stack which stores all the return points, parameters and local variables at some given point of runtime. After multiple return, the execution will eventually get back to the very first call. The sequence of calls and returns, with all the actual values of parameters and local variable values is stored on the stack and is not pre-programmed, it can be different in each run of the thread of the whole application.
When you add exception handing, you have to create one more stack per thread: the stack of "try" points. Each point stores enough information to give the environment the possibility to get back to the tried point in one step from the point when an exception is thrown, but one of the important item in this information is to preserve the state of the call stack. In practice, this can be a values of couple of registers (stack pointer). There is a lot more, of course: you have to store the state of CPU. The implementation of it strongly depends on the CPU architecture. So, exception propagation is like a time machine: you can always get back in time to one of the "try" points. If you learned C or C++, you could be familiar with the "system" call called "long jump", a method which bypasses the usual call-return mechanism. This is like "saving" a computer game: you save some point in time and, in case of fatal problem, can get back as if nothing happened, but you somehow know about the problem. I already tried to describe that idea in my past answer: Does Exception in C# Constructor Cause Caller Assignment to Fail?
Now, why this exception information is a stack of objects, not just one "storage"? Because the thread goes through the sequence of calls and returns in some unpredictable order (in general case), and passes through some sequence of try points, so this sequence is also unpredictable, can be different in different runs. You push each try point on stack as the execution goes, and propagation of an exception when on is throws goes back in time, so you jump back to the last try point pushed on stack and pop it. Then, depending on the handler, you go into the new call-return sequence forward, or re-throw an exception of throw a different one (one of the distinct handling techniques), and the exception is propagated back in time to earlier and earlier try point. So, in all possible runs of the thread, you always push a try point to exception stack or pop it.
This is a highly simplified schema focusing mostly on runtime and the data structures.