source: libcfa/src/exception.hfa @ 0989e79

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 0989e79 was 8fc9a5f, checked in by Andrew Beach <ajbeach@…>, 4 years ago

Did some work the exception header to better fake associated types.

  • Property mode set to 100644
File size: 12.6 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        VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable(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// IS_EXCEPTION(exception_name [, (...parameters)])
129// IS_RESUMPTION_EXCEPTION(exception_name [, (parameters...)])
130// IS_TERMINATION_EXCEPTION(exception_name [, (parameters...)])
131// Create an assertion that exception_name, possibly with the qualifing parameters, is the given
132// kind of exception with the standard vtable with the same parameters if applicable.
133#define IS_EXCEPTION(...) _IS_EXCEPTION(is_exception, __VA_ARGS__, , ~)
134#define IS_RESUMPTION_EXCEPTION(...) _IS_EXCEPTION(is_resumption_exception, __VA_ARGS__, , ~)
135#define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~)
136
137// All internal helper macros begin with an underscore.
138#define _CLOSE(...) __VA_ARGS__ }
139#define _GLUE2(left, right) left##right
140#define _GLUE3(left, middle, right) left##middle##right
141#define _EXC_DISPATCH(to, ...) to(__VA_ARGS__,__cfaehm_base_exception_t,)
142#define _UNPACK(...) __VA_ARGS__
143
144#define _TRIVIAL_EXCEPTION_DECLARATION(exception_name, parent_name, ...) \
145        _VTABLE_DECLARATION(exception_name, parent_name)(); \
146        struct exception_name { \
147                VTABLE_FIELD(exception_name); \
148        }; \
149        void ?{}(exception_name & this); \
150        const char * _GLUE2(exception_name,_msg)(exception_name * this)
151
152#define _TRIVIAL_EXCEPTION_INSTANCE(exception_name, parent_name, ...) \
153        void ?{}(exception_name & this) { \
154                VTABLE_INIT(this, exception_name); \
155        } \
156        const char * _GLUE2(exception_name,_msg)(exception_name * this) { \
157                return #exception_name; \
158        } \
159        _VTABLE_INSTANCE(exception_name, parent_name,)(_GLUE2(exception_name,_msg))
160
161#define _FORALL_TRIVIAL_EXCEPTION(exception_name, parent_name, assertions, \
162                parameters, parent_parameters) \
163        _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \
164                parameters, parent_parameters)(); \
165        forall assertions struct exception_name { \
166                FORALL_VTABLE_FIELD(exception_name, parameters); \
167        }; \
168        _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters)
169
170#define _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) \
171        forall(_UNPACK assertions | \
172                is_exception(exception_name parameters, VTABLE_TYPE(exception_name) parameters)) \
173        void ?{}(exception_name parameters & this)
174
175#define _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) \
176        _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) { \
177                (this).virtual_table = &get_exception_vtable(&this); \
178        }
179
180#define _DATA_EXCEPTION(exception_name, parent_name, ...) \
181        _VTABLE_DECLARATION(exception_name, parent_name)(); \
182        struct exception_name { \
183                VTABLE_FIELD(exception_name); \
184                _CLOSE
185
186#define _FORALL_DATA_EXCEPTION(exception_name, parent_name, \
187                assertions, parameters, parent_parameters) \
188        _FORALL_VTABLE_DECLARATION(exception_name, parent_name, \
189                assertions, parameters, parent_parameters)(); \
190        _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters); \
191        forall assertions struct exception_name { \
192                FORALL_VTABLE_FIELD(exception_name, parameters); \
193                _CLOSE
194
195#define _VTABLE_DECLARATION(exception_name, parent_name, ...) \
196        struct exception_name; \
197        VTABLE_TYPE(exception_name); \
198        VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *); \
199        extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \
200        VTABLE_TYPE(exception_name) { \
201                VTABLE_TYPE(parent_name) const * parent; \
202                size_t size; \
203                void (*copy)(exception_name * this, exception_name * other); \
204                void (*^?{})(exception_name & this); \
205                const char * (*msg)(exception_name * this); \
206                _CLOSE
207
208#define _VTABLE_INSTANCE(exception_name, parent_name, ...) \
209        VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *) { \
210                return VTABLE_NAME(exception_name); \
211        } \
212        void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \
213                *this = *other; \
214        } \
215        VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name) @= { \
216                &VTABLE_NAME(parent_name), sizeof(exception_name), \
217                _GLUE2(exception_name,_copy), ^?{}, \
218                _CLOSE
219
220#define _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \
221                parameters, parent_parameters) \
222        forall assertions struct exception_name; \
223        forall assertions VTABLE_TYPE(exception_name) { \
224                VTABLE_TYPE(parent_name) parent_parameters const * parent; \
225                size_t size; \
226                void (*copy)(exception_name parameters * this, exception_name parameters * other); \
227                void (*^?{})(exception_name parameters & this); \
228                const char * (*msg)(exception_name parameters * this); \
229                _CLOSE
230
231#define _POLY_VTABLE_INSTANCE(exception_name, parent_name, ...) \
232        extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name); \
233        VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable( \
234                        exception_name(__VA_ARGS__) *) { \
235                return VTABLE_NAME(exception_name); \
236        } \
237        void _GLUE2(exception_name,_copy)( \
238                        exception_name(__VA_ARGS__) * this, exception_name(__VA_ARGS__) * other) { \
239                *this = *other; \
240        } \
241        VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name) @= { \
242                &VTABLE_NAME(parent_name), sizeof(exception_name(__VA_ARGS__)), \
243                _GLUE2(exception_name,_copy), ^?{}, \
244                _CLOSE
245
246#define _IS_EXCEPTION(kind, exception_name, parameters, ...) \
247        kind(exception_name parameters, VTABLE_TYPE(exception_name) parameters)
Note: See TracBrowser for help on using the repository browser.