source: libcfa/src/exception.hfa @ 341e252

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 341e252 was 1c01c58, checked in by Andrew Beach <ajbeach@…>, 4 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.