-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f75cf88
commit f40e5e4
Showing
1 changed file
with
67 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Technical Specification for the heap specifier | ||
|
||
## Implementation steps: | ||
|
||
- [x] Add basic support | ||
- [x] Move all std data structures to use the heap specifier | ||
- [x] Add tests for this feature | ||
- [x] Generate default dtor for structs with heap fields where free is called on those fields | ||
- [x] Make copy ctor mandatory for structs with heap fields | ||
- [ ] Allow assignment from heap to non-heap pointers to create non-owning pointers | ||
- [ ] Perform a swap when assigning from heap to heap pointers | ||
|
||
## Syntax | ||
|
||
```spice | ||
// As struct field | ||
type TestStruct struct { | ||
heap int* ptr | ||
} | ||
// As local variable | ||
f<int> foo() { | ||
heap int* ptr = sAlloc(sizeof(type int)); | ||
*ptr = 5; | ||
return ptr; | ||
} | ||
``` | ||
|
||
## Functionality | ||
|
||
### General introduction | ||
|
||
The `heap` specifier can only be applied to pointer variables/fields and is used to indicate that the memory for the | ||
variable/field was or is going to be allocated on the heap. It acts similar to a `unique_ptr` would in C++, but builtin | ||
into the language. | ||
|
||
The heap specifier can be used in the following ways: | ||
|
||
- As a field type specifier in a struct | ||
- As a local variable type specifier | ||
- As a function return type specifier | ||
- As a parameter type specifier | ||
|
||
When the `heap` specifier is used for a struct field, the compiler will automatically generate a destructor for that | ||
struct, that will free the memory allocated for the field. The `heap` specifier can also be used in local variables | ||
and function return types. When a function returns a `heap` pointer, the caller is responsible for freeing the memory | ||
allocated for the pointer. The `heap` specifier can also be used in function parameters. When a function parameter is | ||
declared as `heap`, the callee is responsible for freeing the memory allocated for the parameter. | ||
|
||
### Assignment semantics | ||
|
||
When assigning a `heap` pointer to a non-heap pointer, the non-heap pointer becomes a non-owning pointer. This means | ||
that the non-heap pointer does not have to free its memory, as it does not own it. The memory is still owned by the | ||
`heap` pointer, and the memory will be freed when the `heap` pointer goes out of scope. | ||
|
||
When assigning a `heap` pointer to another `heap` pointer, the memory is not copied, but the ownership gets | ||
transferred to the left hand side variable. This means that the original `heap` pointer will get the value `nil` and is | ||
no longer responsible for freeing the memory. This is done to prevent double freeing of the memory. | ||
|
||
Assigning a non-heap pointer to a `heap` pointer is not allowed, as the non-heap pointer does not own the memory which | ||
it points to. | ||
|
||
### Struct implications | ||
|
||
When a struct has a field with the `heap` specifier, the compiler will automatically generate a destructor for the | ||
struct. The destructor will free the memory allocated for the `heap` field. The compiler will also make the copy | ||
constructor mandatory for the struct. This is done to prevent double freeing of the memory. |