
2 changed files with 249 additions and 223 deletions
@ -0,0 +1,237 @@ |
|||||
|
# pEpACIDLang - Language Mapping Specification for C99 (LMS-C99) |
||||
|
|
||||
|
<!-- TOC --> |
||||
|
* [pEpACIDLang - Language Mapping Specification for C99 (LMS-C99)](#pepacidlang---language-mapping-specification-for-c99-lms-c99) |
||||
|
* [About This Document](#about-this-document) |
||||
|
* [IDL-Types](#idl-types) |
||||
|
* [Type Classes](#type-classes) |
||||
|
* [IDL-Type Mapping To C](#idl-type-mapping-to-c) |
||||
|
* [Creation and Destruction](#creation-and-destruction) |
||||
|
* [Primitive Types](#primitive-types) |
||||
|
* [Object Types](#object-types) |
||||
|
* [Allocators](#allocators) |
||||
|
* [Destructors](#destructors) |
||||
|
* [Method Parameters](#method-parameters) |
||||
|
* [Rules For Parameter Allocation](#rules-for-parameter-allocation) |
||||
|
* [Parameter Passing Modes](#parameter-passing-modes) |
||||
|
* [Mapping Table for C](#mapping-table-for-c) |
||||
|
* [Rules For Parameters Of Primitive-Type](#rules-for-parameters-of-primitive-type) |
||||
|
* [Update](#update) |
||||
|
* [Rules For Parameters Of Object-Type](#rules-for-parameters-of-object-type) |
||||
|
* [Read](#read) |
||||
|
* [Update](#update-1) |
||||
|
* [Consume](#consume) |
||||
|
* [Produce](#produce) |
||||
|
* [Rules For Multithreading](#rules-for-multithreading) |
||||
|
<!-- TOC --> |
||||
|
|
||||
|
This is the document specifying the pEpACIDLang language mapping for C99. |
||||
|
|
||||
|
C99, because this is the minimum language level for the generated target code. |
||||
|
We will use features of a higher language level once there are good reasons to do that. |
||||
|
|
||||
|
The interface generator implements parts of the language mapping specification. |
||||
|
|
||||
|
|
||||
|
## About This Document |
||||
|
|
||||
|
State: Draft, to be reviewed with fdik and positron. |
||||
|
|
||||
|
**ATTENTION, IMPORTANT** |
||||
|
In this document, all types expressed as T are the IDL-types, not their corresponding c-types. |
||||
|
An example for clarity: |
||||
|
If `T` is the type `string`, the IDL-type `string` is meant, so the c-type of `T*` is `char**`. |
||||
|
|
||||
|
Usually a variable typename is expressed as `T`. But sometimes `T` is being used to refer to an instance of type `T`. |
||||
|
This imprecision is used for brevity, but only where the context does not allow for an ambiguity. |
||||
|
|
||||
|
## IDL-Types |
||||
|
|
||||
|
### Type Classes |
||||
|
|
||||
|
There are only two type-classes. |
||||
|
|
||||
|
* Primitive Types |
||||
|
* Object Types |
||||
|
|
||||
|
### IDL-Type Mapping To C |
||||
|
|
||||
|
| Type-Class | IDL-Type | C-Type | |
||||
|
|------------|-----------|--------------| |
||||
|
| Primitive | int | int | |
||||
|
| Primitive | uint | unsigned int | |
||||
|
| Primitive | size | size_t | |
||||
|
| Primitive | bool | bool | |
||||
|
| Primitive | enum | enum | |
||||
|
| Object | struct | struct* | |
||||
|
| Object | string | char* | |
||||
|
| Object | binary | char* | |
||||
|
| Object | opaque | void* | |
||||
|
| Object | list\<T\> | list_T* | |
||||
|
| Object | pair<F,S> | pair_F_S* | |
||||
|
|
||||
|
### Creation and Destruction |
||||
|
|
||||
|
#### Primitive Types |
||||
|
|
||||
|
* Primitive types are always statically allocated |
||||
|
* Primitive types are trivially constructable and destroyable |
||||
|
* All storage classes (auto/static/extern/register) are allowed |
||||
|
|
||||
|
#### Object Types |
||||
|
|
||||
|
For any object-type `T`, corresponding `new` and `free` methods are being generated. |
||||
|
|
||||
|
To create an object of type `T` correctly, there are two ways: |
||||
|
|
||||
|
1. Using its allocator-method |
||||
|
2. Using any method that has a parameter of type `T` with mode `Produce` |
||||
|
|
||||
|
To destroy an object of type `T` correctly, the only way is to use its destructor-method. |
||||
|
|
||||
|
##### Allocators |
||||
|
|
||||
|
The allocator-method has the signature: |
||||
|
`IDL_STATUS new_T(T*)` |
||||
|
|
||||
|
* The memory for `T` has to be dynamically allocated |
||||
|
* An empty object is being created. Any object-types reachable through `T` are pointing to `NULL`. |
||||
|
|
||||
|
Result: |
||||
|
STATUS_OK - `T*` is pointing to a valid object |
||||
|
STATUS_ERROR - Dereferencing of `T*` is undefined behaviour |
||||
|
|
||||
|
##### Destructors |
||||
|
|
||||
|
The destructor-method has the signature: |
||||
|
`IDL_STATUS free_T(T*)` |
||||
|
|
||||
|
1. For all object-type members of `T` itself, their respective destructor-methods are being called |
||||
|
2. The memory for `T` is freed compatibly to how it was allocated using its allocator-method |
||||
|
3. `T*` is set to `NULL` |
||||
|
|
||||
|
Result: |
||||
|
STATUS_OK - All memory reachable through `T*` is freed and `T*` is NULL |
||||
|
STATUS_ERROR - FATAL (most implementations of `free()` can guarantee this will never happen) |
||||
|
|
||||
|
## Method Parameters |
||||
|
|
||||
|
The main concerns when sharing memory (e.g. in form of parameters) are: |
||||
|
|
||||
|
* Ownership: defined as who is allowed and responsible to destroy an object. |
||||
|
* Mutability: Who is allowed to change the contents of the memory location that is known to several parties. |
||||
|
|
||||
|
In environments where memory management is explicit, the lifecycle of data in memory is: |
||||
|
|
||||
|
1. Memory being allocated |
||||
|
2. Memory being shared with producers/consumers (e.g. as a parameter Read/Update/Consume) |
||||
|
3. Read/write operations by multiple parties (needs synchronization if multithreaded environment) |
||||
|
3. Make sure this memory will never be accessed again by nobody |
||||
|
4. Memory has to be freed exactly once and compatibly to how it was allocated |
||||
|
|
||||
|
Every such lifecycle must be completed. |
||||
|
All of this must be guaranteed. |
||||
|
|
||||
|
### Rules For Parameter Allocation |
||||
|
|
||||
|
Parameters have to be allocated as follows: |
||||
|
|
||||
|
* Primitive-types: The general rules outlined under [Creation and Destruction](#creation-and-destruction) apply |
||||
|
* Object-types: Using the allocator- and destructor-methods outlined under [Creation and Destruction](#creation-and-destruction) |
||||
|
|
||||
|
These rules apply regardless of the parameter passing mode. |
||||
|
|
||||
|
### Parameter Passing Modes |
||||
|
|
||||
|
The modes are named by describing what the callee does, from the perspective of the callee, using one verb. |
||||
|
|
||||
|
* `Read` - Immutable, ownership remains with caller |
||||
|
* `Update` - Mutable, ownership remains with caller |
||||
|
* `Consume` - Mutable, ownership goes to callee |
||||
|
* `Produce` - Immutable, ownership goes to caller |
||||
|
|
||||
|
#### Mapping Table for C |
||||
|
|
||||
|
Type of `T` as a function of type-class and mode. |
||||
|
Where `T` any of the respective IDL-Types (not their respective c-type, as mentioned in [About This Document](#about-this-document)). |
||||
|
|
||||
|
| Mode/Type-Class | READ | UPDATE | CONSUME | PRODUCE | |
||||
|
|------------------|------|--------|---------|---------| |
||||
|
| Primitive | T | T* | - (1) | - (1) | |
||||
|
| Object | T | T* | T | T* | |
||||
|
|
||||
|
#### Rules For Parameters Of Primitive-Type |
||||
|
|
||||
|
(1) A primitive-type cannot be consumed or produced because it's always statically allocated. |
||||
|
|
||||
|
### Update |
||||
|
|
||||
|
The caller has to allocate memory for `T*`. |
||||
|
The callee is allowed to mutate the memory pointed to by `T*`. |
||||
|
The caller is responsible to free the memory pointed to by `T*`. |
||||
|
|
||||
|
#### Rules For Parameters Of Object-Type |
||||
|
|
||||
|
##### Read |
||||
|
|
||||
|
The caller has to guarantee that either-or: |
||||
|
|
||||
|
* `T` is `NULL` |
||||
|
* `T` is pointing to a valid object of type `*T` (allocated as defined under 'Rules For Parameter Allocation') |
||||
|
This guarantee applies transitively for all object-type members of `*T`. |
||||
|
|
||||
|
The callee is not allowed to mutate or free any memory that can be reached through `T`. |
||||
|
The caller is responsible to free all the memory that can be reached through `T`. |
||||
|
|
||||
|
##### Update |
||||
|
|
||||
|
The caller has to guarantee that: |
||||
|
|
||||
|
* All object-types reachable through `T*` are either `NULL` or pointing to a valid object |
||||
|
(allocated as defined under [Rules For Parameter Allocation](#rules-for-parameter-allocation)) |
||||
|
|
||||
|
The callee is allowed to mutate the object in two ways: |
||||
|
|
||||
|
1. Mutate any primitive-types reachable through `T*` |
||||
|
2. Free or replace any object-types reachable trough `T*` |
||||
|
|
||||
|
The callee has to guarantee, that upon return of the method: |
||||
|
|
||||
|
* `T*` is pointing to a valid `*T` (allocated as defined under [Rules For Parameter Allocation](#rules-for-parameter-allocation)) |
||||
|
* All object-type members reachable through `T*` are either `NULL` or pointing to a valid object of type `*T` (allocated as |
||||
|
defined under [Rules For Parameter Allocation](#rules-for-parameter-allocation)) |
||||
|
|
||||
|
Upon success of the method call: |
||||
|
The caller must replace all pointers to `*T` and to any of its transitive members by dereferencing `T*` and its respective |
||||
|
transitive members. |
||||
|
The caller must free `T` and any of its transitive members. |
||||
|
|
||||
|
TODO: Upon any failure of the method call: |
||||
|
|
||||
|
##### Consume |
||||
|
|
||||
|
The same rules for mode `Read` apply, with the exception that the caller has to guarantee to never access `T` again in |
||||
|
any way. |
||||
|
|
||||
|
##### Produce |
||||
|
|
||||
|
The caller is allowed to pass a `T*` with an undefined value. |
||||
|
TODO... |
||||
|
|
||||
|
#### Rules For Multithreading |
||||
|
|
||||
|
These rules apply to all memory that can be accessed through a parameter. |
||||
|
Such memory must be allocated in the calling thread No such memory can be shared with other |
||||
|
TODO.... |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
Loading…
Reference in new issue