Skip to content

Commit

Permalink
Add spec for heap specifier
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer committed Jun 18, 2024
1 parent f75cf88 commit f40e5e4
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions media/specs/heap-specifier.md
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.

0 comments on commit f40e5e4

Please sign in to comment.