summaryrefslogtreecommitdiff
path: root/doc/api/libstd/alloc.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/api/libstd/alloc.txt')
-rw-r--r--doc/api/libstd/alloc.txt160
1 files changed, 160 insertions, 0 deletions
diff --git a/doc/api/libstd/alloc.txt b/doc/api/libstd/alloc.txt
new file mode 100644
index 0000000..c2692a4
--- /dev/null
+++ b/doc/api/libstd/alloc.txt
@@ -0,0 +1,160 @@
+{
+ title: Allocation
+ description: libstd: Allocation
+}
+
+Memory Allocation
+-----------------
+
+ pkg std =
+ generic mk : (val : @a -> @a#)
+ generic alloc : ( -> @a#)
+ generic zalloc : ( -> @a#)
+ generic free : (v:@a# -> void)
+ generic slalloc : (len : size -> @a[:])
+ generic slzalloc : (len : size -> @a[:])
+ generic slgrow : (sl : @a[:]#, len : size -> @a[:])
+ generic slzgrow : (sl : @a[:]#, len : size -> @a[:])
+ generic slfree : (sl : @a[:] -> void)
+ const bytealloc : (sz:size -> byte#)
+ const zbytealloc : (sz:size -> byte#)
+ const bytefree : (m:byte#, sz:size -> void)
+ ;;
+
+ generic mk : (val : @a -> @a#)
+
+`mk` creates a shallow copy of variable passed to it on the heap, returning a
+pointer to the value that it allocated. It is conventionally used for creating
+new copies of larger complex data structures, although it can be used to
+heapify any value.
+
+Returns: Pointer to fully initialized value of type '@a', based on the value
+passed in.
+
+ generic alloc : ( -> @a#)
+ generic zalloc : ( -> @a#)
+
+`alloc` allocates or free a single element of type @a, respectively. `zalloc`
+does the same, but zeros the memory allocated before returning it. `free` is
+used to return the memory allocated by these functions to the system. In
+general, `mk` is preferred over these functions, as it does not leave any
+values uninitialized.,
+
+ generic slalloc : (len : size -> @a[:])
+ generic slzalloc : (len : size -> @a[:])
+
+`slalloc` allocates or frees a slice of `len` items of type @a. `slzalloc`
+does the same, but zeros the memory allocated before returning it. `slfree`
+is used to return the memory to the system.
+
+ generic slgrow : (sl : @a[:]#, len : size -> @a[:])
+ generic slzgrow : (sl : @a[:]#, len : size -> @a[:])
+
+`slgrow` resizes the slize `sl` to length `len`, allocating the appropriate
+amount of memory. `slzgrow` does the same, but any elements between the old
+and new length are zeroed, as in slzalloc.
+
+ generic free : (v:@a# -> void)
+ generic slfree : (sl : @a[:] -> void)
+
+`free` and `slfree` free the storage allocated allocated for the value or
+slice passed to them , allowing it to be reused again later in the program.
+This memory may be unmapped and returned to the operating system, or it may be
+cached within the program.
+
+Any uses of memory after a `free` call is invalid.
+
+ const bytealloc : (sz:size -> byte#)
+ const zbytealloc : (sz:size -> byte#)
+ const bytefree : (m:byte#, sz:size -> void)
+
+`bytealloc` `bytezalloc`, and `bytefree` are the low level raw-byte allocation
+interface, returning blobs of bytes. Since the only way to use more than one
+of these bytes is to cast to a different type, the generic versions are
+generally a better choice.
+
+Examples
+---------
+
+Overall, the examples here should not be unfamiliar to anyone who has used
+either C or C++.
+
+### Mk
+
+`std.mk` should be used to create new, fully constructed values wherever
+possible. The code for this looks like:
+
+```{runmyr mk-example}
+use std
+
+type mytype =
+ a : int
+ b : char
+ c : byte[:[
+;;
+
+const main = {
+ var v
+
+ v = std.mk([
+ .a = 123
+ .b = 'x'
+ .c = "my string" /* this isn't heapified */
+ ])
+
+ std.free(v)
+}
+```
+
+### Alloc and Zalloc
+
+`alloc` and `zalloc` know the type that they're being assigned to, and use
+this to calulate the size to allocate:
+
+
+```{runmyr mk-example}
+use std
+
+const main = {
+ var x : int#
+ var y : int#
+
+ x = std.alloc()
+ y = std.zalloc()
+ std.free(x)
+ std.free(y)
+}
+```
+
+### Slalloc and Slzalloc
+
+`slalloc` and `slzalloc` take a size to allocate, but infer the type similar
+to `alloc` and `zalloc`. They're freed with std.slfree() and slzfree().
+Thankfully, unlike C++ delete and delete[], it's impossible to pass a slice
+to the wrong free function.
+
+
+```{runmyr mk-example}
+use std
+
+const main = {
+ var x : int[:]
+
+ x = std.slalloc(10) /* slice of 10 ints */
+ std.slfree(x)
+}
+```
+
+Growing slices can be done using slgrow() and slzgrow():
+
+```{runmyr mk-example}
+use std
+
+const main = {
+ var x : int[:]
+
+ x = std.slalloc(10) /* slice of 10 ints */
+ x = std.slzgrow(x, 20) /* x[10:20] are guaranteed to be zeroed.*/
+ std.slfree(x)
+}
+```