3 /* Copyright (c) 2006 Eli Gottlieb.
4 * Permission is granted to copy, distribute and/or modify this document
5 * under the terms of the GNU Free Documentation License, Version 1.2
6 * or any later version published by the Free Software Foundation;
7 * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
8 * Texts. A copy of the license is included in the file entitled "COPYING". */
12 /*! \file edi_objects.h
13 * \brief The header file for basic EDI types and the object system.
15 * This file contains declarations of EDI's primitive data types, as well as structures and functions for with the object system.
16 * It represents these data structures and algorithms:
18 * DATA STRUCTURE: THE CLASS LIST - EDI implementing runtime's must keep an internal list of classes implemented by the runtime
19 * and separate lists of classes implemented by each driver. Whoever implements a class is said to "own" that class. The
20 * internal format of this list is up to the runtime coders, but it must be possible to recreate the original list of
21 * edi_class_declaration structures the driver declared to the runtime from it. This list is declared to the runtime in an
22 * initialization function in the header edi.h. The object_class member of an edi_object_metadata structure must point to that
23 * object's class's entry in this list.
25 * ALGORITHM AND DATA STRUCTURE: CLASSES AND INHERITANCE - Classes are described using edi_class_declaration_t structures and
26 * follow very simple rules. All data is private and EDI provides no way to access instance data, so there are no member
27 * variable declarations. However, if the data isn't memory-protected (for example, driver data on the driver heap) EDI allows
28 * the possibility of pointer access to data, since runtime and driver coders could make use of that behavior. Classes may have
29 * one ancestor by declaring so in their class declaration structure, and if child methods are different then parent methods
30 * the children always override their parents. An EDI runtime must also be able to check the existence and ownership of a given
31 * class given its name in an edi_string_t.
33 * ALGORITHM: OBJECT CREATION AND DESTRUCTION - An EDI runtime should be able to call the constructor of a named class, put the
34 * resulting object_pointer into an edi_object_metadata_t and return that structure. The runtime should also be able to call an
35 * object's class's destructor when given a pointer to a valid edi_metadata_t for an already-existing object. Data equivalent
36 * to an edi_object_metadata_t should also be tracked by the runtime for every object in existence in case of sudden EDI shutdown
39 * ALGORITHM: RUNTIME TYPE INFORMATION - When passed the data_pointer member of an edi_object_metadata_t to a valid object, an
40 * EDI runtime must be able to return an edi_string_t containing the name of that object's class and to return function_pointers
41 * to methods when the required information to find the correct method is given by calling a class's method getting function.*/
43 /* If the EDI headers are linked with the standard C library, they use its type definitions. Otherwise, equivalent definitions are
45 #if __STDC_VERSION__ == 199901L
50 # define NULL ((void*)0)
52 typedef unsigned char bool;
56 typedef short int16_t;
58 typedef long long int64_t;
59 typedef unsigned char uint8_t;
60 typedef unsigned short uint16_t;
61 typedef unsigned long uint32_t;
62 typedef unsigned long long uint64_t;
65 /*! \brief Define a variable in the header
70 # define EDI_DEFVAR extern
73 /*! \brief A pointer to the in-memory instance of an object.
75 * This type is sized just like a general C pointer type (whatever*) for the target architecture. It's passed as a first parameter
76 * to all methods, thus allowing EDI classes to be implemented as C++ classes and providing some protection from confusing objects
77 * with normal pointers. Equivalent to a C++ this pointer or an Object Pascal Self argument. */
78 typedef void *object_pointer;
79 /*! \brief A basic pointer type pointing to arbitrary data in an arbitrary location. */
80 typedef void *data_pointer;
81 /*! \brief A basic function pointer type.
83 * A pointer to a piece of code which can be called and return to its caller, used to distinguish between pointers to code and
84 * pointers to data. Its size is hardware-dependent. */
85 typedef void (*function_pointer)(void);
86 /*! \brief The length of an EDI string without its null character. */
87 #define EDI_STRING_LENGTH 31
88 /*! \brief A type representing a 31-character long string with a terminating NULL character at the end. All of EDI uses this type
91 * A null-terminated string type which stores characters in int8s. It allows for 31 characters in each string, with the final
92 * character being the NULL terminator. Functions which use this type must check that its final character is NULL, a string which
93 * doesn't not have this property is invalid and insecure. I (the author of EDI) know and understand that this form of a string
94 * suffers from C programmer's disease, but I can't use anything else without either making string use far buggier or dragging
95 * everyone onto a better language than C. */
96 typedef int8_t edi_string_t[0x20];
97 /*! \brief A type representing a pointer form of #edi_string_t suitable for function returns
99 typedef int8_t *edi_string_ptr_t;
101 /*! \var EDI_BASE_TYPES
102 * \brief A constant array of edi_string_t's holding every available EDI primitive type. */
103 /*! \var EDI_TYPE_MODIFIERS
104 * \brief A constant array of edi_string_t's holding available modifiers for EDI primitive types. */
105 #ifdef IMPLEMENTING_EDI
106 const edi_string_t EDI_BASE_TYPES[9] = {"void","bool","int8_t","int16_t","int32_t","int64_t","function_pointer","intreg","edi_string_t"};
107 const edi_string_t EDI_TYPE_MODIFIERS[2] = {"pointer","unsigned"};
109 //extern const edi_string_t EDI_BASE_TYPES[9] = {"void","bool","int8_t","int16_t","int32_t","int64_t","function_pointer","intreg", "edi_string_t"};
110 //extern const edi_string_t EDI_TYPE_MODIFIERS[2] = {"pointer","unsigned"};
111 extern const edi_string_t EDI_BASE_TYPES[9];
112 extern const edi_string_t EDI_TYPE_MODIFIERS[2];
115 /*! \struct edi_object_metadata_t
116 * \brief A packed structure holding all data to identify an object to the EDI object system. */
118 /*! \brief Points to the instance data of the object represented by this structure.
120 * An object_pointer to the object this structure refers to. The this pointer, so to speak. */
121 object_pointer object;
122 /*! \brief Points the internal record kept by the runtime describing the object's class.
124 * Points to wherever the runtime has stored the class data this object was built from. The class data doesn't need to be
125 * readable to the driver, and so this pointer can point to an arbitrary runtime-reachable location. */
126 data_pointer object_class;
127 } edi_object_metadata_t;
129 /*! \struct edi_variable_declaration_t
130 * \brief The data structure used to describe a variable declaration to the EDI object system.
132 * The data structure used to describe a variable declaration to the EDI object system. The context of the declaration depends on
133 * where the data structure appears, ie: alone, in a class declaration, in a parameter list, etc. */
135 /*! \brief The type of the declared variable.
137 * The type of the variable, which must be a valid EDI primitive type as specified in the constant EDI_BASE_TYPES and
138 * possibly modified by a modifier specified in the constant EDI_TYPE_MODIFIERS. */
140 /*! \brief The name of the declared variable. */
142 /*! \brief Number of array entries if this variable is an array declaration.
144 * An int32_t specifying the number of variables of 'type' in the array 'name'. For a single variable this value should
145 * simply be set to 1, for values greater than 1 a packed array of contiguous variables is being declared, and a value of 0
147 int32_t array_length;
148 } edi_variable_declaration_t;
150 /*! \struct edi_function_declaration_t
151 * \brief The data structure used to declare a function to the EDI object system. */
153 /*! \brief The return type of the function. The same type rules which govern variable definitions apply here. */
154 edi_string_t return_type;
155 /*! \brief The name of the declared function. */
157 /*! \brief The version number of the function, used to tell different implementations of the same function apart. */
159 /*! \brief The number of arguments passed to the function.
161 * The number of entries in the member arguments that the object system should care about. Caring about less misses
162 * parameters to functions, caring about more results in buffer overflows. */
163 uint32_t num_arguments;
164 /*! \brief An array of the declared function's arguments.
166 * A pointer to an array num_arguments long containing edi_variable_declaration_t's for each argument to the declared
168 edi_variable_declaration_t *arguments;
169 /*!\brief A pointer to the declared function's code in memory. */
170 function_pointer code;
171 } edi_function_declaration_t;
173 /*! \brief A pointer to a function for constructing instances of a class.
175 * A pointer to a function which takes no parameters and returns an object_pointer pointing to the newly made instance of a class.
176 * It is the constructor's responsibility to allocate memory for the new object. Each EDI class needs one of these. */
177 typedef object_pointer (*edi_constructor_t)(void);
178 /*! \brief A pointer to a function for destroying instances of a class.
180 * A pointer to a function which takes an object_pointer as a parameter and returns void. This is the destructor counterpart to a
181 * class's edi_constructor_t, it destroys the object pointed to by its parameter and frees the object's memory. Every class must
183 typedef void (*edi_destructor_t)(object_pointer);
185 /*! \brief Information the driver must give the runtime about its classes so EDI can construct them and call their methods.
187 * A structure used to declare a class to an EDI runtime so instances of it can be constructed by the EDI object system. */
189 /*! \brief The name of the class declared by the structure. */
191 /*! \brief The version of the class. This number is used to tell identically named but differently
192 * implemented classes apart.*/
194 /*! \brief The number of methods in the 'methods' function declaration array. */
195 uint32_t num_methods;
196 /*! \brief An array of edi_function_declaration_t declaring the methods of this class. */
197 edi_function_declaration_t *methods;
198 /*! \brief Allocates the memory for a new object of the declared class and constructs the object. Absolutely required.*/
199 edi_constructor_t constructor;
200 /*! \brief Destroys the given object of the declared class and frees its memory. Absolutely required. */
201 edi_destructor_t destructor;
202 /*! \brief A pointer to another EDI class declaration structure specifying the declared class's parent class.
204 * Points to a parent class declared in another class declaration. It can be NULL to mean this class has no parent. */
205 struct edi_class_declaration_t *parent;
206 } edi_class_declaration_t;
208 /*! \brief Checks the existence of the named class.
210 * This checks for the existence on THE CLASS LIST of the class named by its edi_string_t parameter and returns a signed int32_t. If
211 * the class isn't found (ie: it doesn't exist as far as EDI is concerned) -1 is returned, if the class is owned by the driver
212 * (implemented by the driver and declared to the runtime by the driver) 0, and if the class is owned by the runtime (implemented by
214 int32_t check_class_existence(edi_string_t class_name);
215 /*! \brief Constructs an object of the named class and returns its object_pointer and a data_pointer to its class data.
217 * Given a valid class name in an edi_string_t this function constructs the specified class and returns an edi_metadata_t describing
218 * the new object as detailed in OBJECT CREATION AND DESTRUCTION. If the construction fails it returns a structure full of NULL
220 edi_object_metadata_t construct_object(edi_string_t class_name);
221 /*! \brief Destroys the given object using its class data.
223 * As specified in OBJECT CREATION AND DESTRUCTION this function should destroy an object when given its valid edi_metadata_t. The
224 * destruction is accomplished by calling the class's destructor. */
225 void destroy_object(edi_object_metadata_t object);
226 /*! \brief Obtains a function pointer to a named method of a given class.
228 * When given a valid data_pointer object_class from an edi_object_metadata_t and an edi_string_t representing the name of the
229 * desired method retrieves a function_pointer to the method's machine code in memory. If the desired method isn't found, NULL is
231 function_pointer get_method_by_name(data_pointer object_class,edi_string_t method_name);
232 /*! \brief Obtains a function pointer to a method given by a declaration of the given class if the class's method matches the
235 * Works just like get_method_by_name(), but by giving an edi_function_declaration_t for the desired method instead of just its name.
236 * Performs detailed checking against THE CLASS LIST to make sure that the method returned exactly matches the declaration passed
238 function_pointer get_method_by_declaration(data_pointer object_class,edi_function_declaration_t declaration);
240 /* Runtime typing information. */
241 /*! \brief Returns the name of the class specified by a pointer to class data.
243 * Given the data_pointer to an object's class data as stored in an edi_object_metadata_t retrieves the name of the object's class
244 * and returns it in an edi_string_t. */
245 edi_string_ptr_t get_object_class(data_pointer object_class);
246 /*! \brief Returns the name of a class's parent class.
248 * When given an edi_string_t with a class name in it, returns another edi_string_t containing the name of the class's parent, or an
250 edi_string_ptr_t get_class_parent(edi_string_t some_class);
251 /*! \brief Returns the internal class data of a named class (if it exists) or NULL.
253 * When given an edi_string_t with a valid class name in it, returns a pointer to the runtime's internal class data for that class.
254 * Otherwise, it returns NULL. */
255 data_pointer get_internal_class(edi_string_t some_class);