[Openmcl-devel] MCL record forms (emulating in OpenMCL)

Gary Byers gb at clozure.com
Fri Dec 1 09:49:09 UTC 2006

On Thu, 30 Nov 2006, Brent Fulgham wrote:

> Does OpenMCL have an analogous form for the following MCL forms
> record-field-length

There apparently isn't anything documented/exported.
One thing that's fairly general (and maybe a good candidate
for exportation/documentation) is:

CCL::%FOREIGN-TYPE-OR-RECORD-SIZE (type-or-record-name &optional (units :bits))

Foreign type names are (as in C, differing from C++ and some other
languages) in a separate namespace from "record" (struct/union) names.
CCL::%FOREIGN-TYPE-OR-RECORD-SIZE will try to interpret its first
argument as the name of a type and, if that fails, will look it up as
a struct/union tag.  If it finds a type or record tag, it'll determine
that object's size in bits and then return that size in the specifie
units (:BITS, :BYTES, or 32-bit :WORDS), rounding up if necessary.

? (ccl::%foreign-type-or-record-size :double)
? (ccl::%foreign-type-or-record-size :double :bytes)

> %put-long

(setf (%get-long pointer &optional offset) value)
has the same effect as MCL's old
(%put-long pointer value &optional offset)

> %put-single-float (etc...)

(setf (%get-single-float ...) ...) is analogous

MCL's %PUT- functions had the same side-effect (storing something in
foreign memory), but unfortunately were defined to return their
first argument (the pointer) rather than the value being stored
in memory.  They were almost always used for effect only and I doubt
that the code you're looking at cares what value was returned, but
the OpenMCL SETF inverses will return a different value than the
analogous %PUT functions did.

OpenMCL's functions are probably/hopefully better about insisting
that the value is of the right size/signedness, though I think
that they'll sometimes let you be pretty sloppy about that sort
of thing.  I think that MCL's were probably intentionally more
lenient, so somehing like (%PUT-BYTE P 0 511) would possibly store
the low 8 bits of 511 (255) in memory and not get too upset about
the fact that there was an extra bit in that value; OpenMCL might/
should get upset in many more of those cases, but is probably not
100% rigorous about it.

(If there's much old MCL code that tries to exploit this sloppiness,
I probably wrote it ...)

> Example:
> (defun INIT-ARRAY (&array Type &rest Values)
>   (declare (dynamic-extent Values))
>   (let ((Index 0)
>         (Size (record-field-length Type)))
>     (dolist (Value Values &Array)
>       (ecase Type
>         (:long (%put-long &Array Value Index))
>         (:single-float (%put-single-float &Array Value Index)))
>       (incf Index Size))))

Take a good look at that function.  How general is it in practice ?
(It only tries to handle 32-bit/4-byte "long" and 32-bit/4-byte single-float
values; why does it need to determine the size of its type argument
at all ?

> I'm trying to find documentation for MCL's record forms, but there
> doesn't seem to be much on the web (or in the MCL trial download I
> just installed).
> Figuring out the forms for put-long and friends should be pretty
> easy, but I'm not sure what the proper stuff should look like for
> extracting information out of the record.
> Anyone with some MCL perspective?
> Thanks,
> -Brent
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list