source: libcfa/src/exception.hfa@ 40c81e5

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 40c81e5 was 1c01c58, checked in by Andrew Beach <ajbeach@…>, 5 years ago

Rather large commit to get coroutine cancellation working.

This includes what you would expect, like new code in exceptions and a new
test, but it also includes a bunch of other things.

New coroutine state, currently just marks that the stack was cancelled. New
helpers for checking code structure and generating vtables. Changes to the
coroutine interface so resume may throw exceptions on cancellation, plus the
exception type that is thrown. Changes to the coroutine keyword generation to
generate exception code for each type of coroutine.

  • Property mode set to 100644
File size: 11.4 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// exception.hfa -- User facing tools for working with exceptions.
8//
9// Author : Andrew Beach
10// Created On : Thu Apr 7 10:25:00 2020
11// Last Modified By : Andrew Beach
12// Last Modified On : Tue Aug 4 16:22:00 2020
13// Update Count : 3
14//
15
16// Everything below this line should be considered a patch while the exception
17// objects themselves are designed and created and should be removed in time.
18// -----------------------------------------------------------------------------------------------
19
20// TRIVIAL_EXCEPTION_DECLARATION(exception_name);
21// Declare a trivial exception, one that adds no fields or features.
22// This will make the exception visible and may go in a .hfa or .cfa file.
23#define TRIVIAL_EXCEPTION_DECLARATION(...) \
24 _EXC_DISPATCH(_TRIVIAL_EXCEPTION_DECLARATION, __VA_ARGS__)
25
26// TRIVIAL_EXCEPTION_INSTANCE(exception_name);
27// Create the trival exception. This must be used exactly once and should be used in a .cfa file,
28// as it creates the unique instance of the virtual table.
29#define TRIVIAL_EXCEPTION_INSTANCE(...) _EXC_DISPATCH(_TRIVIAL_EXCEPTION_INSTANCE, __VA_ARGS__)
30
31// TRIVIAL_EXCEPTION(exception_name[, parent_name]);
32// Does both of the above, a short hand if the exception is only used in one .cfa file.
33// For legacy reasons this is the only one that official supports having a parent other than the
34// base exception. This feature may be removed or changed.
35#define TRIVIAL_EXCEPTION(...) \
36 _EXC_DISPATCH(_TRIVIAL_EXCEPTION_DECLARATION, __VA_ARGS__); \
37 _EXC_DISPATCH(_TRIVIAL_EXCEPTION_INSTANCE, __VA_ARGS__)
38
39// FORALL_TRIVIAL_EXCEPTION(exception_name, (assertions...), (parameters...));
40// Forward declare a polymorphic but otherwise trivial exception type. You must provide the entire
41// assertion list (exactly what would go in the forall clause) and parameters list (only the
42// parameter names from the assertion list, same order and comma seperated). This should be
43// visible where ever use the exception. This just generates the polymorphic framework, see
44// POLY_VTABLE_DECLARATION to allow instantiations.
45#define FORALL_TRIVIAL_EXCEPTION(exception_name, assertions, parameters) \
46 _FORALL_TRIVIAL_EXCEPTION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
47
48// FORALL_TRIVIAL_INSTANCE(exception_name, (assertions...), (parameters...))
49// Create the forall trivial exception. The assertion list and parameters must match.
50// There must be exactly one use of this in a program for each exception type. This just
51// generates the polymorphic framework, see POLY_VTABLE_INSTANCE to allow instantiations.
52#define FORALL_TRIVIAL_INSTANCE(exception_name, assertions, parameters) \
53 _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters)
54
55// DATA_EXCEPTION(exception_name)(fields...);
56// Forward declare an exception that adds fields but no features. The added fields go in the
57// second argument list. The virtual table instance must be provided later (see VTABLE_INSTANCE).
58#define DATA_EXCEPTION(...) _EXC_DISPATCH(_DATA_EXCEPTION, __VA_ARGS__)
59
60// FORALL_DATA_EXCEPTION(exception_name, (assertions...), (parameters...))(fields...);
61// Define a polymorphic exception that adds fields but no additional features. The assertion list
62// and matching parameters must match. Then you can give the list of fields. This should be
63// visible where ever you use the exception. This just generates the polymorphic framework, see
64// POLY_VTABLE_DECLARATION to allow instantiations.
65#define FORALL_DATA_EXCEPTION(exception_name, assertions, parameters) \
66 _FORALL_DATA_EXCEPTION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
67
68// FORALL_DATA_INSTANCE(exception_name, (assertions...), (parameters...))
69// Create a polymorphic data exception. The assertion list and parameters must match. This should
70// appear once in each program. This just generates the polymorphic framework, see
71// POLY_VTABLE_INSTANCE to allow instantiations.
72#define FORALL_DATA_INSTANCE(exception_name, assertions, parameters) \
73 _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters)
74
75// VTABLE_DECLARATION(exception_name)([new_features...]);
76// Declare a virtual table type for an exception with exception_name. You may also add features
77// (fields on the virtual table) by including them in the second list.
78#define VTABLE_DECLARATION(...) _EXC_DISPATCH(_VTABLE_DECLARATION, __VA_ARGS__)
79
80// VTABLE_INSTANCE(exception_name)(msg [, others...]);
81// Create the instance of the virtual table. There must be exactly one instance of a virtual table
82// for each exception type. This fills in most of the fields of the virtual table (uses ?=? and
83// ^?{}) but you must provide the message function and any other fields added in the declaration.
84#define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__)
85
86// FORALL_VTABLE_DECLARATION(exception_name, (assertions...), (parameters...))([new_features...]);
87// Declare a polymorphic virtual table type for an exception with exception_name, the given
88// assertions and parameters. You may also add features (fields on the virtual table). This just
89// generates the polymorphic framework, see POLY_VTABLE_DECLARATION to allow instantiations.
90#define FORALL_VTABLE_DECLARATION(exception_name, assertions, parameters) \
91 _FORALL_VTABLE_DECLARATION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
92
93// POLY_VTABLE_DECLARATION(exception_name, types...);
94// Declares that an instantiation for this exception exists for the given types. This should be
95// visible anywhere you use the instantiation of the exception is used.
96#define POLY_VTABLE_DECLARATION(exception_name, ...) \
97 void mark_exception(exception_name(__VA_ARGS__) *); \
98 extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name)
99
100// POLY_VTABLE_INSTANCE(exception_name, types...)(msg [, others...]);
101// Creates an instantiation for the given exception for the given types. This should occur only
102// once in the entire program. You must fill in all features, message and any others given in the
103// initial declaration.
104#define POLY_VTABLE_INSTANCE(exception_name, ...) \
105 _POLY_VTABLE_INSTANCE(exception_name, __cfaehm_base_exception_t, __VA_ARGS__)
106
107// VTABLE_TYPE(exception_name) | VTABLE_NAME(exception_name)
108// Get the name of the vtable type or the name of the vtable instance for an exception type.
109#define VTABLE_TYPE(exception_name) struct _GLUE2(exception_name,_vtable)
110#define VTABLE_NAME(exception_name) _GLUE3(_,exception_name,_vtable_instance)
111
112// VTABLE_FIELD(exception_name);
113// FORALL_VTABLE_FIELD(exception_name, (parameters-or-types));
114// The declaration of the virtual table field. Should be the first declaration in a virtual type.
115#define VTABLE_FIELD(exception_name) VTABLE_TYPE(exception_name) const * virtual_table
116#define FORALL_VTABLE_FIELD(exception_name, parameters) \
117 VTABLE_TYPE(exception_name) parameters const * virtual_table
118
119// VTABLE_INIT(object_reference, exception_name);
120// Sets a virtual table field on an object to the virtual table instance for the type.
121#define VTABLE_INIT(this, exception_name) (this).virtual_table = &VTABLE_NAME(exception_name)
122
123// VTABLE_ASSERTION(exception_name, (parameters...))
124// The assertion that there is an instantiation of the vtable for the exception and types.
125#define VTABLE_ASSERTION(exception_name, parameters) \
126 { VTABLE_TYPE(exception_name) parameters VTABLE_NAME(exception_name); }
127
128// All internal helper macros begin with an underscore.
129#define _CLOSE(...) __VA_ARGS__ }
130#define _GLUE2(left, right) left##right
131#define _GLUE3(left, middle, right) left##middle##right
132#define _EXC_DISPATCH(to, ...) to(__VA_ARGS__,__cfaehm_base_exception_t,)
133#define _UNPACK(...) __VA_ARGS__
134
135#define _TRIVIAL_EXCEPTION_DECLARATION(exception_name, parent_name, ...) \
136 _VTABLE_DECLARATION(exception_name, parent_name)(); \
137 struct exception_name { \
138 VTABLE_FIELD(exception_name); \
139 }; \
140 void ?{}(exception_name & this); \
141 const char * _GLUE2(exception_name,_msg)(exception_name * this)
142
143#define _TRIVIAL_EXCEPTION_INSTANCE(exception_name, parent_name, ...) \
144 void ?{}(exception_name & this) { \
145 VTABLE_INIT(this, exception_name); \
146 } \
147 const char * _GLUE2(exception_name,_msg)(exception_name * this) { \
148 return #exception_name; \
149 } \
150 _VTABLE_INSTANCE(exception_name, parent_name,)(_GLUE2(exception_name,_msg))
151
152#define _FORALL_TRIVIAL_EXCEPTION(exception_name, parent_name, assertions, \
153 parameters, parent_parameters) \
154 _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \
155 parameters, parent_parameters)(); \
156 forall assertions struct exception_name { \
157 FORALL_VTABLE_FIELD(exception_name, parameters); \
158 }; \
159 _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters)
160
161#define _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) \
162 forall(_UNPACK assertions | VTABLE_ASSERTION(exception_name, parameters) ) \
163 void ?{}(exception_name parameters & this)
164
165#define _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) \
166 _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) { \
167 VTABLE_INIT(this, exception_name); \
168 }
169
170#define _DATA_EXCEPTION(exception_name, parent_name, ...) \
171 _VTABLE_DECLARATION(exception_name, parent_name)(); \
172 struct exception_name { \
173 VTABLE_FIELD(exception_name); \
174 _CLOSE
175
176#define _FORALL_DATA_EXCEPTION(exception_name, parent_name, \
177 assertions, parameters, parent_parameters) \
178 _FORALL_VTABLE_DECLARATION(exception_name, parent_name, \
179 assertions, parameters, parent_parameters)(); \
180 _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters); \
181 forall assertions struct exception_name { \
182 FORALL_VTABLE_FIELD(exception_name, parameters); \
183 _CLOSE
184
185#define _VTABLE_DECLARATION(exception_name, parent_name, ...) \
186 struct exception_name; \
187 void mark_exception(exception_name *); \
188 VTABLE_TYPE(exception_name); \
189 extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \
190 VTABLE_TYPE(exception_name) { \
191 VTABLE_TYPE(parent_name) const * parent; \
192 size_t size; \
193 void (*copy)(exception_name * this, exception_name * other); \
194 void (*^?{})(exception_name & this); \
195 const char * (*msg)(exception_name * this); \
196 _CLOSE
197
198#define _VTABLE_INSTANCE(exception_name, parent_name, ...) \
199 void mark_exception(exception_name *) {} \
200 void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \
201 *this = *other; \
202 } \
203 VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name) @= { \
204 &VTABLE_NAME(parent_name), sizeof(exception_name), \
205 _GLUE2(exception_name,_copy), ^?{}, \
206 _CLOSE
207
208#define _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \
209 parameters, parent_parameters) \
210 forall assertions struct exception_name; \
211 forall assertions VTABLE_TYPE(exception_name) { \
212 VTABLE_TYPE(parent_name) parent_parameters const * parent; \
213 size_t size; \
214 void (*copy)(exception_name parameters * this, exception_name parameters * other); \
215 void (*^?{})(exception_name parameters & this); \
216 const char * (*msg)(exception_name parameters * this); \
217 _CLOSE
218
219#define _POLY_VTABLE_INSTANCE(exception_name, parent_name, ...) \
220 void mark_exception(exception_name(__VA_ARGS__) *) {} \
221 void _GLUE2(exception_name,_copy)( \
222 exception_name(__VA_ARGS__) * this, exception_name(__VA_ARGS__) * other) { \
223 *this = *other; \
224 } \
225 VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name) @= { \
226 &VTABLE_NAME(parent_name), sizeof(exception_name(__VA_ARGS__)), \
227 _GLUE2(exception_name,_copy), ^?{}, \
228 _CLOSE
Note: See TracBrowser for help on using the repository browser.