Owning wrapper over dynamically allocated storage with automatic destruction of the owned object while ownership remains in the wrapper.


Ownership boundary


OwnerWithDestructor (Value destructor -- ownerSchema)

Constructs an owner schema from an element schema and an explicit destructor callable.

Known issue: an OwnerWithDestructor fails to compile when its explicit destructor omits the allocation size: its DIE and acquire paths then call mplFree with the address only while mplFree expects the size and the address (Argument (target) is not on the stack reported from memory.mpl). A destructor with stack effect (element -- allocationSize) can compile when it returns the size of the original allocation. Owner and owner are unaffected.


objectSize (object -- size)

Returns the storage size for a value or the size supplied by its SIZE field.


Owner

Methods

valid?

(-- valid) Tests whether the owner currently holds an object.

acquire

(element --) Replaces the current owned object with element.

Postconditions

  • The previous owned object is destroyed if one was present.
  • valid? becomes TRUE.

clear

(--) Destroys the owned object and leaves the owner empty.

Postconditions

get

(-- ref) Returns Ref to the owned object.

Preconditions

lower

(-- owner) Returns an owner lowered to the base element type.

Preconditions

Postconditions

  • The original owner becomes empty.
  • The result owner takes over the same storage.

init

(object --) Allocates storage and initializes the owner from object.

Preconditions

initDerived

(object --) Allocates storage from object and stores the base view in the owner.

Preconditions

release

(-- ref) Releases the owned object as Ref and leaves the owner empty.

Preconditions

Postconditions

Fields


owner (element -- owner)

Constructs Owner from one element and transfers ownership of newly allocated storage to the result.

Compile-time owner and release types

"Owner"   use
"control" use

{} 0 {} [
  holder: 5 owner;
  holder.valid? printStack _:;
  holder.get printStack _:;
  @holder.release printStack _:;
  holder.valid? printStack _:;
  0
] "main" exportFunction

Expected Output During Compilation

Cond
Int32 Cref
Int32 Ref
FALSE

Runtime example

"Owner"   use
"String"  use
"control" use

{} Int32 {} [
  holder: 5 owner;
  ("value=" @holder.get new LF) printList
  released: @holder.release;
  ("released=" @released new LF) printList
  0
] "main" exportFunction

Expected Output

value=5
released=5

Runtime example: clear resets validity

"Owner"   use
"String"  use
"control" use

{} Int32 {} [
  holder: 5 owner;
  ("valid0=" holder.valid? LF) printList
  @holder.clear
  ("valid1=" holder.valid? LF) printList
  0
] "main" exportFunction

Expected Output

valid0=TRUE
valid1=FALSE

ownerDerived (element base destructor -- owner)

Constructs an owner with explicit base type and destructor handling.

Known issue: the result is an OwnerWithDestructor; it fails when the supplied destructor omits the required allocation size.


getHeapUsedSize (owner -- size)

Returns total heap usage of the owned object as Natx.


See also