// Testing Interactions Between Termination and Resumption #include #include "except-io.hfa" exception star {}; exception moon {}; vtable(star) star_vt; vtable(moon) moon_vt; int main(int argc, char * argv[]) { // Resume falls back to terminate. try { throwResume (star){&star_vt}; } catch (star *) { sout | "caught as termination"; } // Variant of the above to check timing. try { loud_region a = "try block with resume throw"; throwResume (star){&star_vt}; } catch (star *) { sout | "caught as termination"; } catchResume (star *) { sout | "intermediate rethrow"; throwResume; } sout | nl; // Resume does not catch terminate. try { try { throw (star){&star_vt}; } catchResume (star *) { sout | "resume catch on terminate"; } } catchResume (star *) { sout | "resume catch on terminate"; } catch (star *) { sout | "terminate catch on terminate"; } sout | nl; // Terminate does not catch resume. try { try { throwResume (star){&star_vt}; } catch (star *) { sout | "terminate catch on resume"; } } catch (star *) { sout | "terminate catch on resume"; } catchResume (star *) { sout | "resume catch on resume"; } sout | nl; // Resume a termination exception. try { try { try { throw (star){&star_vt}; } catchResume (star *) { sout | "inner resume catch (error)"; } } catch (star * error) { sout | "termination catch, will resume"; throwResume *error; } } catchResume (star *) { sout | "outer resume catch"; } sout | nl; // Terminate a resumption exception. try { try { try { throwResume (star){&star_vt}; } catch (star *) { sout | "inner termination catch"; } } catchResume (star * error) { sout | "resumption catch, will terminate"; throw *error; } } catch (star *) { sout | "outer terminate catch (error)"; } sout | nl; // Unwinding a resumption catch does not break the system. try { try { try { try { sout | "throwing resume moon"; throwResume (moon){&moon_vt}; } catch (star *) { sout | "termination catch"; } sout | "throwing resume star"; throwResume (star){&star_vt}; } catchResume (star *) { sout | "resumption star catch"; } } catchResume (moon *) { sout | "resumption moon catch, will terminate"; throw (star){&star_vt}; } } catchResume (star *) { sout | "outermost catch (error)"; } }