Index: doc/theses/andrew_beach_MMath/code/CondCatch.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/CondCatch.java	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/CondCatch.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -6,23 +6,15 @@
 	static boolean should_catch = false;
 
-	static void throw_exception() throws EmptyException {
-		throw new EmptyException();
-	}
-
-	static void cond_catch() throws EmptyException {
-		try {
-			throw_exception();
-		} catch (EmptyException exc) {
-			if (!should_catch) {
-				throw exc;
-			}
-		}
-	}
-
 	private static long loop(int times) {
 		long startTime = System.nanoTime();
 		for (int count = 0 ; count < times ; ++count) {
 			try {
-				cond_catch();
+				try {
+					throw new EmptyException();
+				} catch (EmptyException exc) {
+					if (!should_catch) {
+						throw exc;
+					}
+				}
 			} catch (EmptyException exc) {
 				// ...
@@ -46,5 +38,5 @@
 
 		long time = loop(times);
-		System.out.println("Run-Time (ns): " + time);
+		System.out.format("Run-Time (s): %.1f%n", time / 1_000_000_000.);
 	}
 }
Index: c/theses/andrew_beach_MMath/code/CrossCatch.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/CrossCatch.java	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,35 +1,0 @@
-// Enter and Leave a Try Statement with a Termination Handler
-
-class NotRaisedException extends Exception {}
-
-public class CrossCatch {
-	private static boolean shouldThrow = false;
-
-	private static long loop(int times) {
-		long startTime = System.nanoTime();
-		for (int count = 0 ; count < times ; ++count) {
-			try {
-				if (shouldThrow) {
-					throw new NotRaisedException();
-				}
-			} catch (NotRaisedException e) {
-				// ...
-			}
-		}
-		long endTime = System.nanoTime();
-		return endTime - startTime;
-	}
-
-	public static void main(String[] args) {
-		int times = 1;
-		if (0 < args.length) {
-			times = Integer.parseInt(args[0]);
-		}
-
-		// Warm-Up:
-		loop(1000);
-
-		long time = loop(times);
-		System.out.println("Run-Time (ns): " + time);
-	}
-}
Index: c/theses/andrew_beach_MMath/code/CrossFinally.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/CrossFinally.java	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,31 +1,0 @@
-// Cross a Try Statement with a Finally Clause
-
-public class CrossFinally {
-	private static boolean shouldThrow = false;
-
-	private static long loop(int times) {
-		long startTime = System.nanoTime();
-		for (int count = 0 ; count < times ; ++count) {
-			try {
-				// ...
-			} finally {
-				// ...
-			}
-		}
-		long endTime = System.nanoTime();
-		return endTime - startTime;
-	}
-
-	public static void main(String[] args) {
-		int times = 1;
-		if (0 < args.length) {
-			times = Integer.parseInt(args[0]);
-		}
-
-		// Warm-Up:
-		loop(1000);
-
-		long time = loop(times);
-		System.out.println("Run-Time (ns): " + time);
-	}
-}
Index: doc/theses/andrew_beach_MMath/code/ResumeFixupEmpty.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/ResumeFixupEmpty.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/ResumeFixupEmpty.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,42 @@
+public class ResumeFixupEmpty {
+	public interface Fixup {
+		public int op(int fixup);
+	}
+
+	static void nounwind_fixup(int frames, Fixup raised_rtn) {
+		if (0 < frames) {
+			nounwind_fixup(frames - 1, raised_rtn);
+		} else {
+			int fixup = frames;
+			fixup = raised_rtn.op(fixup);
+		}
+	}
+
+	private static long loop(int times, int total_frames) {
+		Fixup raised = (int fixup) -> total_frames + 42; // use local scope => lexical link
+
+		long startTime = System.nanoTime();
+		for (int count = 0 ; count < times ; ++count) {
+			nounwind_fixup(total_frames, raised);
+		}
+		long endTime = System.nanoTime();
+		return endTime - startTime;
+	}
+
+	public static void main(String[] args) {
+		int times = 1;
+		int total_frames = 1;
+		if (0 < args.length) {
+			times = Integer.parseInt(args[0]);
+		}
+		if (1 < args.length) {
+			total_frames = Integer.parseInt(args[1]);
+		}
+
+		// Warm-Up:
+		loop(1000, total_frames);
+
+		long time = loop(times, total_frames);
+		System.out.format("Run-Time (s): %.1f%n", time / 1_000_000_000.);
+	}
+}
Index: doc/theses/andrew_beach_MMath/code/ResumeFixupOther.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/ResumeFixupOther.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/ResumeFixupOther.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,44 @@
+public class ResumeFixupOther {
+	public interface Fixup {
+		public int op(int fixup);
+	}
+
+	static void nounwind_fixup(int frames, Fixup raised_rtn, Fixup not_raised_rtn) {
+	 	Fixup not_raised = (int fixup) -> frames + 42; // use local scope => lexical link
+		if (0 < frames) {
+			nounwind_fixup(frames - 1, raised_rtn, not_raised);
+		} else {
+			int fixup = 17;
+			fixup = raised_rtn.op(fixup);
+		}
+	}
+
+	private static long loop(int times, int total_frames) {
+		Fixup raised = (int fixup) -> total_frames + 42; // use local scope => lexical link
+		Fixup not_raised = (int fixup) -> total_frames + 42; // use local scope => lexical link
+
+		long startTime = System.nanoTime();
+		for (int count = 0 ; count < times ; ++count) {
+		    nounwind_fixup(total_frames, raised, not_raised);
+		}
+		long endTime = System.nanoTime();
+		return endTime - startTime;
+	}
+
+	public static void main(String[] args) {
+		int times = 1;
+		int total_frames = 1;
+		if (0 < args.length) {
+			times = Integer.parseInt(args[0]);
+		}
+		if (1 < args.length) {
+			total_frames = Integer.parseInt(args[1]);
+		}
+
+		// Warm-Up:
+		loop(1000, total_frames);
+
+		long time = loop(times, total_frames);
+		System.out.format("Run-Time (s): %.1f%n", time / 1_000_000_000.);
+	}
+}
Index: doc/theses/andrew_beach_MMath/code/ThrowEmpty.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/ThrowEmpty.java	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/ThrowEmpty.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -39,5 +39,5 @@
 
 		long time = loop(times, total_frames);
-		System.out.println("Run-Time (ns): " + time);
+		System.out.format("Run-Time (s): %.1f%n", time / 1_000_000_000.);
 	}
 }
Index: doc/theses/andrew_beach_MMath/code/ThrowFinally.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/ThrowFinally.java	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/ThrowFinally.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -44,5 +44,5 @@
 
 		long time = loop(times, total_frames);
-		System.out.println("Run-Time (ns): " + time);
+		System.out.format("Run-Time (s): %.1f%n", time / 1_000_000_000.);
 	}
 }
Index: doc/theses/andrew_beach_MMath/code/ThrowOther.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/ThrowOther.java	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/ThrowOther.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -52,5 +52,5 @@
 
 		long time = loop(times, total_frames);
-		System.out.println("Run-Time (ns): " + time);
+		System.out.format("Run-Time (s): %.1f%n", time / 1_000_000_000.);
 	}
 }
Index: doc/theses/andrew_beach_MMath/code/TryCatch.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/TryCatch.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/TryCatch.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,35 @@
+// Enter and Leave a Try Statement with a Termination Handler
+
+class NotRaisedException extends Exception {}
+
+public class TryCatch {
+	private static boolean shouldThrow = false;
+
+	private static long loop(int times) {
+		long startTime = System.nanoTime();
+		for (int count = 0 ; count < times ; ++count) {
+			try {
+				if (shouldThrow) {
+					throw new NotRaisedException();
+				}
+			} catch (NotRaisedException e) {
+				// ...
+			}
+		}
+		long endTime = System.nanoTime();
+		return endTime - startTime;
+	}
+
+	public static void main(String[] args) {
+		int times = 1;
+		if (0 < args.length) {
+			times = Integer.parseInt(args[0]);
+		}
+
+		// Warm-Up:
+		loop(1000);
+
+		long time = loop(times);
+		System.out.format("Run-Time (s): %.1f%n", time / 1_000_000_000.);
+	}
+}
Index: doc/theses/andrew_beach_MMath/code/TryFinally.java
===================================================================
--- doc/theses/andrew_beach_MMath/code/TryFinally.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/TryFinally.java	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,31 @@
+// Enter and Leave a Try Statement with a Finally Handler
+
+public class TryFinally {
+	private static boolean shouldThrow = false;
+
+	private static long loop(int times) {
+		long startTime = System.nanoTime();
+		for (int count = 0 ; count < times ; ++count) {
+			try {
+				// ...
+			} finally {
+				// ...
+			}
+		}
+		long endTime = System.nanoTime();
+		return endTime - startTime;
+	}
+
+	public static void main(String[] args) {
+		int times = 1;
+		if (0 < args.length) {
+			times = Integer.parseInt(args[0]);
+		}
+
+		// Warm-Up:
+		loop(1000);
+
+		long time = loop(times);
+		System.out.format("Run-Time (s): %.1f%n", time / 1_000_000_000.);
+	}
+}
Index: doc/theses/andrew_beach_MMath/code/cond-catch.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/cond-catch.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/cond-catch.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,31 +3,18 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.h>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
-
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
+exception empty_exception;
+vtable(empty_exception) empty_vt;
 
 bool should_catch = false;
-
-void throw_exception() {
-	throw (empty_exception){&empty_vt};
-}
-
-void cond_catch() {
-	try {
-		throw_exception();
-	} catch (empty_exception * exc ; should_catch) {
-		asm volatile ("# catch block (conditional)");
-	}
-}
 
 int main(int argc, char * argv[]) {
 	unsigned int times = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		should_catch = strtol(argv[2], 0p, 10);
+		should_catch = (unsigned int)strto(argv[2], 0p, 2);
 	}
 
@@ -35,5 +22,7 @@
 	for (unsigned int count = 0 ; count < times ; ++count) {
 		try {
-			cond_catch();
+			throw (empty_exception){&empty_vt};
+		} catch (empty_exception * exc ; should_catch) {
+			asm volatile ("# catch block (conditional)");
 		} catch (empty_exception * exc) {
 			asm volatile ("# catch block (unconditional)");
@@ -41,4 +30,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/cond-catch.cpp
===================================================================
--- doc/theses/andrew_beach_MMath/code/cond-catch.cpp	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/cond-catch.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -4,5 +4,7 @@
 #include <exception>
 #include <iostream>
+#include <iomanip>
 
+using namespace std;
 using namespace std::chrono;
 
@@ -10,19 +12,4 @@
 
 bool should_catch = false;
-
-void throw_exception() {
-	throw EmptyException();
-}
-
-void cond_catch() {
-	try {
-		throw_exception();
-	} catch (EmptyException & exc) {
-		if (!should_catch) {
-			throw;
-		}
-		asm volatile ("# catch block (conditional)");
-	}
-}
 
 int main(int argc, char * argv[]) {
@@ -38,5 +25,12 @@
     for (unsigned int count = 0 ; count < times ; ++count) {
         try {
-			cond_catch();
+			try {
+				throw EmptyException();
+			} catch (EmptyException & exc) {
+				if (!should_catch) {
+					throw;
+				}
+				asm volatile ("# catch block (conditional)");
+			}
 		} catch (EmptyException &) {
 			asm volatile ("# catch block (unconditional)");
@@ -45,4 +39,4 @@
 	time_point<steady_clock> end_time = steady_clock::now();
 	nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time);
-	std::cout << "Run-Time (ns): " << duration.count() << std::endl;
+	cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. << endl;
 }
Index: doc/theses/andrew_beach_MMath/code/cond-catch.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/cond-catch.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/cond-catch.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+
+# Conditional Match (or Re-Raise)
+
+from time import thread_time_ns
+
+
+class EmptyException(Exception):
+    pass
+
+
+should_catch = False
+
+
+def main(argv):
+    times = 1
+    if 1 < len(argv):
+        times = int(argv[1])
+    if 2 < len(argv):
+        should_catch = 0 < int(argv[2])
+
+    start_time = thread_time_ns()
+    for count in range(times):
+        try:
+            try:
+                raise EmptyException()
+            except EmptyException as exc:
+                if not should_catch:
+                    raise
+        except EmptyException:
+            pass
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/cond-fixup.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/cond-fixup.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/cond-fixup.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,31 +3,18 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
-
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
+exception empty_exception;
+vtable(empty_exception) empty_vt;
 
 bool should_catch = false;
-
-void throw_exception() {
-	throwResume (empty_exception){&empty_vt};
-}
-
-void cond_catch() {
-	try {
-		throw_exception();
-	} catchResume (empty_exception * exc ; should_catch) {
-		asm volatile ("# fixup block (conditional)");
-	}
-}
 
 int main(int argc, char * argv[]) {
 	unsigned int times = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		should_catch = strtol(argv[2], 0p, 10);
+		should_catch = (unsigned int)strto(argv[2], 0p, 2);
 	}
 
@@ -35,5 +22,7 @@
 	for (unsigned int count = 0 ; count < times ; ++count) {
 		try {
-			cond_catch();
+			throwResume (empty_exception){&empty_vt};
+		} catchResume (empty_exception * exc ; should_catch) {
+			asm volatile ("# fixup block (conditional)");
 		} catchResume (empty_exception * exc) {
 			asm volatile ("# fixup block (unconditional)");
@@ -41,4 +30,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: c/theses/andrew_beach_MMath/code/cond_catch.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/cond_catch.py	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,47 +1,0 @@
-#!/usr/bin/env python3
-
-# Conditional Match (or Re-Raise)
-
-from time import thread_time_ns
-
-
-class EmptyException(Exception):
-    pass
-
-
-should_catch = False
-
-
-def throw_exception():
-    raise EmptyException()
-
-
-def cond_catch():
-    try:
-        throw_exception()
-    except EmptyException as exc:
-        if not should_catch:
-            raise
-
-
-def main(argv):
-    times = 1
-    if 1 < len(argv):
-        times = int(argv[1])
-    if 2 < len(argv):
-        should_catch = 0 < int(argv[2])
-
-    start_time = thread_time_ns()
-    for count in range(times):
-        try:
-            cond_catch();
-        except EmptyException:
-            pass
-
-    end_time = thread_time_ns()
-    print('Run-Time (ns):', end_time - start_time)
-
-
-if '__main__' == __name__:
-    import sys
-    main(sys.argv)
Index: c/theses/andrew_beach_MMath/code/cross-catch.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/cross-catch.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,31 +1,0 @@
-// Cross a Try Statement with a Termination Handler
-#include <clock.hfa>
-#include <exception.hfa>
-#include <fstream.hfa>
-#include <stdlib.hfa>
-
-EHM_EXCEPTION(not_raised_exception)();
-
-EHM_VIRTUAL_TABLE(not_raised_exception, not_vt);
-
-int main(int argc, char * argv[]) {
-	unsigned int times = 1;
-	volatile bool should_throw = false;
-	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
-	}
-
-	Time start_time = timeHiRes();
-	for (unsigned int count = 0 ; count < times ; ++count) {
-		try {
-			asm volatile ("# try block");
-			if (should_throw) {
-				throw (not_raised_exception){&not_vt};
-			}
-		} catch (not_raised_exception *) {
-			asm volatile ("# catch block");
-		}
-	}
-	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
-}
Index: c/theses/andrew_beach_MMath/code/cross-catch.cpp
===================================================================
--- doc/theses/andrew_beach_MMath/code/cross-catch.cpp	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,32 +1,0 @@
-// Cross a Try Statement with a Termination Handler
-#include <chrono>
-#include <cstdlib>
-#include <exception>
-#include <iostream>
-
-using namespace std::chrono;
-
-struct NotRaisedException : public std::exception {};
-
-int main(int argc, char * argv[]) {
-	unsigned int times = 1;
-	volatile bool should_throw = false;
-	if (1 < argc) {
-		times = strtol(argv[1], nullptr, 10);
-	}
-
-	time_point<steady_clock> start_time = steady_clock::now();
-	for (unsigned int count = 0 ; count < times ; ++count) {
-		try {
-			asm volatile ("# try block");
-			if (should_throw) {
-				throw NotRaisedException();
-			}
-		} catch (NotRaisedException &) {
-			asm volatile ("# catch block");
-		}
-	}
-	time_point<steady_clock> end_time = steady_clock::now();
-	nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time);
-	std::cout << "Run-Time (ns): " << duration.count() << std::endl;
-}
Index: c/theses/andrew_beach_MMath/code/cross-finally.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/cross-finally.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,31 +1,0 @@
-// Cross a Try Statement With Finally Clause
-#include <clock.hfa>
-#include <exception.hfa>
-#include <fstream.hfa>
-#include <stdlib.hfa>
-
-EHM_EXCEPTION(not_raised_exception)();
-
-EHM_VIRTUAL_TABLE(not_raised_exception, not_vt);
-
-int main(int argc, char * argv[]) {
-	unsigned int times = 1;
-	volatile bool should_throw = false;
-	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
-	}
-
-	Time start_time = timeHiRes();
-	for (unsigned int count = 0 ; count < times ; ++count) {
-		try {
-			asm volatile ("# try block");
-			if (should_throw) {
-				throw (not_raised_exception){&not_vt};
-			}
-		} finally {
-			asm volatile ("# finally block");
-		}
-	}
-	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
-}
Index: c/theses/andrew_beach_MMath/code/cross-resume.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/cross-resume.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,29 +1,0 @@
-// Cross a Try Statement With Finally Clause
-#include <clock.hfa>
-#include <exception.hfa>
-#include <fstream.hfa>
-#include <stdlib.hfa>
-
-EHM_EXCEPTION(not_raised_exception)();
-
-int main(int argc, char * argv[]) {
-	unsigned int times = 1;
-	unsigned int total_frames = 1;
-	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
-	}
-	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
-	}
-
-	Time start_time = timeHiRes();
-	for (unsigned int count = 0 ; count < times ; ++count) {
-		try {
-			asm volatile ("");
-		} catchResume (not_raised_exception *) {
-			asm volatile ("");
-		}
-	}
-	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
-}
Index: c/theses/andrew_beach_MMath/code/cross_catch.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/cross_catch.py	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,30 +1,0 @@
-#!/usr/bin/env python3
-
-# Cross a Try Statement with a Termination Handler
-
-from time import thread_time_ns
-
-
-class NotRaisedException(Exception):
-    pass
-
-
-def main(argv):
-    times = 1;
-    if 1 < len(argv):
-        times = int(argv[1])
-
-    start_time = thread_time_ns()
-    for count in range(times):
-        try:
-            pass
-        except NotRaisedException:
-            pass
-
-    end_time = thread_time_ns()
-    print('Run-Time (ns):', end_time - start_time)
-
-
-if '__main__' == __name__:
-    import sys
-    main(sys.argv)
Index: c/theses/andrew_beach_MMath/code/cross_finally.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/cross_finally.py	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,29 +1,0 @@
-#!/usr/bin/env python3
-
-# Cross a Try Statement With Finally Clause
-
-from time import thread_time_ns
-
-
-def main(argv):
-    times = 1;
-    total_frames = 1;
-    if 1 < len(argv):
-        times = int(argv[1])
-    if 2 < len(argv):
-        total_frames = int(argv[2])
-
-    start_time = thread_time_ns()
-    for count in range(times):
-        try:
-            pass
-        finally:
-            pass
-
-    end_time = thread_time_ns()
-    print('Run-Time (ns):', end_time - start_time)
-
-
-if '__main__' == __name__:
-    import sys
-    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/resume-detor.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-detor.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/resume-detor.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,9 +3,8 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
-
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
+exception empty_exception;
+vtable(empty_exception) empty_vt;
 
 struct WithDestructor {};
@@ -17,5 +16,4 @@
 void unwind_destructor(unsigned int frames) {
 	if (frames) {
-
 		WithDestructor object;
 		unwind_destructor(frames - 1);
@@ -29,8 +27,8 @@
 	unsigned int total_frames = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
+		total_frames = strto(argv[2], 0p, 10);
 	}
 
@@ -44,4 +42,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/resume-empty.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-empty.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/resume-empty.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,13 +3,12 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
+exception empty_exception;
+vtable(empty_exception) empty_vt;
 
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
-
-void unwind_empty(unsigned int frames) {
+void nounwind_empty(unsigned int frames) {
 	if (frames) {
-		unwind_empty(frames - 1);
+		nounwind_empty(frames - 1);
 	} else {
 		throwResume (empty_exception){&empty_vt};
@@ -21,14 +20,14 @@
 	unsigned int total_frames = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
+		total_frames = strto(argv[2], 0p, 10);
 	}
 
 	Time start_time = timeHiRes();
-	for (int count = 0 ; count < times ; ++count) {
+	for (unsigned int count = 0 ; count < times ; ++count) {
 		try {
-			unwind_empty(total_frames);
+			nounwind_empty(total_frames);
 		} catchResume (empty_exception *) {
 			asm volatile ("# fixup block");
@@ -36,4 +35,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/resume-finally.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-finally.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/resume-finally.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,9 +3,8 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
-
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
+exception empty_exception;
+vtable(empty_exception) empty_vt;
 
 void unwind_finally(unsigned int frames) {
@@ -25,8 +24,8 @@
 	unsigned int total_frames = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
+		total_frames = strto(argv[2], 0p, 10);
 	}
 
@@ -40,4 +39,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/resume-fixup-empty-f.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-fixup-empty-f.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/resume-fixup-empty-f.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,35 @@
+// Resume Across Fixup
+#include <clock.hfa>
+#include <fstream.hfa>
+#include <stdlib.hfa>									// strto
+
+void nounwind_fixup(unsigned int frames, void (*raised_rtn)(int &)) {
+	if (frames) {
+		nounwind_fixup(frames - 1, raised_rtn);
+	} else {
+		int fixup = 17;
+		raised_rtn(fixup);
+	}
+}
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	unsigned int total_frames = 1;
+	if (1 < argc) {
+		times = strto(argv[1], 0p, 10);
+	}
+	if (2 < argc) {
+		total_frames = strto(argv[2], 0p, 10);
+	}
+
+	void raised(int & fixup) {
+		fixup = total_frames + 42;						// use local scope => lexical link
+	}
+
+	Time start_time = timeHiRes();
+	for (unsigned int count = 0 ; count < times ; ++count) {
+		nounwind_fixup(total_frames, raised);
+	}
+	Time end_time = timeHiRes();
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
+}
Index: doc/theses/andrew_beach_MMath/code/resume-fixup-empty-r.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-fixup-empty-r.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/resume-fixup-empty-r.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,41 @@
+// Resume Across Empty Function
+#include <clock.hfa>
+#include <exception.hfa>
+#include <fstream.hfa>
+#include <stdlib.hfa>									// strto
+
+exception fixup_exception {
+	int & fixup;
+};
+vtable(fixup_exception) fixup_vt;
+
+void nounwind_empty(unsigned int frames) {
+	if (frames) {
+		nounwind_empty(frames - 1);
+	} else {
+		int fixup = 17;
+		throwResume (fixup_exception){&fixup_vt, fixup}; // change bad fixup
+	}
+}
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	unsigned int total_frames = 1;
+	if (1 < argc) {
+		times = strto(argv[1], 0p, 10);
+	}
+	if (2 < argc) {
+		total_frames = strto(argv[2], 0p, 10);
+	}
+
+	Time start_time = timeHiRes();
+	for (unsigned int count = 0 ; count < times ; ++count) {
+		try {
+			nounwind_empty(total_frames);
+		} catchResume (fixup_exception * ex) {
+			ex->fixup = total_frames + 42;
+		}
+	}
+	Time end_time = timeHiRes();
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
+}
Index: doc/theses/andrew_beach_MMath/code/resume-fixup-empty.cpp
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-fixup-empty.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/resume-fixup-empty.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,41 @@
+// Resume Across Fixup
+#include <chrono>
+#include <cstdlib>
+#include <exception>
+#include <iostream>
+#include <iomanip>
+#include <functional>
+
+using namespace std;
+using namespace chrono;
+
+void nounwind_fixup(unsigned int frames, function<void (int &)> raised_rtn ) {
+	if (frames) {
+		nounwind_fixup(frames - 1, raised_rtn);
+	} else {
+		int fixup = 17;
+		raised_rtn(fixup);
+	}
+}
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	unsigned int total_frames = 1;
+	if (1 < argc) {
+		times = strtol(argv[1], nullptr, 10);
+	}
+	if (2 < argc) {
+		total_frames = strtol(argv[2], nullptr, 10);
+	}
+
+	auto raised = [=] (int & fixup) -> void {
+					  fixup = total_frames + 42;		// use local scope => lexical link
+				  };
+	time_point<steady_clock> start_time = steady_clock::now();
+	for (unsigned int count = 0 ; count < times ; ++count) {
+		nounwind_fixup(total_frames, raised);
+	}
+	time_point<steady_clock> end_time = steady_clock::now();
+	nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time);
+	cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. << endl;
+}
Index: doc/theses/andrew_beach_MMath/code/resume-fixup-empty.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-fixup-empty.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/resume-fixup-empty.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+
+from time import thread_time_ns
+
+def nounwind_fixup(frames, raised_rtn):
+    if 0 < frames:
+        nounwind_fixup(frames - 1, raised_rtn)
+    else:
+        fixup = 17;
+        raised_rtn(fixup);
+
+
+def main(argv):
+    times = 1
+    total_frames = 1
+    if 1 < len(argv):
+        times = int(argv[1])
+    if 2 < len(argv):
+        total_frames = int(argv[2])
+
+    raised = lambda lfixup : total_frames + 42		# use local scope => lexical link
+    start_time = thread_time_ns()
+    for count in range(times):
+        nounwind_fixup(total_frames, raised)
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/resume-fixup-other-f.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-fixup-other-f.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/resume-fixup-other-f.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,46 @@
+// Resume Across Fixup
+#include <clock.hfa>
+#include <fstream.hfa>
+#include <stdlib.hfa>									// strto
+
+unsigned int frames;									// use global because of gcc thunk problem
+
+void nounwind_fixup(unsigned int dummy, void (*raised_rtn)(int &), void (*not_raised_rtn)(int &)) {
+	void not_raised(int & fixup) {
+		fixup = frames + 42;							// use local scope => lexical link
+	}
+
+	if (frames) {
+		frames -= 1;
+		nounwind_fixup(42, raised_rtn, not_raised);
+	} else {
+		int fixup = dummy;
+		raised_rtn(fixup);
+	}
+}
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	unsigned int total_frames = 1;
+	if (1 < argc) {
+		times = strto(argv[1], 0p, 10);
+	}
+	if (2 < argc) {
+		total_frames = strto(argv[2], 0p, 10);
+	}
+	frames = total_frames;
+
+	void raised(int & fixup) {
+		fixup = total_frames + 42;						// use local scope => lexical link
+	}
+	void not_raised(int & fixup) {
+		fixup = total_frames + 42;						// use local scope => lexical link
+	}
+
+	Time start_time = timeHiRes();
+	for (int count = 0 ; count < times ; ++count) {
+		nounwind_fixup(42, raised, not_raised);
+	}
+	Time end_time = timeHiRes();
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
+}
Index: doc/theses/andrew_beach_MMath/code/resume-fixup-other-r.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-fixup-other-r.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/resume-fixup-other-r.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,52 @@
+// Resume Across Other Handler
+#include <clock.hfa>
+#include <exception.hfa>
+#include <fstream.hfa>
+#include <stdlib.hfa>									// strto
+
+exception fixup_exception {
+	int & fixup;
+};
+vtable(fixup_exception) fixup_vt;
+exception not_raised_exception {
+	int & fixup;
+};
+
+unsigned int frames;									// use global because of gcc thunk problem
+
+void nounwind_other(unsigned int dummy) {
+	if (frames) {
+		frames -= 1;
+		try {
+			nounwind_other(42);
+		} catchResume (not_raised_exception * ex) {
+			ex->fixup = frames + 42;					// use local scope => lexical link
+		}
+	} else {
+		int fixup = dummy;
+		throwResume (fixup_exception){&fixup_vt, fixup}; // change bad fixup
+	}
+}
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	unsigned int total_frames = 1;
+	if (1 < argc) {
+		times = strto(argv[1], 0p, 10);
+	}
+	if (2 < argc) {
+		total_frames = strto(argv[2], 0p, 10);
+	}
+	frames = total_frames;
+
+	Time start_time = timeHiRes();
+	for (int count = 0 ; count < times ; ++count) {
+		try {
+			nounwind_other(42);
+		} catchResume (fixup_exception * ex) {
+			ex->fixup = total_frames + 42;
+		}
+	}
+	Time end_time = timeHiRes();
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
+}
Index: doc/theses/andrew_beach_MMath/code/resume-fixup-other.cpp
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-fixup-other.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/resume-fixup-other.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,49 @@
+// Resume Across Fixup
+#include <chrono>
+#include <cstdlib>
+#include <exception>
+#include <iostream>
+#include <iomanip>
+#include <functional>
+
+using namespace std;
+using namespace chrono;
+
+void nounwind_fixup(unsigned int frames, function<void (int &)> raised_rtn, function<void (int &)> not_raised_rtn ) {
+	auto not_raised = [=](int & fixup) -> void {
+						  fixup = frames + 42;			// use local scope => lexical link
+					  };
+
+	if (frames) {
+		nounwind_fixup(frames - 1, raised_rtn, not_raised);
+	} else {
+		int fixup = 17;
+		raised_rtn(fixup);
+	}
+}
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	unsigned int total_frames = 1;
+	if (1 < argc) {
+		times = strtol(argv[1], nullptr, 10);
+	}
+	if (2 < argc) {
+		total_frames = strtol(argv[2], nullptr, 10);
+	}
+
+	auto raised = [=] (int & fixup) -> void {
+					  fixup = total_frames + 42;		// use local scope => lexical link
+				  };
+	auto not_raised = [=] (int & fixup) -> void {
+						  fixup = total_frames + 42;	// use local scope => lexical link
+					  };
+
+	time_point<steady_clock> start_time = steady_clock::now();
+	for (unsigned int count = 0 ; count < times ; ++count) {
+		nounwind_fixup(total_frames, raised, not_raised);
+	}
+	time_point<steady_clock> end_time = steady_clock::now();
+	nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time);
+	cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. << endl;
+}
Index: doc/theses/andrew_beach_MMath/code/resume-fixup-other.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-fixup-other.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/resume-fixup-other.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+from time import thread_time_ns
+
+def nounwind_fixup(frames, raised_rtn, not_raised_rtn):
+    not_raised = lambda lfixup : frames + 42		# use local scope => lexical link
+    if 0 < frames:
+        nounwind_fixup(frames - 1, raised_rtn, not_raised)
+    else:
+        fixup = 17;
+        raised_rtn(fixup);
+
+
+def main(argv):
+    times = 1
+    total_frames = 1
+    if 1 < len(argv):
+        times = int(argv[1])
+    if 2 < len(argv):
+        total_frames = int(argv[2])
+
+    raised = lambda lfixup : total_frames + 42		# use local scope => lexical link
+    not_raised = lambda lfixup : total_frames + 42	# use local scope => lexical link
+    start_time = thread_time_ns()
+    for count in range(times):
+        nounwind_fixup(total_frames, raised, not_raised)
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/resume-other.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/resume-other.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/resume-other.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,16 +3,14 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
+exception empty_exception;
+vtable(empty_exception) empty_vt;
+exception not_raised_exception;
 
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
-
-EHM_EXCEPTION(not_raised_exception)();
-
-void unwind_other(unsigned int frames) {
+void nounwind_other(unsigned int frames) {
 	if (frames) {
 		try {
-			unwind_other(frames - 1);
+			nounwind_other(frames - 1);
 		} catchResume (not_raised_exception *) {
 			asm volatile ("# fixup block (stack)");
@@ -27,8 +25,8 @@
 	unsigned int total_frames = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
+		total_frames = strto(argv[2], 0p, 10);
 	}
 
@@ -36,5 +34,5 @@
 	for (int count = 0 ; count < times ; ++count) {
 		try {
-			unwind_other(total_frames);
+			nounwind_other(total_frames);
 		} catchResume (empty_exception *) {
 			asm volatile ("# fixup block (base)");
@@ -42,4 +40,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/run.sh
===================================================================
--- doc/theses/andrew_beach_MMath/code/run.sh	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/run.sh	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-readonly ALL_TESTS=(cond-match-{all,none} cross-{catch,finally} \
-		raise-{detor,empty,finally,other})
+readonly ALL_TESTS=(raise-{empty,detor,finally,other} try-{catch,finally} cond-match-{all,none} \
+		    raise-{fixup-empty,fixup-other})
 
 gen-file-name() (
@@ -18,5 +18,6 @@
 )
 
-readonly N=${1:-5}
+#readonly N=${1:-5}
+readonly N=${1:-1}
 readonly OUT_FILE=$(gen-file-name ${2:-run-%-$N})
 
Index: doc/theses/andrew_beach_MMath/code/test.sh
===================================================================
--- doc/theses/andrew_beach_MMath/code/test.sh	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/test.sh	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -4,10 +4,17 @@
 # test.sh LANGUAGE TEST
 #   Run the TEST in LANGUAGE.
+# test.sh -a
+#   Build all tests.
 # test.sh -b SOURCE_FILE...
 #   Build a test from SOURCE_FILE(s).
+# test.sh -c
+#   Clean all executables.
 # test.sh -v LANGUAGE TEST FILE
 #   View the result from TEST in LANGUAGE stored in FILE.
 
-readonly ITERATIONS=1000000 # 1 000 000, one million
+readonly ITERS_1M=1000000 # 1 000 000, one million
+readonly ITERS_10M=10000000 # 10 000 000, ten million
+readonly ITERS_100M=100000000 # 100 000 000, hundred million
+readonly ITERS_1000M=1000000000 # 1 000 000 000, billion
 readonly STACK_HEIGHT=100
 
@@ -24,8 +31,8 @@
 	*.cfa)
 		# Requires a symbolic link.
-		mmake "${1%.cfa}" "$1" ./cfa -DNDEBUG -nodebug -O3 "$1" -o "${1%.cfa}"
+		mmake "${1%.cfa}" "$1" cfa -DNDEBUG -nodebug -O3 "$1" -o "${1%.cfa}"
 		;;
 	*.cpp)
-		mmake "${1%.cpp}-cpp" "$1" g++ -DNDEBUG -O3 "$1" -o "${1%.cpp}-cpp"
+		mmake "${1%.cpp}-cpp" "$1" g++-10 -DNDEBUG -O3 "$1" -o "${1%.cpp}-cpp"
 		;;
 	*.java)
@@ -39,13 +46,24 @@
 )
 
-if [ "-b" = "$1" ]; then
+if [ "-a" = "$1" ]; then			# build all
+	for file in *.cfa *.cpp *.java; do
+		build $file
+	done
+	exit 0
+elif [ "-b" = "$1" ]; then			# build given
 	for file in "${@:2}"; do
 		build $file
 	done
 	exit 0
+elif [ "-c" = "$1" ]; then			# clean all
+	rm -f `basename -s ".cfa" -a *.cfa`
+	rm -f `basename -s ".cpp" -a *.cpp`
+	rm -f *-cpp
+	rm -f *.class
+	exit 0
 elif [ "-v" = "$1" -a 4 = "$#" ]; then
-    TEST_LANG="$2"
-    TEST_CASE="$3"
-    VIEW_FILE="$4"
+	TEST_LANG="$2"
+	TEST_CASE="$3"
+	VIEW_FILE="$4"
 elif [ 2 -eq "$#" ]; then
 	TEST_LANG="$1"
@@ -63,59 +81,73 @@
 
 case "$TEST_CASE" in
-cond-match-all)
-	CFAT="./cond-catch $ITERATIONS 1"
-	CFAR="./cond-fixup $ITERATIONS 1"
-	CPP="./cond-catch-cpp $ITERATIONS 1"
-	JAVA="java CondCatch $ITERATIONS 1"
-	PYTHON="./cond_catch.py $ITERATIONS 1"
-	;;
-cond-match-none)
-	CFAT="./cond-catch $ITERATIONS 0"
-	CFAR="./cond-fixup $ITERATIONS 0"
-	CPP="./cond-catch-cpp $ITERATIONS 0"
-	JAVA="java CondCatch $ITERATIONS 0"
-	PYTHON="./cond_catch.py $ITERATIONS 0"
-	;;
-cross-catch)
-	CFAT="./cross-catch $ITERATIONS"
-	CFAR="./cross-resume $ITERATIONS"
-	CPP="./cross-catch-cpp $ITERATIONS"
-	JAVA="java CrossCatch $ITERATIONS"
-	PYTHON="./cross_catch.py $ITERATIONS"
-	;;
-cross-finally)
-	CFAT="./cross-finally $ITERATIONS"
-	CFAR=unsupported
-	CPP=unsupported
-	JAVA="java CrossFinally $ITERATIONS"
-	PYTHON="./cross_finally.py $ITERATIONS"
+raise-empty)
+	CFAT="./throw-empty $ITERS_1M $STACK_HEIGHT"
+# see resume-fixup-empty-r	CFAR="./resume-empty $ITERS_1M $STACK_HEIGHT"
+	CPP="./throw-empty-cpp $ITERS_1M $STACK_HEIGHT"
+	JAVA="java ThrowEmpty $ITERS_1M $STACK_HEIGHT"
+	PYTHON="./throw-empty.py $ITERS_1M $STACK_HEIGHT"
 	;;
 raise-detor)
-	CFAT="./throw-detor $ITERATIONS $STACK_HEIGHT"
-	CFAR="./resume-detor $ITERATIONS $STACK_HEIGHT"
-	CPP="./throw-detor-cpp $ITERATIONS $STACK_HEIGHT"
+	CFAT="./throw-detor $ITERS_1M $STACK_HEIGHT"
+# N/A	CFAR="./resume-detor $ITERS_1M $STACK_HEIGHT"
+	CPP="./throw-detor-cpp $ITERS_1M $STACK_HEIGHT"
 	JAVA=unsupported
 	PYTHON=unsupported
 	;;
-raise-empty)
-	CFAT="./throw-empty $ITERATIONS $STACK_HEIGHT"
-	CFAR="./resume-empty $ITERATIONS $STACK_HEIGHT"
-	CPP="./throw-empty-cpp $ITERATIONS $STACK_HEIGHT"
-	JAVA="java ThrowEmpty $ITERATIONS $STACK_HEIGHT"
-	PYTHON="./throw_empty.py $ITERATIONS $STACK_HEIGHT"
-	;;
 raise-finally)
-	CFAT="./throw-finally $ITERATIONS $STACK_HEIGHT"
-	CFAR="./resume-finally $ITERATIONS $STACK_HEIGHT"
+	CFAT="./throw-finally $ITERS_1M $STACK_HEIGHT"
+# N/A	CFAR="./resume-finally $ITERS_1M $STACK_HEIGHT"
 	CPP=unsupported
-	JAVA="java ThrowFinally $ITERATIONS $STACK_HEIGHT"
-	PYTHON="./throw_finally.py $ITERATIONS $STACK_HEIGHT"
+	JAVA="java ThrowFinally $ITERS_1M $STACK_HEIGHT"
+	PYTHON="./throw-finally.py $ITERS_1M $STACK_HEIGHT"
 	;;
 raise-other)
-	CFAT="./throw-other $ITERATIONS $STACK_HEIGHT"
-	CFAR="./resume-other $ITERATIONS $STACK_HEIGHT"
-	CPP="./throw-other-cpp $ITERATIONS $STACK_HEIGHT"
-	JAVA="java ThrowOther $ITERATIONS $STACK_HEIGHT"
-	PYTHON="./throw_other.py $ITERATIONS $STACK_HEIGHT"
+	CFAT="./throw-other $ITERS_1M $STACK_HEIGHT"
+# N/A	CFAR="./resume-other $ITERS_1M $STACK_HEIGHT"
+	CPP="./throw-other-cpp $ITERS_1M $STACK_HEIGHT"
+	JAVA="java ThrowOther $ITERS_1M $STACK_HEIGHT"
+	PYTHON="./throw-other.py $ITERS_1M $STACK_HEIGHT"
+	;;
+try-catch)
+	CFAT="./try-catch $ITERS_1000M"
+	CFAR="./try-resume $ITERS_1000M"
+	CPP="./try-catch-cpp $ITERS_1000M"
+	JAVA="java TryCatch $ITERS_1000M"
+	PYTHON="./try-catch.py $ITERS_1000M"
+	;;
+try-finally)
+	CFAT="./try-finally $ITERS_1000M"
+	CFAR=unsupported
+	CPP=unsupported
+	JAVA="java TryFinally $ITERS_1000M"
+	PYTHON="./try-finally.py $ITERS_1000M"
+	;;
+cond-match-all)
+	CFAT="./cond-catch $ITERS_10M 1"
+	CFAR="./cond-fixup $ITERS_10M 1"
+	CPP="./cond-catch-cpp $ITERS_10M 1"
+	JAVA="java CondCatch $ITERS_10M 1"
+	PYTHON="./cond-catch.py $ITERS_10M 1"
+	;;
+cond-match-none)
+	CFAT="./cond-catch $ITERS_10M 0"
+	CFAR="./cond-fixup $ITERS_10M 0"
+	CPP="./cond-catch-cpp $ITERS_10M 0"
+	JAVA="java CondCatch $ITERS_10M 0"
+	PYTHON="./cond-catch.py $ITERS_10M 0"
+	;;
+raise-fixup-empty)
+	CFAT="./resume-fixup-empty-f $ITERS_10M $STACK_HEIGHT"
+	CFAR="./resume-fixup-empty-r $ITERS_10M $STACK_HEIGHT"
+	CPP="./resume-fixup-empty-cpp $ITERS_10M $STACK_HEIGHT"
+	JAVA="java ResumeFixupEmpty $ITERS_10M $STACK_HEIGHT"
+	PYTHON="./resume-fixup-empty.py $ITERS_10M $STACK_HEIGHT"
+	;;
+raise-fixup-other)
+	CFAT="./resume-fixup-other-f $ITERS_10M $STACK_HEIGHT"
+	CFAR="./resume-fixup-other-r $ITERS_10M $STACK_HEIGHT"
+	CPP="./resume-fixup-other-cpp $ITERS_10M $STACK_HEIGHT"
+	JAVA="java ResumeFixupOther $ITERS_10M $STACK_HEIGHT"
+	PYTHON="./resume-fixup-other.py $ITERS_10M $STACK_HEIGHT"
 	;;
 *)
@@ -126,12 +158,12 @@
 
 case "$TEST_LANG" in
-cfa-t) CALL="$CFAT";;
-cfa-r) CALL="$CFAR";;
-cpp) CALL="$CPP";;
-java) CALL="$JAVA";;
-python) CALL="$PYTHON";;
-*)
-	echo "No such language: $TEST_LANG" >&2
-	exit 2
+	cfa-t) CALL="$CFAT";;
+	cfa-r) CALL="$CFAR";;
+	cpp) CALL="$CPP";;
+	java) CALL="$JAVA";;
+	python) CALL="$PYTHON";;
+	*)
+		echo "No such language: $TEST_LANG" >&2
+		exit 2
 	;;
 esac
@@ -140,6 +172,6 @@
 
 if [ -n "$VIEW_FILE" ]; then
-    grep -A 1 -B 0 "$CALL" "$VIEW_FILE" | sed -n -e 's!Run-Time (ns): !!;T;p'
-    exit
+	grep -A 1 -B 0 "$CALL" "$VIEW_FILE" | sed -n -e 's!Run-Time (ns): !!;T;p'
+	exit
 fi
 
Index: doc/theses/andrew_beach_MMath/code/throw-detor.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-detor.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/throw-detor.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,9 +3,8 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
-
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
+exception empty_exception;
+vtable(empty_exception) empty_vt;
 
 struct WithDestructor {};
@@ -28,8 +27,8 @@
 	unsigned int total_frames = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
+		total_frames = strto(argv[2], 0p, 10);
 	}
 
@@ -43,4 +42,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/throw-detor.cpp
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-detor.cpp	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/throw-detor.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -4,5 +4,7 @@
 #include <exception>
 #include <iostream>
+#include <iomanip>
 
+using namespace std;
 using namespace std::chrono;
 
@@ -44,4 +46,4 @@
 	time_point<steady_clock> end_time = steady_clock::now();
 	nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time);
-	std::cout << "Run-Time (ns): " << duration.count() << std::endl;
+	cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. << endl;
 }
Index: doc/theses/andrew_beach_MMath/code/throw-empty.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-empty.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/throw-empty.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,9 +3,8 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
-
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
+exception empty_exception;
+vtable(empty_exception) empty_vt;
 
 void unwind_empty(unsigned int frames) {
@@ -21,8 +20,8 @@
 	unsigned int total_frames = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
+		total_frames = strto(argv[2], 0p, 10);
 	}
 
@@ -36,4 +35,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/throw-empty.cpp
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-empty.cpp	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/throw-empty.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -4,5 +4,7 @@
 #include <exception>
 #include <iostream>
+#include <iomanip>
 
+using namespace std;
 using namespace std::chrono;
 
@@ -37,4 +39,4 @@
 	time_point<steady_clock> end_time = steady_clock::now();
 	nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time);
-	std::cout << "Run-Time (ns): " << duration.count() << std::endl;
+	cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. << endl;
 }
Index: doc/theses/andrew_beach_MMath/code/throw-empty.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-empty.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/throw-empty.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+
+# Throw Across Empty Function
+
+from time import thread_time_ns
+
+
+class EmptyException(Exception):
+    pass
+
+
+def unwind_empty(frames):
+    if 0 < frames:
+        unwind_empty(frames - 1)
+    else:
+        raise EmptyException()
+
+
+def main(argv):
+    times = 1
+    total_frames = 1
+    if 1 < len(argv):
+        times = int(argv[1])
+    if 2 < len(argv):
+        total_frames = int(argv[2])
+
+    start_time = thread_time_ns()
+    for count in range(times):
+        try:
+            unwind_empty(total_frames)
+        except EmptyException:
+            pass
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/throw-finally.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-finally.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/throw-finally.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,18 +3,21 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
+exception empty_exception;
+vtable(empty_exception) empty_vt;
 
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
+unsigned int frames;									// use global because of gcc thunk problem
 
-void unwind_finally(unsigned int frames) {
+void unwind_finally(unsigned int dummy) {
 	if (frames) {
+		frames -= 1;
 		try {
-			unwind_finally(frames - 1);
+			unwind_finally(42);
 		} finally {
 			asm volatile ("# finally block");
 		}
 	} else {
+		dummy = 42;
 		throw (empty_exception){&empty_vt};
 	}
@@ -25,14 +28,15 @@
 	unsigned int total_frames = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
+		total_frames = strto(argv[2], 0p, 10);
 	}
+	frames = total_frames;
 
 	Time start_time = timeHiRes();
 	for (int count = 0 ; count < times ; ++count) {
 		try {
-			unwind_finally(total_frames);
+			unwind_finally(42);
 		} catch (empty_exception *) {
 			asm volatile ("# catch block");
@@ -40,4 +44,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/throw-finally.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-finally.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/throw-finally.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+
+# Throw Across Finally
+
+from time import thread_time_ns
+
+
+class EmptyException(Exception):
+    pass
+
+
+def unwind_finally(frames):
+    if 0 < frames:
+        try:
+            unwind_finally(frames - 1)
+        finally:
+            pass
+    else:
+        raise EmptyException()
+
+
+def main(argv):
+    times = 1
+    total_frames = 1
+    if 1 < len(argv):
+        times = int(argv[1])
+    if 2 < len(argv):
+        total_frames = int(argv[2])
+
+    start_time = thread_time_ns()
+    for count in range(times):
+        try:
+            unwind_finally(total_frames)
+        except EmptyException:
+            pass
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/throw-other.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-other.cfa	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/throw-other.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,20 +3,22 @@
 #include <exception.hfa>
 #include <fstream.hfa>
-#include <stdlib.hfa>
+#include <stdlib.hfa>									// strto
 
-EHM_EXCEPTION(empty_exception)();
+exception empty_exception;
+vtable(empty_exception) empty_vt;
+exception not_raised_exception;
 
-EHM_VIRTUAL_TABLE(empty_exception, empty_vt);
+unsigned int frames;									// use global because of gcc thunk problem
 
-EHM_EXCEPTION(not_raised_exception)();
-
-void unwind_other(unsigned int frames) {
+void unwind_other(unsigned int dummy) {
 	if (frames) {
+		frames -= 1;
 		try {
-			unwind_other(frames - 1);
+			unwind_other(42);
 		} catch (not_raised_exception *) {
 			asm volatile ("# catch block (stack)");
 		}
 	} else {
+		dummy = 42;
 		throw (empty_exception){&empty_vt};
 	}
@@ -27,14 +29,15 @@
 	unsigned int total_frames = 1;
 	if (1 < argc) {
-		times = strtol(argv[1], 0p, 10);
+		times = strto(argv[1], 0p, 10);
 	}
 	if (2 < argc) {
-		total_frames = strtol(argv[2], 0p, 10);
+		total_frames = strto(argv[2], 0p, 10);
 	}
+	frames = total_frames;
 
 	Time start_time = timeHiRes();
 	for (int count = 0 ; count < times ; ++count) {
 		try {
-			unwind_other(total_frames);
+			unwind_other(42);
 		} catch (empty_exception *) {
 			asm volatile ("# catch block (base)");
@@ -42,4 +45,4 @@
 	}
 	Time end_time = timeHiRes();
-	sout | "Run-Time (ns): " | (end_time - start_time)`ns;
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
 }
Index: doc/theses/andrew_beach_MMath/code/throw-other.cpp
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-other.cpp	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/code/throw-other.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -4,5 +4,7 @@
 #include <exception>
 #include <iostream>
+#include <iomanip>
 
+using namespace std;
 using namespace std::chrono;
 
@@ -43,4 +45,4 @@
 	time_point<steady_clock> end_time = steady_clock::now();
 	nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time);
-	std::cout << "Run-Time (ns): " << duration.count() << std::endl;
+	cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. << endl;
 }
Index: doc/theses/andrew_beach_MMath/code/throw-other.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-other.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/throw-other.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+
+# Throw Across Other Handler
+
+from time import thread_time_ns
+
+
+class EmptyException(Exception):
+    pass
+
+
+class NotRaisedException(Exception):
+    pass
+
+
+def unwind_other(frames):
+    if 0 < frames:
+        try:
+            unwind_other(frames - 1)
+        except NotRaisedException:
+            pass
+    else:
+        raise EmptyException()
+
+
+def main(argv):
+    times = 1
+    total_frames = 1
+    if 1 < len(argv):
+        times = int(argv[1])
+    if 2 < len(argv):
+        total_frames = int(argv[2])
+
+    start_time = thread_time_ns()
+    for count in range(times):
+        try:
+            unwind_other(total_frames)
+        except EmptyException:
+            pass
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/throw-with.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw-with.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/throw-with.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+
+# Throw Across With Statement (closest thing Python has to a destructor)
+
+from time import thread_time_ns
+
+
+class EmptyException(Exception):
+    pass
+
+
+class EmptyContextManager:
+
+    def __enter__(self):
+        pass
+
+    def __exit__(self, exception_type, exception_value, traceback):
+        pass
+
+
+def unwind_with(frames):
+    if 0 < frames:
+        with EmptyContextManager():
+            unwind_with(frames - 1)
+    else:
+        raise EmptyException()
+
+
+def main(argv):
+    times = 1
+    total_frames = 1
+    if 1 < len(argv):
+        times = int(argv[1])
+    if 2 < len(argv):
+        total_frames = int(argv[2])
+
+    start_time = thread_time_ns()
+    for count in range(times):
+        try:
+            unwind_with(total_frames)
+        except EmptyException:
+            pass
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: c/theses/andrew_beach_MMath/code/throw_empty.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw_empty.py	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#!/usr/bin/env python3
-
-# Throw Across Empty Function
-
-from time import thread_time_ns
-
-
-class EmptyException(Exception):
-    pass
-
-
-def unwind_empty(frames):
-    if 0 < frames:
-        unwind_empty(frames - 1)
-    else:
-        raise EmptyException()
-
-
-def main(argv):
-    times = 1
-    total_frames = 1
-    if 1 < len(argv):
-        times = int(argv[1])
-    if 2 < len(argv):
-        total_frames = int(argv[2])
-
-    start_time = thread_time_ns()
-    for count in range(times):
-        try:
-            unwind_empty(total_frames)
-        except EmptyException:
-            pass
-
-    end_time = thread_time_ns()
-    print('Run-Time (ns):', end_time - start_time)
-
-
-if '__main__' == __name__:
-    import sys
-    main(sys.argv)
Index: c/theses/andrew_beach_MMath/code/throw_finally.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw_finally.py	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,43 +1,0 @@
-#!/usr/bin/env python3
-
-# Throw Across Finally
-
-from time import thread_time_ns
-
-
-class EmptyException(Exception):
-    pass
-
-
-def unwind_finally(frames):
-    if 0 < frames:
-        try:
-            unwind_finally(frames - 1)
-        finally:
-            pass
-    else:
-        raise EmptyException()
-
-
-def main(argv):
-    times = 1
-    total_frames = 1
-    if 1 < len(argv):
-        times = int(argv[1])
-    if 2 < len(argv):
-        total_frames = int(argv[2])
-
-    start_time = thread_time_ns()
-    for count in range(times):
-        try:
-            unwind_finally(total_frames)
-        except EmptyException:
-            pass
-
-    end_time = thread_time_ns()
-    print('Run-Time (ns):', end_time - start_time)
-
-
-if '__main__' == __name__:
-    import sys
-    main(sys.argv)
Index: c/theses/andrew_beach_MMath/code/throw_other.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw_other.py	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,47 +1,0 @@
-#!/usr/bin/env python3
-
-# Throw Across Other Handler
-
-from time import thread_time_ns
-
-
-class EmptyException(Exception):
-    pass
-
-
-class NotRaisedException(Exception):
-    pass
-
-
-def unwind_other(frames):
-    if 0 < frames:
-        try:
-            unwind_other(frames - 1)
-        except NotRaisedException:
-            pass
-    else:
-        raise EmptyException()
-
-
-def main(argv):
-    times = 1
-    total_frames = 1
-    if 1 < len(argv):
-        times = int(argv[1])
-    if 2 < len(argv):
-        total_frames = int(argv[2])
-
-    start_time = thread_time_ns()
-    for count in range(times):
-        try:
-            unwind_other(total_frames)
-        except EmptyException:
-            pass
-
-    end_time = thread_time_ns()
-    print('Run-Time (ns):', end_time - start_time)
-
-
-if '__main__' == __name__:
-    import sys
-    main(sys.argv)
Index: c/theses/andrew_beach_MMath/code/throw_with.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/throw_with.py	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ 	(revision )
@@ -1,50 +1,0 @@
-#!/usr/bin/env python3
-
-# Throw Across With Statement (closest thing Python has to a destructor)
-
-from time import thread_time_ns
-
-
-class EmptyException(Exception):
-    pass
-
-
-class EmptyContextManager:
-
-    def __enter__(self):
-        pass
-
-    def __exit__(self, exception_type, exception_value, traceback):
-        pass
-
-
-def unwind_with(frames):
-    if 0 < frames:
-        with EmptyContextManager():
-            unwind_with(frames - 1)
-    else:
-        raise EmptyException()
-
-
-def main(argv):
-    times = 1
-    total_frames = 1
-    if 1 < len(argv):
-        times = int(argv[1])
-    if 2 < len(argv):
-        total_frames = int(argv[2])
-
-    start_time = thread_time_ns()
-    for count in range(times):
-        try:
-            unwind_with(total_frames)
-        except EmptyException:
-            pass
-
-    end_time = thread_time_ns()
-    print('Run-Time (ns):', end_time - start_time)
-
-
-if '__main__' == __name__:
-    import sys
-    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/try-catch.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/try-catch.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/try-catch.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,30 @@
+// Cross a Try Statement with a Termination Handler
+#include <clock.hfa>
+#include <exception.hfa>
+#include <fstream.hfa>
+#include <stdlib.hfa>									// strto
+
+exception not_raised_exception;
+vtable(not_raised_exception) not_vt;
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	volatile bool should_throw = false;
+	if (1 < argc) {
+		times = strto(argv[1], 0p, 10);
+	}
+
+	Time start_time = timeHiRes();
+	for (unsigned int count = 0 ; count < times ; ++count) {
+		try {
+			asm volatile ("# try block");
+			if (should_throw) {
+				throw (not_raised_exception){&not_vt};
+			}
+		} catch (not_raised_exception *) {
+			asm volatile ("# catch block");
+		}
+	}
+	Time end_time = timeHiRes();
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
+}
Index: doc/theses/andrew_beach_MMath/code/try-catch.cpp
===================================================================
--- doc/theses/andrew_beach_MMath/code/try-catch.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/try-catch.cpp	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,34 @@
+// Cross a Try Statement with a Termination Handler
+#include <chrono>
+#include <cstdlib>
+#include <exception>
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+using namespace std::chrono;
+
+struct NotRaisedException : public std::exception {};
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	volatile bool should_throw = false;
+	if (1 < argc) {
+		times = strtol(argv[1], nullptr, 10);
+	}
+
+	time_point<steady_clock> start_time = steady_clock::now();
+	for (unsigned int count = 0 ; count < times ; ++count) {
+		try {
+			asm volatile ("# try block");
+			if (should_throw) {
+				throw NotRaisedException();
+			}
+		} catch (NotRaisedException &) {
+			asm volatile ("# catch block");
+		}
+	}
+	time_point<steady_clock> end_time = steady_clock::now();
+	nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time);
+	cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. << endl;
+}
Index: doc/theses/andrew_beach_MMath/code/try-catch.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/try-catch.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/try-catch.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+
+# Cross a Try Statement with a Termination Handler
+
+from time import thread_time_ns
+
+
+class NotRaisedException(Exception):
+    pass
+
+
+def main(argv):
+    times = 1;
+    if 1 < len(argv):
+        times = int(argv[1])
+
+    start_time = thread_time_ns()
+    for count in range(times):
+        try:
+            pass
+        except NotRaisedException:
+            pass
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/try-finally.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/try-finally.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/try-finally.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,30 @@
+// Cross a Try Statement With Finally Clause
+#include <clock.hfa>
+#include <exception.hfa>
+#include <fstream.hfa>
+#include <stdlib.hfa>									// strto
+
+exception not_raised_exception;
+vtable(not_raised_exception) not_vt;
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	volatile bool should_throw = false;
+	if (1 < argc) {
+		times = strto(argv[1], 0p, 10);
+	}
+
+	Time start_time = timeHiRes();
+	for (unsigned int count = 0 ; count < times ; ++count) {
+		try {
+			asm volatile ("# try block");
+			if (should_throw) {
+				throw (not_raised_exception){&not_vt};
+			}
+		} finally {
+			asm volatile ("# finally block");
+		}
+	}
+	Time end_time = timeHiRes();
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
+}
Index: doc/theses/andrew_beach_MMath/code/try-finally.py
===================================================================
--- doc/theses/andrew_beach_MMath/code/try-finally.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/try-finally.py	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+
+# Cross a Try Statement With Finally Clause
+
+from time import thread_time_ns
+
+
+def main(argv):
+    times = 1;
+    total_frames = 1;
+    if 1 < len(argv):
+        times = int(argv[1])
+    if 2 < len(argv):
+        total_frames = int(argv[2])
+
+    start_time = thread_time_ns()
+    for count in range(times):
+        try:
+            pass
+        finally:
+            pass
+
+    end_time = thread_time_ns()
+    print('Run-Time (s) {:.1f}:'.format((end_time - start_time) / 1_000_000_000.))
+
+
+if '__main__' == __name__:
+    import sys
+    main(sys.argv)
Index: doc/theses/andrew_beach_MMath/code/try-resume.cfa
===================================================================
--- doc/theses/andrew_beach_MMath/code/try-resume.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
+++ doc/theses/andrew_beach_MMath/code/try-resume.cfa	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -0,0 +1,29 @@
+// Cross a Try Statement With Finally Clause
+#include <clock.hfa>
+#include <exception.hfa>
+#include <fstream.hfa>
+#include <stdlib.hfa>									// strto
+
+exception not_raised_exception;
+
+int main(int argc, char * argv[]) {
+	unsigned int times = 1;
+	unsigned int total_frames = 1;
+	if (1 < argc) {
+		times = strto(argv[1], 0p, 10);
+	}
+	if (2 < argc) {
+		total_frames = strto(argv[2], 0p, 10);
+	}
+
+	Time start_time = timeHiRes();
+	for (unsigned int count = 0 ; count < times ; ++count) {
+		try {
+			asm volatile ("");
+		} catchResume (not_raised_exception *) {
+			asm volatile ("");
+		}
+	}
+	Time end_time = timeHiRes();
+	sout | "Run-Time (s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);
+}
Index: doc/theses/andrew_beach_MMath/performance.tex
===================================================================
--- doc/theses/andrew_beach_MMath/performance.tex	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/performance.tex	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -3,7 +3,8 @@
 
 Performance is of secondary importance for most of this project.
-Instead, the focus is to get the features working. The only performance
+Instead, the focus was to get the features working. The only performance
 requirement is to ensure the tests for correctness run in a reasonable
-amount of time.
+amount of time. Hence, a few basic performance tests were performed to
+check this requirement.
 
 \section{Test Set-Up}
@@ -14,19 +15,19 @@
 C++ is the most comparable language because both it and \CFA use the same
 framework, libunwind.
-In fact, the comparison is almost entirely a quality of implementation
-comparison: \CFA's EHM has had significantly less time to be optimized and
+In fact, the comparison is almost entirely a quality of implementation.
+Specifically, \CFA's EHM has had significantly less time to be optimized and
 does not generate its own assembly. It does have a slight advantage in that
 there are some features it handles directly instead of through utility functions,
-but otherwise \Cpp has a significant advantage.
-
-Java is another very popular language with similar termination semantics.
-It is implemented in a very different environment, a virtual machine with
+but otherwise \Cpp should have a significant advantage.
+
+Java is a popular language with similar termination semantics, but
+it is implemented in a very different environment, a virtual machine with
 garbage collection.
 It also implements the @finally@ clause on @try@ blocks allowing for a direct
 feature-to-feature comparison.
-As with \Cpp, Java's implementation is mature, optimizations
+As with \Cpp, Java's implementation is mature, optimized
 and has extra features.
 
-Python is used as an alternative point of comparison because of the \CFA EHM's
+Python is used as an alternative comparison because of the \CFA EHM's
 current performance goals, which is not to be prohibitively slow while the
 features are designed and examined. Python has similar performance goals for
@@ -36,13 +37,16 @@
 resumption exceptions. Even the older programming languages with resumption
 seem to be notable only for having resumption.
-So instead, resumption is compared to a less similar but much more familiar
-feature, termination exceptions.
+So instead, resumption is compared to its simulation in other programming
+languages using fixup functions that are explicitly passed for correction or
+logging purposes.
+% So instead, resumption is compared to a less similar but much more familiar
+%feature, termination exceptions.
 
 All tests are run inside a main loop that repeatedly performs a test.
 This approach avoids start-up or tear-down time from
 affecting the timing results.
-Each test is run a million times.
-The Java versions of the test run this loop an extra 1000 times before
-beginning to actual test to ``warm-up" the JVM.
+Each test is run a N times (configurable from the command line).
+The Java tests runs the main loop 1000 times before
+beginning the actual test to ``warm-up" the JVM.
 
 Timing is done internally, with time measured immediately before and
@@ -66,5 +70,5 @@
 
 The tests are compiled with gcc-10 for \CFA and g++-10 for \Cpp. Java is
-compiled with 11.0.11. Python with 3.8. The tests were run on:
+compiled with version 11.0.11. Python with version 3.8. The tests were run on:
 \begin{itemize}[nosep]
 \item
@@ -73,4 +77,7 @@
 AMD 6380 Abu Dhabi 16-core 4$\times$socket \lstinline{@} 2.5 GHz running Linux v5.11.0-25
 \end{itemize}
+Two kinds of hardware architecture allows discriminating any implementation and
+architectural effects.
+
 
 % We don't use catch-alls but if we did:
@@ -84,55 +91,88 @@
 
 \paragraph{Raise and Handle}
-The first group measures the cost of a try statement when exceptions are raised
-and \emph{the stack is unwound}.  Each test has has a repeating function like
-the following
-\begin{cfa}
+This group measures the cost of a try statement when exceptions are raised and
+the stack is unwound (termination) or not unwound (resumption).  Each test has
+has a repeating function like the following
+\begin{lstlisting}[language=CFA,{moredelim=**[is][\color{red}]{@}{@}}]
 void unwind_empty(unsigned int frames) {
 	if (frames) {
-		unwind_empty(frames - 1);
+		@unwind_empty(frames - 1);@ // AUGMENTED IN OTHER EXPERIMENTS
 	} else throw (empty_exception){&empty_vt};
 }
-\end{cfa}
-which is called M times, where each call recurses to a depth of N, an
+\end{lstlisting}
+which is called N times, where each call recurses to a depth of R (configurable from the command line), an
 exception is raised, the stack is a unwound, and the exception caught.
 \begin{itemize}[nosep]
 \item Empty:
-This test measures the cost of raising (stack walking) an exception through empty
-empty stack frames to an empty handler. (see above)
+For termination, this test measures the cost of raising (stack walking) an
+exception through empty stack frames from the bottom of the recursion to an
+empty handler, and unwinding the stack. (see above code)
+
+\medskip
+For resumption, this test measures the same raising cost but does not unwind
+the stack. For languages without resumption, a fixup function is to the bottom
+of the recursion and called to simulate a fixup operation at that point.
+\begin{cfa}
+void nounwind_fixup(unsigned int frames, void (*raised_rtn)(int &)) {
+	if (frames) {
+		nounwind_fixup(frames - 1, raised_rtn);
+	} else {
+		int fixup = 17;
+		raised_rtn(fixup);
+	}
+}
+\end{cfa}
+where the passed fixup function is:
+\begin{cfa}
+void raised(int & fixup) {
+	fixup = 42;
+}
+\end{cfa}
+For comparison, a \CFA version passing a function is also included.
 \item Destructor:
-
-This test measures the cost of raising an exception through non-empty frames
-where each frame has an object requiring destruction, to an empty
-handler. Hence, there are N destructor calls during unwinding.
-\begin{cfa}
-if (frames) {
+This test measures the cost of raising an exception through non-empty frames,
+where each frame has an object requiring destruction, from the bottom of the
+recursion to an empty handler. Hence, there are N destructor calls during
+unwinding.
+
+\medskip
+This test is not meaningful for resumption because the stack is only unwound as
+the recursion returns.
+\begin{cfa}
 	WithDestructor object;
-	unwind_empty(frames - 1);
+	unwind_destructor(frames - 1);
 \end{cfa}
 \item Finally:
 This test measures the cost of establishing a try block with an empty finally
-clause on the front side of the recursion and running the empty finally clause
-on the back side of the recursion during stack unwinding.
-\begin{cfa}
-if (frames) {
+clause on the front side of the recursion and running the empty finally clauses
+during stack unwinding from the bottom of the recursion to an empty handler.
+\begin{cfa}
 	try {
 		unwind_finally(frames - 1);
 	} finally {}
 \end{cfa}
+
+\medskip
+This test is not meaningful for resumption because the stack is only unwound as
+the recursion returns.
 \item Other Handler:
-This test is like the finally test but the try block has a catch clause for an
-exception that is not raised, so catch matching is executed during stack
-unwinding but the match never successes until the catch at the bottom of the
-stack.
-\begin{cfa}
-if (frames) {
+For termination, this test is like the finally test but the try block has a
+catch clause for an exception that is not raised, so catch matching is executed
+during stack unwinding but the match never successes until the catch at the
+bottom of the recursion.
+\begin{cfa}
 	try {
 		unwind_other(frames - 1);
 	} catch (not_raised_exception *) {}
 \end{cfa}
+
+\medskip
+For resumption, this test measures the same raising cost but does not unwind
+the stack. For languages without resumption, the same fixup function is passed
+and called.
 \end{itemize}
 
-\paragraph{Cross Try Statement}
-The next group measures just the cost of executing a try statement so
+\paragraph{Try/Handle/Finally Statement}
+This group measures just the cost of executing a try statement so
 \emph{there is no stack unwinding}.  Hence, the program main loops N times
 around:
@@ -143,14 +183,14 @@
 \begin{itemize}[nosep]
 \item Handler:
-The try statement has a handler.
+The try statement has a handler (catch/resume).
 \item Finally:
-The try statement replaces the handler with a finally clause.
+The try statement has a finally clause.
 \end{itemize}
 
 \paragraph{Conditional Matching}
-This final group measures the cost of conditional matching.
+This group measures the cost of conditional matching.
 Only \CFA implements the language level conditional match,
-the other languages must mimic with an ``unconditional" match (it still
-checks the exception's type) and conditional re-raise if it was not supposed
+the other languages mimic with an ``unconditional" match (it still
+checks the exception's type) and conditional re-raise if it is not suppose
 to handle that exception.
 \begin{center}
@@ -180,4 +220,9 @@
 The condition is always false. (Never matches or always re-raises.)
 \end{itemize}
+
+\medskip
+\noindent
+All omitted test code for other languages is functionally identical to the \CFA
+tests or simulated, and available online~\cite{CforallExceptionBenchmarks}.
 
 %\section{Cost in Size}
@@ -192,12 +237,50 @@
 
 \section{Results}
-In cases where a feature is not supported by a language the test is skipped
-for that language.
-\PAB{Report all values.
-
-Similarly, if a test does not change between resumption
-and termination in \CFA, then only one test is written and the result
-was put into the termination column.
-}
+One result not directly related to \CFA but important to keep in
+mind is that, for exceptions, the standard intuition about which languages
+should go faster often does not hold. For example, there are a few cases where Python out-performs
+\CFA, \Cpp and Java. The most likely explanation is that, since exceptions are
+rarely considered to be the common case, the more optimized languages
+make that case expense. In addition, languages with high-level
+representations have a much easier time scanning the stack as there is less
+to decode.
+
+Tables~\ref{t:PerformanceTermination} and~\ref{t:PerformanceResumption} show
+the test results for termination and resumption, respectively.  In cases where
+a feature is not supported by a language, the test is skipped for that language
+(marked N/A).  For some Java experiments it was impossible to measure certain
+effects because the JIT corrupted the test (marked N/C). No workaround was
+possible~\cite{Dice21}.  To get experiments in the range of 1--100 seconds, the
+number of times an experiment is run (N) is varied (N is marked beside each
+experiment, e.g., 1M $\Rightarrow$ 1 million test iterations).
+
+An anomaly exists with gcc nested functions used as thunks for implementing
+much of the \CFA EHM. If a nested-function closure captures local variables in
+its lexical scope, performance dropped by a factor of 10.  Specifically, in try
+statements of the form:
+\begin{cfa}
+	try {
+		unwind_other(frames - 1);
+	} catch (not_raised_exception *) {}
+\end{cfa}
+the try block is hoisted into a nested function and the variable @frames@ is
+the local parameter to the recursive function, which triggers the anomaly. The
+workaround is to remove the recursion parameter and make it a global variable
+that is explicitly decremented outside of the try block (marked with a ``*''):
+\begin{cfa}
+	frames -= 1;
+	try {
+		unwind_other();
+	} catch (not_raised_exception *) {}
+\end{cfa}
+To make comparisons fair, a dummy parameter is added and the dummy value passed
+in the recursion. Note, nested functions in gcc are rarely used (if not
+completely unknown) and must follow the C calling convention, unlike \Cpp
+lambdas, so it is not surprising if there are performance issues efficiently
+capturing closures.
+
+% Similarly, if a test does not change between resumption
+% and termination in \CFA, then only one test is written and the result
+% was put into the termination column.
 
 % Raw Data:
@@ -235,19 +318,4 @@
 % Match None    & 0.0 & 0.0 &  9476060146 & 0.0 & 0.0 \\
 
-\begin{tabular}{|l|c c c c c|}
-\hline
-              & \CFA (Terminate) & \CFA (Resume) & \Cpp & Java & Python \\
-\hline
-Raise Empty   & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-Raise D'tor   & 0.0 & 0.0 & 0.0 & N/A & N/A \\
-Raise Finally & 0.0 & 0.0 & N/A & 0.0 & 0.0 \\
-Raise Other   & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-Cross Handler & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-Cross Finally & 0.0 & N/A & N/A & 0.0 & 0.0 \\
-Match All     & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-Match None    & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-\hline
-\end{tabular}
-
 % run-plg7a-a.sat
 % ---------------
@@ -284,41 +352,110 @@
 % Match None    & 0.0 & 0.0 &  7829059869 & 0.0 & 0.0 \\
 
-% PLG7A (in seconds)
-\begin{tabular}{|l|c c c c c|}
+\begin{table}
+\centering
+\caption{Performance Results Termination (sec)}
+\label{t:PerformanceTermination}
+\begin{tabular}{|r|*{2}{|r r r r|}}
 \hline
-              & \CFA (Terminate) & \CFA (Resume) & \Cpp & Java & Python \\
-\hline
-Raise Empty   & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-Raise D'tor   & 0.0 & 0.0 & 0.0 & N/A & N/A \\
-Raise Finally & 0.0 & 0.0 & N/A & 0.0 & 0.0 \\
-Raise Other   & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-Cross Handler & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-Cross Finally & 0.0 & N/A & N/A & 0.0 & 0.0 \\
-Match All     & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
-Match None    & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
+			& \multicolumn{4}{c||}{AMD}		& \multicolumn{4}{c|}{ARM}	\\
+\cline{2-9}
+N\hspace{8pt}		& \multicolumn{1}{c}{\CFA} & \multicolumn{1}{c}{\Cpp} & \multicolumn{1}{c}{Java} & \multicolumn{1}{c||}{Python} &
+			  \multicolumn{1}{c}{\CFA} & \multicolumn{1}{c}{\Cpp} & \multicolumn{1}{c}{Java} & \multicolumn{1}{c|}{Python} \\
+\hline						                                    
+Throw Empty (1M)	& 3.4	& 2.8	& 18.3	& 23.4		& 3.7	& 3.2	& 15.5	& 14.8	\\
+Throw D'tor (1M)	& 48.4	& 23.6	& N/A	& N/A		& 64.2	& 29.0	& N/A	& N/A	\\
+Throw Finally (1M)	& 3.4*	& N/A	& 17.9	& 29.0		& 4.1*	& N/A	& 15.6	& 19.0	\\
+Throw Other (1M)	& 3.6*	& 23.2	& 18.2	& 32.7		& 4.0*	& 24.5	& 15.5	& 21.4	\\
+Try/Catch (100M)	& 6.0	& 0.9	& N/C	& 37.4		& 10.0	& 0.8	& N/C	& 32.2	\\
+Try/Finally (100M)	& 0.9	& N/A	& N/C	& 44.1		& 0.8	& N/A	& N/C	& 37.3	\\
+Match All (10M)		& 32.9	& 20.7	& 13.4	& 4.9		& 36.2	& 24.5	& 12.0	& 3.1	\\
+Match None (10M)	& 32.7	& 50.3	& 11.0	& 5.1		& 36.3	& 71.9	& 12.3	& 4.2	\\
 \hline
 \end{tabular}
-
-One result not directly related to \CFA but important to keep in
-mind is that, for exceptions, the standard intuition about which languages
-should go faster often does not hold. For example, there are cases where Python out-performs
-\Cpp and Java. The most likely explanation is that, since exceptions are
-rarely considered to be the common case, the more optimized languages
-make that case expense. In addition, languages with high-level
-representations have a much easier time scanning the stack as there is less
-to decode.
-
-This observation means that while \CFA does not actually keep up with Python in every
-case, it is usually no worse than roughly half the speed of \Cpp. This performance is good
-enough for the prototyping purposes of the project.
+\end{table}
+
+\begin{table}
+\centering
+\small
+\caption{Performance Results Resumption (sec)}
+\label{t:PerformanceResumption}
+\setlength{\tabcolsep}{5pt}
+\begin{tabular}{|r|*{2}{|r r r r|}}
+\hline
+			& \multicolumn{4}{c||}{AMD}		& \multicolumn{4}{c|}{ARM}	\\
+\cline{2-9}
+N\hspace{8pt}		& \multicolumn{1}{c}{\CFA (R/F)} & \multicolumn{1}{c}{\Cpp} & \multicolumn{1}{c}{Java} & \multicolumn{1}{c||}{Python} &
+			  \multicolumn{1}{c}{\CFA (R/F)} & \multicolumn{1}{c}{\Cpp} & \multicolumn{1}{c}{Java} & \multicolumn{1}{c|}{Python} \\
+\hline						                                    
+Resume Empty (10M)	& 3.8/3.5	& 14.7	& 2.3	& 176.1	& 0.3/0.1	& 8.9	& 1.2	& 119.9	\\
+Resume Other (10M)	& 4.0*/0.1*	& 21.9	& 6.2	& 381.0	& 0.3*/0.1*	& 13.2	& 5.0	& 290.7	\\
+Try/Resume (100M)	& 8.8		& N/A	& N/A	& N/A	& 12.3		& N/A	& N/A	& N/A	\\
+Match All (10M)		& 0.3		& N/A	& N/A	& N/A	& 0.3		& N/A	& N/A	& N/A	\\
+Match None (10M)	& 0.3		& N/A	& N/A	& N/A	& 0.4		& N/A	& N/A	& N/A	\\
+\hline
+\end{tabular}
+\end{table}
+
+As stated, the performance tests are not attempting to compare exception
+handling across languages.  The only performance requirement is to ensure the
+\CFA EHM implementation runs in a reasonable amount of time, given its
+constraints. In general, the \CFA implement did very well. Each of the tests is
+analysed.
+\begin{description}
+\item[Throw/Resume Empty]
+For termination, \CFA is close to \Cpp, where other languages have a higher cost.
+
+For resumption, \CFA is better than the fixup simulations in the other languages, except Java.
+The \CFA results on the ARM computer for both resumption and function simulation are particularly low;
+I have no explanation for this anomaly, except the optimizer has managed to remove part of the experiment.
+Python has a high cost for passing the lambda during the recursion.
+
+\item[Throw D'tor]
+For termination, \CFA is twice the cost of \Cpp.
+The higher cost for \CFA must be related to how destructors are handled.
+
+\item[Throw Finally]
+\CFA is better than the other languages with a @finally@ clause, which is the
+same for termination and resumption.
+
+\item[Throw/Resume Other]
+For termination, \CFA is better than the other languages.
+
+For resumption, \CFA is equal to or better the other languages.
+Again, the \CFA results on the ARM computer for both resumption and function simulation are particularly low.
+Python has a high cost for passing the lambda during the recursion.
+
+\item[Try/Catch/Resume]
+For termination, installing a try statement is more expressive than \Cpp
+because the try components are hoisted into local functions.  At runtime, these
+functions are than passed to libunwind functions to set up the try statement.
+\Cpp zero-cost try-entry accounts for its performance advantage.
+
+For resumption, there are similar costs to termination to set up the try
+statement but libunwind is not used.
+
+\item[Try/Finally]
+Setting up a try finally is less expensive in \CFA than setting up handlers,
+and is significantly less than other languages.
+
+\item[Throw/Resume Match All]
+For termination, \CFA is close to the other language simulations.
+
+For resumption, the stack unwinding is much faster because it does not use
+libunwind.  Instead resumption is just traversing a linked list with each node
+being the next stack frame with the try block.
+
+\item[Throw/Resume Match None]
+The same results as for Match All.
+\end{description}
+
+\begin{comment}
+This observation means that while \CFA does not actually keep up with Python in
+every case, it is usually no worse than roughly half the speed of \Cpp. This
+performance is good enough for the prototyping purposes of the project.
 
 The test case where \CFA falls short is Raise Other, the case where the
 stack is unwound including a bunch of non-matching handlers.
 This slowdown seems to come from missing optimizations.
-
-Importantly, there is a huge slowdown in \Cpp's results bringing that brings
-\CFA's performance back in that roughly half speed area. However many other
-\CFA benchmarks increase their run-time by a similar amount falling far
-behind their \Cpp counter-parts.
 
 This suggests that the performance issue in Raise Other is just an
@@ -364,2 +501,84 @@
 The difference in relative performance does show that there are savings to
 be made by performing the check without catching the exception.
+\end{comment}
+
+
+\begin{comment}
+From: Dave Dice <dave.dice@oracle.com>
+To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
+Subject: Re: [External] : JIT
+Date: Mon, 16 Aug 2021 01:21:56 +0000
+
+> On 2021-8-15, at 7:14 PM, Peter A. Buhr <pabuhr@uwaterloo.ca> wrote:
+> 
+> My student is trying to measure the cost of installing a try block with a
+> finally clause in Java.
+> 
+> We tried the random trick (see below). But if the try block is comment out, the
+> results are the same. So the program measures the calls to the random number
+> generator and there is no cost for installing the try block.
+> 
+> Maybe there is no cost for a try block with an empty finally, i.e., the try is
+> optimized away from the get-go.
+
+There's quite a bit of optimization magic behind the HotSpot curtains for
+try-finally.  (I sound like the proverbial broken record (:>)).
+
+In many cases we can determine that the try block can't throw any exceptions,
+so we can elide all try-finally plumbing.  In other cases, we can convert the
+try-finally to normal if-then control flow, in the case where the exception is
+thrown into the same method.  This makes exceptions _almost cost-free.  If we
+actually need to "physically" rip down stacks, then things get expensive,
+impacting both the throw cost, and inhibiting other useful optimizations at the
+catch point.  Such "true" throws are not just expensive, they're _very
+expensive.  The extremely aggressive inlining used by the JIT helps, because we
+can convert cases where a heavy rip-down would normally needed back into simple
+control flow.
+
+Other quirks involve the thrown exception object.  If it's never accessed then
+we're apply a nice set of optimizations to avoid its construction.  If it's
+accessed but never escapes the catch frame (common) then we can also cheat.
+And if we find we're hitting lots of heavy rip-down cases, the JIT will
+consider recompilation - better inlining -- to see if we can merge the throw
+and catch into the same physical frame, and shift to simple branches.
+
+In your example below, System.out.print() can throw, I believe.  (I could be
+wrong, but most IO can throw).  Native calls that throw will "unwind" normally
+in C++ code until they hit the boundary where they reenter java emitted code,
+at which point the JIT-ed code checks for a potential pending exception.  So in
+a sense the throw point is implicitly after the call to the native method, so
+we can usually make those cases efficient.
+
+Also, when we're running in the interpreter and warming up, we'll notice that
+the == 42 case never occurs, and so when we start to JIT the code, we elide the
+call to System.out.print(), replacing it (and anything else which appears in
+that if x == 42 block) with a bit of code we call an "uncommon trap".  I'm
+presuming we encounter 42 rarely.  So if we ever hit the x == 42 case, control
+hits the trap, which triggers synchronous recompilation of the method, this
+time with the call to System.out.print() and, because of that, we now to adapt
+the new code to handle any traps thrown by print().  This is tricky stuff, as
+we may need to rebuild stack frames to reflect the newly emitted method.  And
+we have to construct a weird bit of "thunk" code that allows us to fall back
+directly into the newly emitted "if" block.  So there's a large one-time cost
+when we bump into the uncommon trap and recompile, and subsequent execution
+might get slightly slower as the exception could actually be generated, whereas
+before we hit the trap, we knew the exception could never be raised.
+
+Oh, and things also get expensive if we need to actually fill in the stack
+trace associated with the exception object.  Walking stacks is hellish.
+
+Quite a bit of effort was put into all this as some of the specjvm benchmarks
+showed significant benefit.
+
+It's hard to get sensible measurements as the JIT is working against you at
+every turn.  What's good for the normal user is awful for anybody trying to
+benchmark.  Also, all the magic results in fairly noisy and less reproducible
+results.
+
+Regards
+Dave
+
+p.s., I think I've mentioned this before, but throwing in C++ is grim as
+unrelated throws in different threads take common locks, so nothing scales as
+you might expect.
+\end{comment}
Index: doc/theses/andrew_beach_MMath/uw-ethesis.bib
===================================================================
--- doc/theses/andrew_beach_MMath/uw-ethesis.bib	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ doc/theses/andrew_beach_MMath/uw-ethesis.bib	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -2,27 +2,15 @@
 % For use with BibTeX
 
-@book{goossens.book,
-	author =	"Michel Goossens and Frank Mittelbach and 
-			 Alexander Samarin",
-	title =		"The \LaTeX\ Companion",
-	year = 		"1994",
-	publisher =	"Addison-Wesley",
-	address = 	"Reading, Massachusetts"
+@misc{Dice21,
+    author	= {Dave Dice},
+    year	= 2021,
+    month	= aug,
+    howpublished= {personal communication}
 }
 
-@book{knuth.book,
-        author =        "Donald Knuth",
-        title =         "The \TeX book",
-        year =          "1986",
-        publisher =     "Addison-Wesley",
-        address =       "Reading, Massachusetts"
+@misc{CforallExceptionBenchmarks,
+    contributer	= {pabuhr@plg},
+    key		= {Cforall Exception Benchmarks},
+    author	= {{\textsf{C}{$\mathbf{\forall}$} Exception Benchmarks}},
+    howpublished= {\href{https://github.com/cforall/ExceptionBenchmarks_SPE20}{https://\-github.com/\-cforall/\-ExceptionBenchmarks\_SPE20}},
 }
-
-@book{lamport.book,
-	author =        "Leslie Lamport",
-	title =         "\LaTeX\ --- A Document Preparation System",
-        edition =       "Second",
-	year = 		"1994",
-	publisher = 	"Addison-Wesley",
-	address =       "Reading, Massachusetts"
-}
Index: libcfa/prelude/builtins.c
===================================================================
--- libcfa/prelude/builtins.c	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ libcfa/prelude/builtins.c	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -10,6 +10,6 @@
 // Created On       : Fri Jul 21 16:21:03 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 21 13:31:34 2021
-// Update Count     : 129
+// Last Modified On : Sat Aug 14 08:45:54 2021
+// Update Count     : 133
 //
 
@@ -107,4 +107,8 @@
 #endif // __SIZEOF_INT128__
 
+// for-control index constraints
+// forall( T | { void ?{}( T &, zero_t ); void ?{}( T &, one_t ); T ?+=?( T &, T ); T ?-=?( T &, T ); int ?<?( T, T ); } )
+// static inline T __for_control_index_constraints__( T t ) { return t; }
+
 // exponentiation operator implementation
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision d00d58175bd0e1df5524a7109ec9127ccb133764)
+++ src/Parser/parser.yy	(revision fe8aa2182b90d16d7e1074b52e0dbd330f9287cf)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 20 22:03:04 2021
-// Update Count     : 5031
+// Last Modified On : Sun Aug  8 09:14:44 2021
+// Update Count     : 5038
 //
 
@@ -185,4 +185,5 @@
 		type = new ExpressionNode( new CastExpr( maybeMoveBuild<Expression>(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
 	} // if
+//	type = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__for_control_index_constraints__" ) ) ), type ) );
 	return new ForCtrl(
 		distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
