From f40e5e47e89985599fb17c792eb1ff7a4e347570 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Wed, 19 Jun 2024 00:58:22 +0200 Subject: [PATCH] Add spec for heap specifier --- media/specs/heap-specifier.md | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 media/specs/heap-specifier.md diff --git a/media/specs/heap-specifier.md b/media/specs/heap-specifier.md new file mode 100644 index 000000000..928c6c9f5 --- /dev/null +++ b/media/specs/heap-specifier.md @@ -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 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.