$Revision: 5.0.2.3 $
Package: SYSTEM
Arguments: (address offset pos type &optional
coerce)
This function and sys:memref provide low-level memory access in Allegro CL. They are tightly integrated for very efficient compilation. Usually, when the type is known at compile-time, the code generated is less than three machine instructions.
Each function calculates an address in memory and performs a read from that address. The width and style of the read depends upon the type.
These functions are setf-able. The setf functions
write to the addressed memory instead of reading. WARNING: except when
the type is :lisp
, these setf-functions do not do any
setf-protection. If they are used to store non-lisp values into a memory location that was
intended to hold a lisp value, then GC death will occur.
Some checking can be done. When the setf functions for sys:memref
and sys:memref-int are given an optional non-nil
fifth coerce
argument, then runtime checking and coersion is done on the value before it is stored.
This is especially useful when the argument is a float value, but of the wrong type, as in
(setf (sys:memref array 0 0 :double-float :coerce) 1.0s0)
Note that when this fifth argument is supplied, then the call is not open-coded when compiled.
object (the first argument of memref) can be any lisp object, whose address (including the tag bits) is used as the base for the memory access. address (the first argument of memref-int) can be any integer that represents a valid address in the lisp. The value of this address (which may be a bignum) is used as the base for the memory access.
offset and pos are equivalent and interchangeable. They are both added as byte-offsets to the base address to determine the final memory address. Usually, the offset is some constant that adjusts for the start of the data in the object being accessed. Some of the offsets for lisp objects are described in <Allegro directory>/misc/lisp.h in the Allegro CL distribution. All offsets are available in the lisp itself using the (undocumented) comp::mdparam function on one of many available offset specifiers (see examples below).
The access-types that are available are as follows:
:unsigned-byte, :signed-byte (1-byte access, 1-byte integer result)
:unsigned-word, :signed-word (2-byte access, 2-byte integer result)
:unsigned-long, :signed-long (4-byte access, 4-byte integer result)
:fixnum (4-byte access, fixnum result [top bits lost on overflow])
:lisp (4-byte access, lisp result [careful, could confuse gc])
:single-float (4-byte access, 4-byte single-float result)
:double-float (8-byte access, 8-byte double-float result)
So, for example, you can access each byte of 1.0 individually:
USER(1): (setq off (comp::mdparam 'comp::md-single-float-data-adj))
-2
USER(2): (sys:memref 1.0 off 0 :unsigned-byte)
63
USER(3): (sys:memref 1.0 off 1 :unsigned-byte)
128
USER(4): (sys:memref 1.0 off 2 :unsigned-byte)
0
USER(5): (sys:memref 1.0 off 3 :unsigned-byte)
0
Or you can look at the whole object:
USER(6): (excl::pointer-to-address 1.0)
8544846
USER(7): (format t "~x" *)
82624e ;; <-- note that the tag is 6, for "other"
NIL
USER(8): (format t "~x" (sys:memref-int #x826248 0 0 :unsigned-long))
40000000 ;; #x40 is the type code for a single-float
NIL
USER(9): (format t "~x" (sys:memref-int #x826248 0 4 :unsigned-long))
3f800000
NIL
You can even set arbitrary locations in lisp objects (user beware):
USER(10): (setq off (comp::mdparam 'comp::md-symbol-plist-adj))
14
USER(11): (symbol-plist 'x)
NIL USER(12): (setf (sys:memref 'x off 0 :lisp) '(foo t))
(FOO T)
USER(13): (symbol-plist 'x)
(FOO T)
The general documentation description is in introduction.htm. The index is in index.htm.
Copyright (C) 1998-1999, Franz Inc., Berkeley, CA. All Rights Reserved.