Subject: Re: accessing Lisp values from C From: Erik Naggum <email@example.com> Date: 1997/04/29 Newsgroups: comp.lang.lisp Message-ID: <firstname.lastname@example.org> * Heiko Kirschke | What you get from lisp_value is the direct LISP object in its internal | Allegro representation. lisp.h tells you how to decode the arg on the C | side. The lower 3 (?) or 2 (?) bits of the value are used as tag bits. | When these bits are 0, the value must be interpreted as a pointer to a | memory-allocated area containing the (non-immediate) LISP object. Very | roughly, these are all objects requiring allocated memory, like symbols, | vectors, ... | | When the tag bits are != 0, the value is an `immediate value', i.e. a | fixnum or a character, without any associated allocated memory. wrong! please be careful with the details when you give such advice. all of this is easy to understand from actually inspecting lisp.h. Allegr CL (the real thing, for Unix) uses three tag bits on most architectures. 0 is even integer and 4 is odd integer (effectively giving 29-bit signed fixnums). all other tags effectively cause the object to be offset somewhat from the pointer. e.g., a cons may have tag 1 and thus you find the CAR on the address having a numeric value one less than the pointer. and the CDR on the address three bytes up. if you can align all objects on word boundaries, and all allocation on 8-byte boundaries, and you have a CPU that can do indexing on registers before access, you lose exactly nothing in performance, and win the ability to use hardware traps for unaligned memory access in the process. | > My problem is that lisp_value returns a different number than | > the registered value in lisp (I noted that it is always multiplied | > by four, but I am not sure). | | So your assumption that the value you receive from lisp_value on the C | side is the value put into the LISP side multiplied by 4 is correct; to | be exact, it is someting like <C value> := <LISP value> * 4 + <fixnum tag | bits value>. yet, to be _exact_, it is multiplied by four (left-shifted two bits), and that's all there is to it. one some architectures, having the lower two bits zero in integers also makes a number of interesting instructions available. note that this is the usual way to deal with tags on byte-adressable CPU's with alignment constraints. #\Erik -- if we work harder, will obsolescence be farther ahead or closer?