Skip to content

Commit

Permalink
Add Pointer.pointer
Browse files Browse the repository at this point in the history
This method is used to create a pointer to a pointer, relying on Inko's
memory layout to make this possible. Pointer pointers are needed for C
APIs that rely on output pointers, such as the SQLite API.

Changelog: added
  • Loading branch information
yorickpeterse committed Sep 26, 2022
1 parent 9698cda commit 8eac159
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 0 deletions.
11 changes: 11 additions & 0 deletions libstd/src/std/ffi.inko
Expand Up @@ -22,6 +22,9 @@ import std::set::Set
# The address used for NULL pointers.
let NULL_ADDRESS = 0x0

# The size (in bytes) of an Inko object header.
let HEADER_SIZE = 16

# A pointer to a C value.
class pub Pointer {
# The raw pointer.
Expand Down Expand Up @@ -75,6 +78,14 @@ class pub Pointer {
fn pub raw -> Any {
@raw
}

# Returns a pointer to the raw pointer wrapped by `self` (aka a pointer
# pointer).
fn pub pointer -> Pointer {
let addr = _INKO.ffi_pointer_address(self) + HEADER_SIZE

Pointer.from_address(addr)
}
}

impl Clone for Pointer {
Expand Down
9 changes: 9 additions & 0 deletions libstd/test/std/test_ffi.inko
Expand Up @@ -81,6 +81,15 @@ fn pub tests(t: mut Tests) {
t.equal(mem.ptr.read(type: Type.U8, offset: 0) as Int, 10)
}

t.test('Pointer.pointer') fn (t) {
let a = Pointer.null
let b = a.pointer

b.write(type: Type.U8, offset: 0, value: 10)
t.equal(a.address, 10)
t.not_equal(b.address, 10)
}

t.test('Pointer.clone') fn (t) {
let ptr = Pointer.from_address(0x4)

Expand Down

0 comments on commit 8eac159

Please sign in to comment.