Skip to content
justinmann edited this page Dec 24, 2017 · 1 revision

There are four different "modes" for data:

  • stack - stored on the stack - default for storing data
  • heap - stored on the heap and reference counted
  • local - reference to a stack or heap variable - default for function parameters
  • weak - stored on the heap, but this reference will not keep it alive

Stack

Stack data is the most efficient, but it has a limited scope. For instance, you cannot keep stack data without making a copy of the data. Stack data that is returned also needs to be copied unless it was created from another function and immediately returned.

class() { this }

a : stack class()
b'stack class : a // This will fail because it needs to be copied
b : copy a

function()'stack class { a } // This will fail because it needs to be copied 
function()'stack class { copy a }
function()'stack class { class() } // Newly created and immediately returned is okay

Heap

Heap data can be assigned to other variables without a copy, but it is more expensive to create and delete. You should use the minimum amount of heap data in your application.

class() { this }

a : heap class()
b : a
function()'heap class { a }

Local

It is rarely useful to explicitly make data "local". This is primarily used by the compiler to efficiently pass data into function calls.

Weak

Because SJ uses reference counting to determine when to free data, it is possible create circular dependency that can never be freed. The solution is a weak reference.

classA(
     b : 'heap classB
) { this }

classB(
     a := empty'heap classA
) { this }

b : heap classB()
a : heap classA(b)
b.a = valid(a) // Created a circular reference that can never be freed

classAWeak(
     b : 'heap classBWeak
) { this }

classBWeak(
     a := empty'weak classAWeak
) { this }

b : heap classBWeak()
a : heap classAWeak(b)
b.a = valid(weak a) // No circular ref

Clone this wiki locally