home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!elroy.jpl.nasa.gov!ames!data.nas.nasa.gov!taligent!apple!cambridge.apple.com!bill@cambridge.apple.com
- From: bill@cambridge.apple.com (Bill St. Clair)
- Newsgroups: comp.lang.lisp.mcl
- Subject: Re: FF-example.c
- Message-ID: <9208281527.AA08770@cambridge.apple.com>
- Date: 28 Aug 92 16:33:21 GMT
- Sender: info-mcl-request@cambridge.apple.com
- Lines: 90
- Approved: comp.lang.lisp.mcl@Cambridge.Apple.C0M
- Full-Name: Bill St. Clair
- Original-To: ST7990@SIUCVMB.SIU.EDU
- Original-Cc: info-mcl
-
- >This question concerns the C code in MCL 2.0:examples:FF
- >examples:ff-example.c. I'd like to know what the following define
- >statements are trying to do:
- >define CDR(x) (* ((long *) (x)))
- >
- >define CAR(x) (* (((Ptr *) (x)) -1))
- >
- >define MACPTR_PTR(x) (* (Ptr *) (((long) (x)) +7)))
- >
- >The definitions are the refered by
- >CDR(* x), CAR(* x) and (MACPTR_PTR(* x) where x is
- >type defined as long *x;
- >
- >The exact code is as follows:
- >growptr(x)
- >long *x;
- >{
- >Ptr newp;
- >if (MACPTR_PTR(CAR(*x))) DisposPtr(MACPTR_PTR(CAR(*x)));
- >newp = NewPtr((CDR(*x))>>FIXNUM_SHIFT);
- >MACPTR_PTR(CAR(*x))=newp;
- >}
- >
- >The lisp FFI defines the above function as
- >
- >(deffcfun (grow-ptr "growptr") ((cons :lisp-ref) :novalue))
- >
- >The lisp call is as follows:
- >(grow-ptr (cons (#_NewPtr 5) 10))
- >_NewPtr 5) 10))
- >
- >I understand the overall function of the code; my proble lies in the
- >particular define stamements.
-
- In order to understand this code, you need to understand how MCL
- represents conses and macptrs. You can get a start on this by reading
- the "Lisp Object Representation" section of the file "ccl:library;lap.doc"
- and looking at the constants in "ccl:library;lispequ.lisp".
-
- A CONS is a pointer to the second of two longwords. The first longword
- is the CAR of the cons. The second longword (the one at which the CONS
- points) is the CDR.
-
- It seems to me that CDR would be more consistently (with the
- CAR & MACPTR-PTR definitions) stated as:
-
- #define CDR(x) (* ((Ptr *) (x)))
-
- This would have necessitated casting the result to long in its
- use in grow_ptr.
-
- The definitions do the standard "I don't know what type the argument
- I'm getting is so I'll cast it to where it needs to be, nor do I know
- whether I need to put parens around it so I will just to be careful"
- that is always necessary when writing C macros.
-
- A MACPTR is a lisp uvector. A uvector has 4 bytes of GC overhead,
- 1 byte of subtype, 3 bytes of length, then length bytes of data.
- A MACPTR is tagged as 1 in the low three bits, meaning that it
- points one byte into the 8 byte header. Hence MACPTR_PTR is accessing the
- first data word in the MACPTR, 1+7 bytes from the start of the header.
- This is where the memory address that the MACPTR boxes is stored.
-
- A lisp fixnum (passed in the CDR of the argument) is tagged as 0 in the
- low three bits. Hence you need to right shift it 3 (FIXNUM_SHIFT) bits
- to get a C long.
-
- grow_ptr could have been written without using the macros as follows
- (though I may have made some mistakes due to my infrequent use of C):
-
- growptr (consptr)
- Ptr *consptr, macptr, macptr_ptr;
- long car, cdr;
- {
- Ptr newp;
- car = (long) *(*consptr - 1);
- cdr = (long) **consptr;
- macptr = (Ptr) (car + 7)
- macptr_ptr = (Ptr) (* macptr)
- if (macptr_ptr) DisposPtr(macptr_ptr);
- newp = NewPtr(cdr >> FIXNUM_SHIFT);
- *macptr = newp;
- }
-
- The reason for doing this with macros is that if the representation
- changes in the future (and Gary has already swapped CAR & CDR and
- eliminated 4 of the 8 bytes of overhead for a uvector), you can simply
- change the macros and recompile.
-
- Clear as mud?
-