This unit provides a number of handy low-level operations. Use
at your own risk.
This unit uses the srfi-4 and extras units.
-
- [procedure] (address->pointer ADDRESS)
-
Creates a new foreign pointer object initialized to point to the address
given in the integer ADDRESS.
- [procedure] (allocate BYTES)
-
Returns a pointer to a freshly allocated region of static memory.
This procedure could be defined as follows:
(define allocate (foreign-lambda c-pointer "malloc" integer))
- [procedure] (free POINTER)
-
Frees the memory pointed to by POINTER. This procedure could
be defined as follows:
(define free (foreign-lambda c-pointer "free" integer))
- [procedure] (null-pointer)
-
Another way to say (address->pointer 0).
- [procedure] (null-pointer? PTR)
-
Returns #t if PTR contains a NULL pointer,
or #f otherwise.
- [procedure] (object->pointer X)
-
Returns a pointer pointing to the Scheme object X, which should be a
non-immediate object. Note that data in the garbage collected heap
moves during garbage collection.
- [procedure] (pointer? X)
-
Returns #t if X is a foreign pointer object, and
#f otherwise.
- [procedure] (pointer->address PTR)
-
Returns the address, to which the pointer PTR points.
- [procedure] (pointer->object PTR)
-
Returns the Scheme object pointed to by the pointer PTR.
- [procedure] (pointer-offset PTR N)
-
Returns a new pointer representing the pointer PTR increased
by [N].
- [procedure] (pointer-u8-ref PTR)
-
Returns the unsigned byte at the address designated by PTR.
- [procedure] (pointer-s8-ref PTR)
-
Returns the signed byte at the address designated by PTR.
- [procedure] (pointer-u16-ref PTR)
-
Returns the unsigned 16-bit integer at the address designated by PTR.
- [procedure] (pointer-s16-ref PTR)
-
Returns the signed 16-bit integer at the address designated by PTR.
- [procedure] (pointer-u32-ref PTR)
-
Returns the unsigned 32-bit integer at the address designated by PTR.
- [procedure] (pointer-s32-ref PTR)
-
Returns the signed 32-bit integer at the address designated by PTR.
- [procedure] (pointer-f32-ref PTR)
-
Returns the 32-bit float at the address designated by PTR.
- [procedure] (pointer-f64-ref PTR)
-
Returns the 64-bit double at the address designated by PTR.
- [procedure] (pointer-u8-set! PTR N)
-
Stores the unsigned byte N at the address designated by PTR.
- [procedure] (pointer-s8-set! PTR N)
-
Stores the signed byte N at the address designated by PTR.
- [procedure] (pointer-u16-set! PTR N)
-
Stores the unsigned 16-bit integer N at the address designated by PTR.
- [procedure] (pointer-s16-set! PTR N)
-
Stores the signed 16-bit integer N at the address designated by PTR.
- [procedure] (pointer-u32-set! PTR N)
-
Stores the unsigned 32-bit integer N at the address designated by PTR.
- [procedure] (pointer-s32-set! PTR N)
-
Stores the unsigned 32-bit integer N at the address designated by PTR.
- [procedure] (pointer-f32-set! PTR N)
-
Stores the 32-bit floating-point number N at the address designated by PTR.
- [procedure] (pointer-f64-set! PTR N)
-
Stores the 64-bit floating-point number N at the address designated by PTR.
-
- [procedure] (extend-procedure PROCEDURE X)
-
Returns a copy of the procedure PROCEDURE which contains an
additional data slot initialized to X. If PROCEDURE
is already an extended procedure, then it's data slot is changed to
contain X and the same procedure is returned.
- [procedure] (extended-procedure? PROCEDURE)
-
Returns #t if PROCEDURE is an extended procedure,
or #f otherwise.
- [procedure] (procedure-data PROCEDURE)
-
Returns the data object contained in the extended procedure
PROCEDURE.
- [procedure] (set-procedure-data! PROCEDURE X)
-
Changes the data object contained in the extended procedure
PROCEDURE to X.
(define foo
(letrec ((f (lambda () (procedure-data x)))
(x #f) )
(set! x (extend-procedure f 123))
x) )
(foo) ==> 123
(set-procedure-data! foo 'hello)
(foo) ==> hello
-
- [procedure] (byte-vector FIXNUM ...)
-
Returns a freshly allocated byte-vector with FIXNUM ... as its
initial contents.
- [procedure] (byte-vector? X)
-
Returns #t if X is a byte-vector object, or
#f otherwise.
- [procedure] (byte-vector-fill! BYTE-VECTOR N)
-
Sets each element of BYTE-VECTOR to N, which should
be an exact integer.
- [procedure] (byte-vector->list BYTE-VECTOR)
-
Returns a list with elements taken from BYTE-VECTOR.
- [procedure] (byte-vector->string BYTE-VECTOR)
-
Returns a string with the contents of BYTE-VECTOR.
- [procedure] (byte-vector-length BYTE-VECTOR)
-
Returns the number of elements in BYTE-VECTOR.
- [procedure] (byte-vector-ref BYTE-VECTOR INDEX)
-
Returns the byte at the INDEXth position of BYTE-VECTOR.
- [procedure] (byte-vector-set! BYTE-VECTOR INDEX N)
-
Sets the byte at the INDEXth position of BYTE-VECTOR
to the value of the exact integer n.
- [procedure] (executable-byte-vector->procedure PBYTE-VECTOR)
-
Returns a procedure that on invocation will execute the code
in PBYTE-VECTOR, which should have been allocated using
make-executable-byte-vector. The procedure follows the native C
calling convention, and will be called as if declared with the following
prototype:
void <procedure>(int argc, C_word closure, C_word k, C_word arg1, ...)
-
argc contains the number of arguments arg1, ...
that are passed plus 2 (including closure and k).
-
closure is the procedure object itself.
-
k is a continuation closure that should be called when
the code is about to return.
typedef void (*CONTINUATION)(int argc, C_word closure, C_word result);
((CONTINUATION)k[ 1 ])(2, k, result)
(k is a data object with the second word being the actual code
pointer)
An example:
(define x (make-executable-byte-vector 17))
(move-memory!
'#u8(#x8b #x44 #x24 #x0c ; movl 12(%esp), %eax - `k'
#x8b #x5c #x24 #x10 ; movl 16(%esp), %ebx - `arg1'
#x53 ; pushl %ebx - push result
#x50 ; pushl %eax - push k
#x6a #x02 ; pushl $2 - push argument count
#x8b #x40 #x04 ; movl 4(%eax), %eax - fetch code pointer
#xff #xd0) ; call *%eax
x)
(define y (executable-byte-vector->procedure x))
(y 123) ==> 123
The result of calling executable-byte-vector->procedure with
a non-executable statically allocated byte-vector is undefined.
- [procedure] (invoke-executable-byte-vector PBYTE-VECTOR ARG1 ...)
-
Invokes the machine code stored in the executable byte-vector
PBYTE-VECTOR. The native C calling conventions are used, but
the invoked code is passed a single argument containing a pointer to an
array of the Scheme objects ARG1 ....
(define v (make-executable-byte-vector 7))
(move-memory!
'#u8(#x8b #x44 #x24 #x04 ; movl 4(%esp), %eax
#x8b #x00 ; movl 0(%eax), %eax
#xc3) ; ret
v)
(invoke-executable-byte-vector v "hello!") ==> "hello!"
- [procedure] (list->byte-vector LIST)
-
Returns a byte-vector with elements taken from LIST, where the
elements of LIST should be exact integers.
- [procedure] (make-byte-vector SIZE [INIT])
-
Creates a new byte-vector of size SIZE. If INIT is
given, then it should be an exact integer with which every element of
the byte-vector is initialized.
- [procedure] (make-executable-byte-vector SIZE [INIT])
-
As make-static-byte-vector, but the code is suitable for
execution. Note: this feature is currently only available on
x86 platforms.
- [procedure] (make-static-byte-vector SIZE [INIT])
-
As make-byte-vector, but allocates the byte-vector in storage
that is not subject to garbage collection. To free the allocated memory,
one has to call release explicitly.
- [procedure] (static-byte-vector->pointer PBYTE-VECTOR)
-
Returns a pointer object pointing to the data in the statically allocated
byte-vector PBYTE-VECTOR.
- [procedure] (string->byte-vector STRING)
-
Returns a byte-vector with the contents of STRING.
-
- [procedure] (evict X [ALLOCATOR])
-
Copies the object X recursively into the memory pointed
to by the foreign pointer object returned by ALLOCATOR,
which should be a procedure of a single argument (the number of bytes
to allocate). The freshly copied object is returned. This facility
allows moving arbitrary objects into static memory, but care should be
taken when mutating evicted data: setting slots in evicted vector-like
objects to non-evicted data is not allowed. It is possible to
set characters/bytes in evicted strings or byte-vectors, though. It is
advisable not to evict ports, because they might be mutated by
certain file-operations. evict is able to handle circular and
shared structures, but evicted symbols are no longer unique: a fresh
copy of the symbol is created, so
(define x 'foo)
(define y (evict 'foo))
y ==> foo
(eq? x y) ==> #f
(define z (evict '(bar bar)))
(eq? (car z) (cadr z)) ==> #t
The ALLOCATOR defaults to allocate.
- [procedure] (evict-to-location X PTR [LIMIT])
-
As evict but moves the object at the address pointed to by
the machine pointer PTR. If the number of copied bytes exceeds
the optional LIMIT then an error is signalled. Two values are
returned: the evicted object and a new pointer pointing to the first
free address after the evicted object.
- [procedure] (evicted? X)
-
Returns #t if X is a non-immediate evicted data object,
or #f otherwise.
- [procedure] (object-size X)
-
Returns the number of bytes that would be needed to evict the data
object X.
- [procedure] (release X [RELEASER])
-
Frees memory occupied by the evicted object X recursively.
RELEASER should be a procedure of a single argument (a foreign
pointer object to the static memory to be freed) and defaults to the
C-library free().
- [procedure] (unevict X)
-
Copies the object X and nested objects back into the normal
Scheme heap. Symbols are re-interned into the symbol table. Strings
and byte-vectors are not copied.
A locative is an object that points to an element of a containing object,
much like a ``pointer'' in traditional programming languages. The element can
be accessed and changed indirectly, by performing access or change operations
on the locative. The container object can be computed by calling the
location->object procedure. Even though the locative refers to an element of a container object,
the container can still be reclaimed by garbage collection.
Locatives may be passed to foreign procedures that expect pointer arguments.
The effect of creating locatives for evicted data (see evict) is undefined.
-
- [procedure] (make-locative EXP [INDEX
- )]
Creates a locative that refers to the element of the non-immediate object EXP
at position INDEX. EXP may be a vector, pair, string, byte-vector,
SRFI-4 number-vector, SRFI-25 array or record. INDEX should be a fixnum,
a slot-name (in case EXP is a SRFI-9 record), or a valid index into
a SRFI-25 array. INDEX defaults to 0.
- [procedure] (locative? X)
-
Returns #t if X is a locative, or #f otherwise.
- [procedure] (locative-ref LOC)
-
Returns the element to which the locative LOC refers. If the containing
object has been reclaimed by garbage collection, an error is signalled.
- [procedure] (locative-set! LOC X)
-
Changes the element to which the locative LOC refers to X.
If the containing
object has been reclaimed by garbage collection, an error is signalled.
- [procedure] (locative->object LOC)
-
Returns the object that contains the element referred to by LOC or
#f if the container has been reclaimed by garbage collection.
-
- [procedure] (align-to-word PTR-OR-INT)
-
Accepts either a machine pointer or an integer as argument and returns
a new pointer or integer aligned to the native word size of the host
platform.
- [procedure] (become! ALIST)
-
Changes the identity of the value of the car of each pair in
ALIST to the value of the cdr. Both values may not be immediate
(i.e. exact integers, characters, booleans or the empty list).
(define x "i used to be a string")
(define y '#(and now i am a vector))
(become! (list (cons x y)))
x ==> #(and now i am a vector)
y ==> #(and now i am a vector)
(eq? x y) ==> #t
Note: this operation invokes a major garbage collection.
The effect of using become! on evicted data (see evict)
is undefined.
- [procedure] (block-ref BLOCK INDEX)
-
Returns the contents of the INDEXth slot of the object
BLOCK. BLOCK may be a vector, record structure,
pair or symbol.
- [procedure] (block-set! BLOCK INDEX X)
-
Sets the contents of the INDEXth slot of the object
BLOCK to the value of X. BLOCK may be a
vector, record structure, pair or symbol.
- [procedure] (copy X)
-
Copies X recursively and returns the fresh copy. Objects
allocated in static memory are copied back into garbage collected storage.
- [procedure] (make-record-instance SYMBOL ARG1 ...)
-
Returns a new instance of the record type SYMBOL, with it's
slots initialized to ARG1 .... To illustrate:
(define-record point x y)
expands into something quite similar to:
(begin
(define (make-point x y)
(make-record-instance 'point x y) )
(define (point? x)
(and (record-instance? x)
(eq? 'point (block-ref x 0)) ) )
(define (point-x p) (block-ref p 1))
(define (point-x-set! p x) (block-set! p 1 x))
(define (point-y p) (block-ref p 2))
(define (point-y-set! p y) (block-set! p 1 y)) )
- [procedure] (move-memory! FROM TO [BYTES])
-
Copies BYTES bytes of memory from FROM to TO.
FROM and TO may be strings, primitive byte-vectors,
SRFI-4 byte-vectors (see: 6.12), memory mapped files or foreign
pointers (as obtained from a call to foreign-lambda, for
example). if BYTES is not given and the size of the source
or destination operand is known then the maximal number of bytes will
be copied.
- [procedure] (number-of-bytes BLOCK)
-
Returns the number of bytes that the object BLOCK contains.
BLOCK may be any non-immediate value.
- [procedure] (number-of-slots BLOCK)
-
Returns the number of slots that the object BLOCK contains.
BLOCK may be a vector, record structure, pair or symbol.
- [procedure] (record-instance? X)
-
Returns #t if X is an instance of a record type.
See also: make-record-instance.