| [307a732] | 1 | // Draft of tests for exception handling.
 | 
|---|
| [fcc88a4] | 2 | // Outdated: The integer constant exceptions need to be replaced with virtual
 | 
|---|
 | 3 | // exceptions for the new system.
 | 
|---|
| [307a732] | 4 | 
 | 
|---|
| [ad0be81] | 5 | // ERROR: exceptions do not interact with ^?{} properly.
 | 
|---|
 | 6 | 
 | 
|---|
| [307a732] | 7 | #include <stdio.h>
 | 
|---|
 | 8 | #include <stdbool.h>
 | 
|---|
 | 9 | 
 | 
|---|
| [e9145a3] | 10 | #include "except-mac.h"
 | 
|---|
 | 11 | TRIVIAL_EXCEPTION(yin)
 | 
|---|
 | 12 | TRIVIAL_EXCEPTION(yang)
 | 
|---|
 | 13 | TRIVIAL_EXCEPTION(zen)
 | 
|---|
 | 14 | 
 | 
|---|
 | 15 | 
 | 
|---|
| [cbce272] | 16 | // Local type to mark exits from scopes. (see ERROR)
 | 
|---|
| [307a732] | 17 | struct signal_exit {
 | 
|---|
 | 18 |         const char * area;
 | 
|---|
 | 19 | };
 | 
|---|
 | 20 | 
 | 
|---|
 | 21 | void ?{}(signal_exit * this, const char * area) {
 | 
|---|
 | 22 |         this->area = area;
 | 
|---|
 | 23 | }
 | 
|---|
 | 24 | 
 | 
|---|
 | 25 | void ^?{}(signal_exit * this) {
 | 
|---|
 | 26 |         printf("Exiting: %s\n", this->area);
 | 
|---|
 | 27 | //      sout | "Exiting:" | this->area | endl;
 | 
|---|
 | 28 | }
 | 
|---|
 | 29 | 
 | 
|---|
| [cbce272] | 30 | 
 | 
|---|
| [e9145a3] | 31 | // Mark throws: make sure to only pass in exception types.
 | 
|---|
 | 32 | forall(dtype T)
 | 
|---|
 | 33 | void terminate(T * except_value) {
 | 
|---|
| [307a732] | 34 |         signal_exit a = {"terminate function"};
 | 
|---|
| [e9145a3] | 35 |         THROW(except_value);
 | 
|---|
| [307a732] | 36 |         printf("terminate returned\n");
 | 
|---|
 | 37 | }
 | 
|---|
 | 38 | 
 | 
|---|
| [e9145a3] | 39 | forall(dtype T)
 | 
|---|
 | 40 | void resume(T * except_value) {
 | 
|---|
| [307a732] | 41 |         signal_exit a = {"resume function"};
 | 
|---|
| [e9145a3] | 42 |         THROW_RESUME(except_value);
 | 
|---|
| [307a732] | 43 |         printf("resume returned\n");
 | 
|---|
 | 44 | }
 | 
|---|
 | 45 | 
 | 
|---|
 | 46 | // Termination Test: Two handlers: no catch, catch
 | 
|---|
 | 47 | void bar() {
 | 
|---|
 | 48 |         signal_exit a = {"bar function"};
 | 
|---|
 | 49 |         try {
 | 
|---|
| [e9145a3] | 50 |                 terminate(&(zen){});
 | 
|---|
 | 51 |         } catch (yin * error) {
 | 
|---|
 | 52 |                 printf("bar caught exception yin.\n");
 | 
|---|
| [307a732] | 53 |         }
 | 
|---|
 | 54 | }
 | 
|---|
 | 55 | 
 | 
|---|
 | 56 | void foo() {
 | 
|---|
 | 57 |         signal_exit a = {"foo function"};
 | 
|---|
 | 58 |         try {
 | 
|---|
 | 59 |                 bar();
 | 
|---|
| [e9145a3] | 60 |         } catch (yang * error) {
 | 
|---|
 | 61 |                 printf("foo caught exception yang.\n");
 | 
|---|
 | 62 |         } catch (zen * error) {
 | 
|---|
 | 63 |                 printf("foo caught exception zen.\n");
 | 
|---|
| [307a732] | 64 |         }
 | 
|---|
 | 65 | }
 | 
|---|
 | 66 | 
 | 
|---|
 | 67 | // Resumption Two Handler Test: no catch, catch.
 | 
|---|
 | 68 | void beta() {
 | 
|---|
 | 69 |         signal_exit a = {"beta function"};
 | 
|---|
 | 70 |         try {
 | 
|---|
| [e9145a3] | 71 |                 zen x;
 | 
|---|
 | 72 |                 resume(&x);
 | 
|---|
 | 73 |         } catchResume (yin * error) {
 | 
|---|
 | 74 |                 printf("beta caught exception yin\n");
 | 
|---|
| [307a732] | 75 |         }
 | 
|---|
 | 76 | }
 | 
|---|
 | 77 | 
 | 
|---|
 | 78 | void alpha() {
 | 
|---|
 | 79 |         signal_exit a = {"alpha function"};
 | 
|---|
 | 80 |         try {
 | 
|---|
 | 81 |                 beta();
 | 
|---|
| [e9145a3] | 82 |         } catchResume (yang * error) {
 | 
|---|
 | 83 |                 printf("alpha caught exception yang\n");
 | 
|---|
 | 84 |         } catchResume (zen * error) {
 | 
|---|
 | 85 |                 printf("alpha caught exception zen\n");
 | 
|---|
| [307a732] | 86 |         }
 | 
|---|
 | 87 | }
 | 
|---|
 | 88 | 
 | 
|---|
 | 89 | // Finally Test:
 | 
|---|
 | 90 | void farewell(bool jump) {
 | 
|---|
 | 91 |         try {
 | 
|---|
 | 92 |                 if (jump) {
 | 
|---|
 | 93 |                         printf("jump out of farewell\n");
 | 
|---|
 | 94 |                         goto endoffunction;
 | 
|---|
 | 95 |                 } else {
 | 
|---|
 | 96 |                         printf("walk out of farewell\n");
 | 
|---|
 | 97 |                 }
 | 
|---|
 | 98 |         } finally {
 | 
|---|
 | 99 |                 printf("See you next time\n");
 | 
|---|
 | 100 |         }
 | 
|---|
 | 101 |         endoffunction:
 | 
|---|
 | 102 |         printf("leaving farewell\n");
 | 
|---|
 | 103 | }
 | 
|---|
 | 104 | 
 | 
|---|
 | 105 | // Resume-to-Terminate Test:
 | 
|---|
 | 106 | void fallback() {
 | 
|---|
 | 107 |         try {
 | 
|---|
| [e9145a3] | 108 |                 zen x;
 | 
|---|
 | 109 |                 resume(&x);
 | 
|---|
 | 110 |         } catch (zen * error) {
 | 
|---|
 | 111 |                 printf("fallback caught termination zen\n");
 | 
|---|
| [307a732] | 112 |         }
 | 
|---|
 | 113 | }
 | 
|---|
 | 114 | 
 | 
|---|
 | 115 | // Terminate Throw New Exception:
 | 
|---|
 | 116 | void terminate_swap() {
 | 
|---|
 | 117 |         signal_exit a = {"terminate_swap"};
 | 
|---|
 | 118 |         try {
 | 
|---|
| [e9145a3] | 119 |                 yin x;
 | 
|---|
 | 120 |                 terminate(&x);
 | 
|---|
 | 121 |         } catch (yin * error) {
 | 
|---|
 | 122 |                 yang y;
 | 
|---|
 | 123 |                 terminate(&y);
 | 
|---|
| [307a732] | 124 |         }
 | 
|---|
 | 125 | }
 | 
|---|
 | 126 | 
 | 
|---|
 | 127 | void terminate_swapped() {
 | 
|---|
 | 128 |         signal_exit a = {"terminate_swapped"};
 | 
|---|
 | 129 |         try {
 | 
|---|
 | 130 |                 terminate_swap();
 | 
|---|
| [e9145a3] | 131 |         } catch (yang * error) {
 | 
|---|
 | 132 |                 printf("terminate_swapped caught exception yang\n");
 | 
|---|
| [307a732] | 133 |         }
 | 
|---|
 | 134 | }
 | 
|---|
 | 135 | 
 | 
|---|
 | 136 | // Resume Throw New Exception:
 | 
|---|
 | 137 | void resume_swap() {
 | 
|---|
| [ad0be81] | 138 |         signal_exit a = {"resume_swap"};
 | 
|---|
| [307a732] | 139 |         try {
 | 
|---|
| [e9145a3] | 140 |                 yin x;
 | 
|---|
 | 141 |                 resume(&x);
 | 
|---|
 | 142 |         } catchResume (yin * error) {
 | 
|---|
 | 143 |                 yang y;
 | 
|---|
 | 144 |                 resume(&y);
 | 
|---|
| [307a732] | 145 |         }
 | 
|---|
 | 146 | }
 | 
|---|
 | 147 | 
 | 
|---|
 | 148 | void resume_swapped() {
 | 
|---|
 | 149 |         try {
 | 
|---|
 | 150 |                 resume_swap();
 | 
|---|
| [e9145a3] | 151 |         } catchResume (yang * error) {
 | 
|---|
 | 152 |                 printf("resume_swapped caught exception yang\n");
 | 
|---|
| [307a732] | 153 |         }
 | 
|---|
 | 154 | }
 | 
|---|
 | 155 | 
 | 
|---|
 | 156 | // Terminate Rethrow:
 | 
|---|
 | 157 | void reterminate() {
 | 
|---|
 | 158 |         try {
 | 
|---|
 | 159 |                 try {
 | 
|---|
| [e9145a3] | 160 |                         zen x;
 | 
|---|
 | 161 |                         terminate(&x);
 | 
|---|
 | 162 |                 } catch (zen * error) {
 | 
|---|
 | 163 |                         printf("reterminate zen caught and "
 | 
|---|
 | 164 |                                "will rethrow exception zen\n");
 | 
|---|
| [307a732] | 165 |                         throw;
 | 
|---|
 | 166 |                 }
 | 
|---|
| [e9145a3] | 167 |         } catch (zen * error) {
 | 
|---|
 | 168 |                 printf("reterminate 1 caught exception zen\n");
 | 
|---|
| [307a732] | 169 |         }
 | 
|---|
 | 170 | }
 | 
|---|
 | 171 | 
 | 
|---|
 | 172 | // Resume Rethrow:
 | 
|---|
 | 173 | void reresume() {
 | 
|---|
 | 174 |         try {
 | 
|---|
 | 175 |                 try {
 | 
|---|
| [e9145a3] | 176 |                         zen x;
 | 
|---|
 | 177 |                         resume(&x);
 | 
|---|
 | 178 |                 } catchResume (zen * error) {
 | 
|---|
 | 179 |                         printf("reresume zen caught and rethrows exception zen\n");
 | 
|---|
| [307a732] | 180 |                         throwResume;
 | 
|---|
 | 181 |                 }
 | 
|---|
| [e9145a3] | 182 |         } catchResume (zen * error) {
 | 
|---|
 | 183 |                 printf("reresume 1 caught exception zen\n");
 | 
|---|
| [307a732] | 184 |         }
 | 
|---|
 | 185 | }
 | 
|---|
 | 186 | 
 | 
|---|
 | 187 | // Terminate-Resume interaction:
 | 
|---|
 | 188 | void fum() {
 | 
|---|
 | 189 |         // terminate block, call resume
 | 
|---|
 | 190 |         try {
 | 
|---|
| [e9145a3] | 191 |                 zen x;
 | 
|---|
 | 192 |                 resume(&x);
 | 
|---|
 | 193 |         } catch (zen * error) {
 | 
|---|
 | 194 |                 printf("fum caught exception zen\n");
 | 
|---|
| [307a732] | 195 |         }
 | 
|---|
 | 196 | }
 | 
|---|
 | 197 | 
 | 
|---|
 | 198 | void foe() {
 | 
|---|
 | 199 |         // resume block, call terminate
 | 
|---|
 | 200 |         try {
 | 
|---|
| [e9145a3] | 201 |                 zen y;
 | 
|---|
 | 202 |                 terminate(&y);
 | 
|---|
 | 203 |         } catchResume (zen * error) {
 | 
|---|
 | 204 |                 printf("foe caught exception zen\n");
 | 
|---|
| [307a732] | 205 |         }
 | 
|---|
 | 206 | }
 | 
|---|
 | 207 | 
 | 
|---|
 | 208 | void fy() {
 | 
|---|
 | 209 |         // terminate block calls fum, call foe
 | 
|---|
 | 210 |         try {
 | 
|---|
 | 211 |                 foe();
 | 
|---|
| [e9145a3] | 212 |         } catch (zen * error) {
 | 
|---|
 | 213 |                 printf("fy caught exception zen\n");
 | 
|---|
| [307a732] | 214 |                 fum();
 | 
|---|
 | 215 |         }
 | 
|---|
 | 216 | }
 | 
|---|
 | 217 | 
 | 
|---|
 | 218 | void fee() {
 | 
|---|
 | 219 |         // resume block, call fy
 | 
|---|
 | 220 |         try {
 | 
|---|
 | 221 |                 fy();
 | 
|---|
| [e9145a3] | 222 |         } catchResume (zen * error) {
 | 
|---|
 | 223 |                 printf("fee caught exception zen\n");
 | 
|---|
| [307a732] | 224 |         }
 | 
|---|
 | 225 | }
 | 
|---|
 | 226 | 
 | 
|---|
 | 227 | 
 | 
|---|
 | 228 | // main: choose which tests to run
 | 
|---|
 | 229 | int main(int argc, char * argv[]) {
 | 
|---|
 | 230 |         signal_exit a = {"main function"};
 | 
|---|
 | 231 | 
 | 
|---|
 | 232 |         foo(); printf("\n");
 | 
|---|
 | 233 |         alpha(); printf("\n");
 | 
|---|
 | 234 |         farewell(false); printf("\n");
 | 
|---|
 | 235 |         farewell(true); printf("\n");
 | 
|---|
 | 236 |         fallback(); printf("\n");
 | 
|---|
 | 237 |         terminate_swapped(); printf("\n");
 | 
|---|
 | 238 |         resume_swapped(); printf("\n");
 | 
|---|
 | 239 |         reterminate(); printf("\n");
 | 
|---|
 | 240 |         reresume(); printf("\n");
 | 
|---|
 | 241 |         fee(); printf("\n");
 | 
|---|
| [e9145a3] | 242 | 
 | 
|---|
| [307a732] | 243 |         // Uncaught termination test.
 | 
|---|
| [e9145a3] | 244 |         printf("Throw uncaught.\n");
 | 
|---|
 | 245 |         yang z;
 | 
|---|
 | 246 |         terminate(&z);
 | 
|---|
| [307a732] | 247 | }
 | 
|---|