Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RAII #659

Closed
wants to merge 89 commits into from
Closed

RAII #659

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
e248051
<ignore> added test artifacts to .ignore
hiemstar May 17, 2024
0e2cdb0
<feature> added __init metamethod to initialize managed types in raii.
hiemstar May 17, 2024
683526d
<feature> added __dtor metamethod to destruct managed variables in raii.
hiemstar May 17, 2024
5ba46c8
<feature> added __copy metamethod which enables specialized copy-assi…
hiemstar May 17, 2024
d867d28
<tests> added simple testing of raii metamethods __init, __dtor, __co…
hiemstar May 17, 2024
52ae95d
<terralib> revert commented out code to make things work on my local …
hiemstar May 17, 2024
31482a8
<bugfix> now calling __dtor before a new copy-assignment
hiemstar May 17, 2024
a685745
<bugfix> fixed dispatch of __copy. calling __copy is limited to rhs b…
hiemstar May 21, 2024
d677352
<refactor> added hasmetamethod(v, method). changed copy assignment be…
hiemstar May 21, 2024
b77f477
forgot to uncomment SDKROOT code on macos
renehiemstra May 22, 2024
8ba635e
<bugfix> fixed small bug in copyconstruction where the type is passed…
hiemstar May 22, 2024
1ff7038
<test> tests/raii-copyctr-cast.t, which combines __cast and __copy me…
hiemstar May 22, 2024
1d03783
Merge branch 'raii' of github.com:renehiemstra/terra into raii
hiemstar May 22, 2024
31a006b
<test> raii-shared_ptr.t which tests some functionality for a shared …
hiemstar May 22, 2024
ac0c68a
<bugfix> enabled copy assignments for rhs 'select' variables and rhs …
hiemstar May 23, 2024
8aee8b1
<test> raii-offset_ptr.t: example with a type that has some sematics …
hiemstar May 23, 2024
94caf67
<feature> added lib/terralibext.t that is being called from terralib …
hiemstar May 26, 2024
8cbc4b0
<refactor> changed __init, __copy, __dtor from metamethods to regular…
hiemstar May 26, 2024
509816d
<refactor> cleaned up terralibext.t
hiemstar May 27, 2024
0090b2e
<refactor> updated tests to incorporate changes in 'terralibext.t'
hiemstar May 27, 2024
9bf3f79
<test> raii-compose.t: testing composable use of managed structs.
hiemstar May 27, 2024
e1d9cf0
<feature> first implementation of raii composable managed datastructures
hiemstar May 27, 2024
49170c6
<refactor> updated tests/raii-shared_ptr.t
hiemstar May 27, 2024
2e3dcf3
<bugfix> fixed assignment__copy assignment. removed __dtor in custom …
hiemstar May 27, 2024
4e6bfc3
<refactor> reorganized raii tests.
hiemstar May 27, 2024
95a7e84
<test> raii-tuple-default-copy.t and fails/raii-tuple-custom-copy.t
hiemstar May 27, 2024
f4caa8b
<bugfix> fixed throwing error in createassignment in case of a tuple …
hiemstar May 27, 2024
25cb501
<bugfix> proper error exception for tuple assignment of managed varia…
hiemstar May 27, 2024
dd7754f
<uncomment> system code macos in terralib.lua
hiemstar May 27, 2024
5415fe2
<docs> lib/raii.md - discussing implementation and use of RAII concepts.
hiemstar May 29, 2024
ced17ed
<ignore> added test artifacts to .ignore
hiemstar May 17, 2024
8877111
<feature> added __init metamethod to initialize managed types in raii.
hiemstar May 17, 2024
b760837
<feature> added __dtor metamethod to destruct managed variables in raii.
hiemstar May 17, 2024
c503201
<feature> added __copy metamethod which enables specialized copy-assi…
hiemstar May 17, 2024
59d0945
<tests> added simple testing of raii metamethods __init, __dtor, __co…
hiemstar May 17, 2024
69b96e0
<terralib> revert commented out code to make things work on my local …
hiemstar May 17, 2024
5510a1d
<bugfix> now calling __dtor before a new copy-assignment
hiemstar May 17, 2024
010da09
<bugfix> fixed dispatch of __copy. calling __copy is limited to rhs b…
hiemstar May 21, 2024
4e363b0
<refactor> added hasmetamethod(v, method). changed copy assignment be…
hiemstar May 21, 2024
3dbede1
<bugfix> fixed small bug in copyconstruction where the type is passed…
hiemstar May 22, 2024
2c83bf9
<test> tests/raii-copyctr-cast.t, which combines __cast and __copy me…
hiemstar May 22, 2024
5e55ed5
forgot to uncomment SDKROOT code on macos
renehiemstra May 22, 2024
2c24f11
<test> raii-shared_ptr.t which tests some functionality for a shared …
hiemstar May 22, 2024
543bac5
<bugfix> enabled copy assignments for rhs 'select' variables and rhs …
hiemstar May 23, 2024
1b56cf1
<test> raii-offset_ptr.t: example with a type that has some sematics …
hiemstar May 23, 2024
9762db8
<feature> added lib/terralibext.t that is being called from terralib …
hiemstar May 26, 2024
44fa7ad
<refactor> changed __init, __copy, __dtor from metamethods to regular…
hiemstar May 26, 2024
a2671e3
<refactor> cleaned up terralibext.t
hiemstar May 27, 2024
0d21b6d
<refactor> updated tests to incorporate changes in 'terralibext.t'
hiemstar May 27, 2024
84dfe04
<test> raii-compose.t: testing composable use of managed structs.
hiemstar May 27, 2024
433c5b7
<feature> first implementation of raii composable managed datastructures
hiemstar May 27, 2024
93114ff
<refactor> updated tests/raii-shared_ptr.t
hiemstar May 27, 2024
880342e
<bugfix> fixed assignment__copy assignment. removed __dtor in custom …
hiemstar May 27, 2024
d2d2ce8
<refactor> reorganized raii tests.
hiemstar May 27, 2024
2c3a4e0
<test> raii-tuple-default-copy.t and fails/raii-tuple-custom-copy.t
hiemstar May 27, 2024
2aeb433
<bugfix> fixed throwing error in createassignment in case of a tuple …
hiemstar May 27, 2024
5fcd780
<bugfix> proper error exception for tuple assignment of managed varia…
hiemstar May 27, 2024
ee3b76d
<uncomment> system code macos in terralib.lua
hiemstar May 27, 2024
dd5efb3
<docs> lib/raii.md - discussing implementation and use of RAII concepts.
hiemstar May 29, 2024
19d2f39
<merge> rebased changes on top of upstream/master
hiemstar May 29, 2024
50abd4a
<refactor> addmissing<dtor,copy,init> generates a missing method only…
hiemstar May 29, 2024
ae58678
<refactor> prohibiting assignments of managed objects consisting of m…
hiemstar May 29, 2024
5c31ea5
<systemcode> forgot to uncomment system code for macos.
hiemstar May 29, 2024
ec311ad
<docs> updated /lib/raii.md
hiemstar May 29, 2024
35040c6
<docs> updated /lib/raii.md
hiemstar May 29, 2024
12f6128
Update terralib.lua
renehiemstra May 31, 2024
296ba5c
<docs> updated /lib/raii.md
hiemstar Jun 5, 2024
e020696
<BUILD> added terralibext.t to list of terra files that are to be ins…
hiemstar Jun 27, 2024
df66d4c
Merge remote-tracking branch 'upstream/master' into raii
hiemstar Jun 27, 2024
84ebde2
Merge branch 'terralang:master' into raii
renehiemstra Aug 13, 2024
eaff090
<bugfix> fixed issue with assignment of managed variables where a tem…
hiemstar Aug 27, 2024
487cf69
<refactor> removed the print statements in terralibext.t in the gener…
hiemstar Aug 27, 2024
8109b94
Merge branch 'raii' of github.com:renehiemstra/terra into raii
hiemstar Aug 27, 2024
477ba23
<bugfix> fixed pasted-copy bug in __addmissingcopy - where hasdtor sh…
hiemstar Sep 7, 2024
86a3873
<feature> added __move, __forward to terralibext.t
hiemstar Sep 30, 2024
829ff63
<bugfix> passing by value in __generate_move in lib/terralibext.t
hiemstar Oct 17, 2024
7e30579
Merge remote-tracking branch 'upstream/master' into raii
hiemstar Oct 17, 2024
099ae98
<bugfix> direct initialization with managed members now works as expe…
hiemstar Nov 22, 2024
bed8cf0
fixed test to conform to added code of previous bugfix. one should be…
hiemstar Nov 22, 2024
2642290
<tests> added raii-copyctr.t that tests direct initialization and cop…
hiemstar Nov 22, 2024
779c01f
<test> added tests for returning managed vars from function
hiemstar Nov 25, 2024
952b904
<test> testing return managed variables from functions.
hiemstar Nov 25, 2024
e75ff3d
<bugfix> structcast now working correctly, also when returning multip…
hiemstar Nov 25, 2024
3f9d92f
forgot to uncomment macos specific code.
hiemstar Nov 25, 2024
b65e647
fixed typo 'environment' in README; added some test arctifacts and .d…
hiemstar Nov 25, 2024
4d4cf13
fixed typo in README
hiemstar Nov 25, 2024
c409fce
Merge branch 'master' into raii
renehiemstra Nov 26, 2024
440965d
<ignore> removed ducplicate 'cmake-build-debug' from .ignore file.
renehiemstra Nov 27, 2024
14234ca
<doc> added raii.md to documentation folder. updated content.
renehiemstra Nov 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
/tests/objc2
/tests/stdio.exe


*.bc
*.ll
*.o
Expand Down
177 changes: 177 additions & 0 deletions docs/raii.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# Deterministic Automated Resource Management

Resource management in programming languages generally falls into one of the following categories:

1. **Manual allocation and deallocation**
2. **Automatic garbage collection**
3. **Automatic scope-bound resource management** (commonly referred to as [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization), or *Resource Acquisition Is Initialization*).

Traditionally, Terra has only supported manual, C-style resource management. While functional, this approach limits the full potential of Terra’s powerful metaprogramming capabilities. To address this limitation, the current implementation introduces **automated resource management**.

---

## Scope-Bound Resource Management (RAII)

The new implementation provides **scope-bound resource management (RAII)**, a method typically associated with systems programming languages like C++ and Rust. With RAII, a resource's lifecycle is tied to the stack object that manages it. When the object goes out of scope and is not explicitly returned, the associated resource is automatically destructed.

### Examples of Resources Managed via RAII:
- Allocated heap memory
- Threads of execution
- Open sockets
- Open files
- Locked mutexes
- Disk space
- Database connections

---

## Experimental Implementation Overview

The current Terra implementation supports the **Big Three** (as described by the [Rule of Three](https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)) in C++):

1. **Object destruction**
2. **Copy assignment**
3. **Copy construction**

However, **rvalue references** (introduced in C++11) are not supported in Terra. As a result, the current RAII implementation is comparable to that of **C++03** or **Rust**.

### Key Features:
Compiler support is provided for the following methods:
```terra
A.methods.__init(self : &A)
A.methods.__dtor(self : &A)
(A or B).methods.__copy(from : &A, to : &B)
```
These methods facilitate the implementation of smart containers and pointers, such as `std::string`, `std::vector` and `std::unique_ptr`, `std::shared_ptr`, `boost:offset_ptr` in C++.

### Design Overview
* No Breaking Changes: This implementation does not introduce breaking changes to existing Terra code. No new keywords are required, ensuring that existing syntax remains compatible.
* Type Checking Integration: These methods are introduced during the type-checking phase (handled in terralib.lua). They can be implemented as either macros or Terra functions.
* Composability: The implementation follows simple, consistent rules that ensure smooth compatibility with existing Terra syntax for construction, casting, and function returns.
* Heap resources: Heap resources are allocated and deallocated using standard C functions like malloc and free, leaving memory allocation in the hands of the programmer. The idea here is that remaining functionality, such as allocators, are implemented as libraries.

---

## Safety and Future Work

While safety is a growing concern in programming, the current implementation has several safety challenges, similar to those in C++ or Rust's unsafe mode.

### Future Work Includes:
1. **Library support for composable allocators**:
- Tracing or debugging allocators to detect memory leaks or other faulty behavior.
2. **Compile-time borrow checking**:
- Similar to Rust or Mojo, ensuring safer resource usage.
3. **Improved lifetime analysis**:
- Making the compiler aware of when resources (e.g., heap allocations) are introduced.
- Making the compiler aware of when resources are last used.

---

## Compiler supported methods for RAII
A managed type is one that implements at least `__dtor` and optionally `__init` and `__copy` or, by induction, has fields or subfields that are of a managed type. In the following we assume `struct A` is a managed type.

To enable RAII, import the library */lib/terralibext.t* using
```terra
require "terralibext"
```
The compiler only checks for `__init`, `__dtor` and `__copy` in case this library is loaded.

### Object initialization
`__init` is used to initialize managed variables:
```
A.methods.__init(self : &A)
```
The compiler checks for an `__init` method in any variable definition statement, without explicit initializer, and emits the call right after the variable definition, e.g.
```
var a : A
a:__init() --generated by compiler
```
### Copy assignment
`__copy` enables specialized copy-assignment and, combined with `__init`, copy construction. `__copy` takes two arguments, which can be different, as long as one of them is a managed type, e.g.
```
A.metamethods.__copy(from : &A, to : &B)
```
and / or
```
A.metamethods.__copy(from : &B, to : &A)
```
If `a : A` is a managed type, then the compiler will replace a regular assignment by a call to the implemented `__copy` method
```
b = a ----> A.methods.__copy(a, b)
```
or
```
a = b ----> A.methods.__copy(b, a)
```
`__copy` can be a (overloaded) terra function or a macro.

The programmer is responsible for managing any heap resources associated with the arguments of the `__copy` method.

### Copy construction
In object construction, `__copy` is combined with `__init` to perform copy construction. For example,
```
var b : B = a
```
is replaced by the following statements
```
var b : B
b:__init() --generated by compiler if `__init` is implemented
A.methods.__copy(a, b) --generated by compiler
```
If the right `__copy` method is not implemented but a user defined `__cast` metamethod exists that can cast one of the arguments to the correct type, then the cast is performed and then the relevant copy method is applied.

### Object destruction
`__dtor` can be used to free heap memory
```
A.methods.__dtor(self : &A)
```
The implementation adds a deferred call to `__dtor ` near the end of a scope, right before a potential return statement, for all variables local to the current scope that are not returned. Hence, `__dtor` is tied to the lifetime of the object. For example, for a block of code the compiler would generate
```
do
var x : A, y : A
...
...
defer x:__dtor() --generated by compiler
defer y:__dtor() --generated by compiler
end
```
or in case of a terra function
```
terra foo(x : A)
var y : A, z : A
...
...
defer z:__dtor() --generated by compiler
return y
end
```
`__dtor` is also called before any regular assignment (if a __copy method is not implemented) to free 'old' resources. So
```
a = b
```
is replaced by
```
a:__dtor() --generated by compiler
a = b
```
## Compositional API's
If a struct has fields or subfields that are managed types, but do not implement `__init`, `__copy` or `__dtor`, then the compiler will generate default methods that inductively call existing `__init`, `__copy` or `__dtor` methods for its fields and subfields. This enables compositional API's like `vector(vector(int))` or `vector(string)`. This is implemented as an extension to *terralib.lua* in *lib/terralibext.t*.

## Examples
The following files have been added to the terra testsuite:
* *raii.t* tests whether `__dtor`, `__init`, and `__copy` are evaluated correctly for simple datatypes.
* *raii-copyctr.t* tests `__copy`.
* *raii-copyctr-cast.t* tests the combination of `metamethods.__cast` and `__copy`.
* *raii-unique_ptr.t* tests some functionality of a unique pointer type.
* *raii-shared_ptr.t* tests some functionality of a shared pointer type.
* *raii-offset_ptr.t* tests some functionality of an offset pointer implementation, found e.g. in *boost.cpp*.
* *raii-compose.t* tests the compositional aspect.

You can have a look there for some common code patterns.

## Current limitations
* The implementation is not aware of when an actual heap allocation is made and therefore assumes that a managed variable always carries a heap resource. It is up to the programmer to properly initialize pointer variables to nil to avoid calling 'free' on uninitialized pointers.
* Tuple (copy) assignment (regular or using `__copy`) are prohibited by the compiler in case of managed variables. This is done to prevent memory leaks or unwanted deletions in assignments such as
```
a, b = b, a
```
Loading
Loading