nupp.mem.heap
Owned, malloc-backed C arrays.
The returned array is affine and is released with free at scope exit. Its logical element count moves with the allocation and its pointer is available only through checked span views.
local heap = nupp.mem.heap
do
local values = heap.allocate(ffi.typeof<int32>(), 4)
local writable = values:write()
writable[1] = 42 as int32
drop writable
local readable = values:read()
print(readable[1], #readable)
end -- free runs hereAn allocation here sits outside LuaJIT's GC allocation limit, which is the reason to reach for one over a carray. Reading and writing are the operations nupp.mem.span defines, and a live reader and a live writer over one array report NUPP2607.
See c-interop.md for how this sits beside carray, and ownership.md for the borrow rules the views are written against.
Module contents
Types
| Type | Kind | Description |
|---|---|---|
Array | record | An owned contiguous native allocation whose logical count cannot be separated from its pointer in checked code. |
ArrayToken | interface |
Functions
| Function | Kind | Description |
|---|---|---|
allocate | function | Allocates count contiguous values of element outside LuaJIT's GC allocation limit. |
destroyArray | function | Frees an allocation, which is what every heap array's contract names. |
Types#
Arrayrecord#
record heap.Array<T> is heap.ArrayToken
readonly count: integer
drop: function(takes self: Array<T>): nil
close: function(takes self: Array<T>): nil
read: function(borrows self: Array<T>): span.Span<T> borrows (self)
write: function(exclusive self: Array<T>): span.Writable<T> borrows (self)
endAn owned contiguous native allocation whose logical count cannot be separated from its pointer in checked code.
Type parameters
| Name | Description |
|---|---|
T |
Methods
drop#
drop: function(takes self: Array<T>): nilReleases the allocation. Scope exit invokes this automatically.
Arguments
| Name | Type | Description |
|---|---|---|
takes self | Array<T> |
Returns
| Type | Description |
|---|---|
nil |
close#
Frees the allocation. drop and scope exit both reach this.
Arguments
| Name | Type | Description |
|---|---|---|
takes self | Array<T> |
Returns
| Type | Description |
|---|---|
nil |
read#
Borrows the whole allocation as a shared checked span.
The borrow lasts as long as the span does, so a writer cannot be taken out while one is live.
Arguments
| Name | Type | Description |
|---|---|---|
borrows self | Array<T> |
Returns
| Type | Description |
|---|---|
span.Span<T> borrows (self) |
write#
Borrows the whole allocation as an affine checked write span.
Exclusive for as long as the writer is live, so read reports NUPP2607 until the writer is dropped.
Arguments
| Name | Type | Description |
|---|---|---|
exclusive self | Array<T> |
Returns
| Type | Description |
|---|---|
span.Writable<T> borrows (self) |
Fields
ArrayTokeninterface#
sealed interface heap.ArrayToken
close: function(takes self: ArrayToken): nil
endMethods
close#
close: function(takes self: ArrayToken): nilArguments
| Name | Type | Description |
|---|---|---|
takes self | ArrayToken |
Returns
| Type | Description |
|---|---|
nil |
Functions#
heap.allocatefunction#
function heap.allocate<T>(element: ctype<T>, count: integer): affine(heap.Array<T>, heap.destroyArray)Allocates count contiguous values of element outside LuaJIT's GC allocation limit.
The result owns the allocation and frees it at its lexical boundary. The bytes are not zeroed, so a program that reads before it writes reads whatever was there.
Type parameters
| Name | Description |
|---|---|
T |
Arguments
| Name | Type | Description |
|---|---|---|
element | ctype<T> | the ctype of one element |
count | integer | how many elements to allocate |
Returns
| Type | Description |
|---|---|
affine(heap.Array<T>, heap.destroyArray) | the array, owned by the caller |
Raises
when count is negative, the byte size overflows a Lua integer, or malloc fails
heap.destroyArrayfunction#
function heap.destroyArray<T is heap.ArrayToken>(takes self: T): nilFrees an allocation, which is what every heap array's contract names.
Nothing calls this by hand. It is the terminal consumer affine carries, so a scope boundary or an explicit drop reaches it.
Type parameters
| Name | Description |
|---|---|
T |
Arguments
| Name | Type | Description |
|---|---|---|
takes self | T | the array, spent by this call |
Returns
| Type | Description |
|---|---|
nil |