home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / lisp / mcl / 1334 < prev    next >
Encoding:
Internet Message Format  |  1992-08-29  |  3.5 KB

  1. Path: sparky!uunet!elroy.jpl.nasa.gov!ames!data.nas.nasa.gov!taligent!apple!cambridge.apple.com!bill@cambridge.apple.com
  2. From: bill@cambridge.apple.com (Bill St. Clair)
  3. Newsgroups: comp.lang.lisp.mcl
  4. Subject: Re: FF-example.c
  5. Message-ID: <9208281527.AA08770@cambridge.apple.com>
  6. Date: 28 Aug 92 16:33:21 GMT
  7. Sender: info-mcl-request@cambridge.apple.com
  8. Lines: 90
  9. Approved: comp.lang.lisp.mcl@Cambridge.Apple.C0M
  10. Full-Name: Bill St. Clair
  11. Original-To: ST7990@SIUCVMB.SIU.EDU
  12. Original-Cc: info-mcl
  13.  
  14. >This question concerns the C code in MCL 2.0:examples:FF
  15. >examples:ff-example.c. I'd like to know what the following define
  16. >statements are trying to do:
  17. >define CDR(x) (* ((long *) (x)))
  18. >
  19. >define CAR(x) (* (((Ptr *) (x)) -1))
  20. >
  21. >define MACPTR_PTR(x) (* (Ptr *) (((long) (x)) +7)))
  22. >
  23. >The definitions are the refered by
  24. >CDR(* x), CAR(* x) and (MACPTR_PTR(* x)  where x is
  25. >type defined as             long *x;
  26. >
  27. >The exact code is as follows:
  28. >growptr(x)
  29. >long *x;
  30. >{
  31. >Ptr newp;
  32. >if (MACPTR_PTR(CAR(*x))) DisposPtr(MACPTR_PTR(CAR(*x)));
  33. >newp = NewPtr((CDR(*x))>>FIXNUM_SHIFT);
  34. >MACPTR_PTR(CAR(*x))=newp;
  35. >}
  36. >
  37. >The lisp FFI defines the above function as
  38. >
  39. >(deffcfun (grow-ptr "growptr") ((cons :lisp-ref) :novalue))
  40. >
  41. >The lisp call is as follows:
  42. >(grow-ptr (cons (#_NewPtr 5) 10))
  43. >_NewPtr 5) 10))
  44. >
  45. >I understand the overall function of the code; my proble lies in the
  46. >particular define stamements.
  47.  
  48. In order to understand this code, you need to understand how MCL
  49. represents conses and macptrs. You can get a start on this by reading
  50. the "Lisp Object Representation" section of the file "ccl:library;lap.doc"
  51. and looking at the constants in "ccl:library;lispequ.lisp".
  52.  
  53. A CONS is a pointer to the second of two longwords. The first longword
  54. is the CAR of the cons. The second longword (the one at which the CONS
  55. points) is the CDR.
  56.  
  57. It seems to me that CDR would be more consistently (with the
  58. CAR & MACPTR-PTR definitions) stated as:
  59.  
  60. #define CDR(x) (* ((Ptr *) (x)))
  61.  
  62. This would have necessitated casting the result to long in its
  63. use in grow_ptr.
  64.  
  65. The definitions do the standard "I don't know what type the argument
  66. I'm getting is so I'll cast it to where it needs to be, nor do I know
  67. whether I need to put parens around it so I will just to be careful"
  68. that is always necessary when writing C macros.
  69.  
  70. A MACPTR is a lisp uvector. A uvector has 4 bytes of GC overhead,
  71. 1 byte of subtype, 3 bytes of length, then length bytes of data.
  72. A MACPTR is tagged as 1 in the low three bits, meaning that it
  73. points one byte into the 8 byte header. Hence MACPTR_PTR is accessing the
  74. first data word in the MACPTR, 1+7 bytes from the start of the header.
  75. This is where the memory address that the MACPTR boxes is stored.
  76.  
  77. A lisp fixnum (passed in the CDR of the argument) is tagged as 0 in the
  78. low three bits. Hence you need to right shift it 3 (FIXNUM_SHIFT) bits
  79. to get a C long.
  80.  
  81. grow_ptr could have been written without using the macros as follows
  82. (though I may have made some mistakes due to my infrequent use of C):
  83.  
  84. growptr (consptr)
  85.   Ptr *consptr, macptr, macptr_ptr;
  86.   long car, cdr;  
  87. {
  88.   Ptr newp;
  89.   car = (long) *(*consptr - 1);
  90.   cdr = (long) **consptr;
  91.   macptr = (Ptr) (car + 7)
  92.   macptr_ptr = (Ptr) (* macptr)
  93.   if (macptr_ptr) DisposPtr(macptr_ptr);
  94.   newp = NewPtr(cdr >> FIXNUM_SHIFT);
  95.   *macptr = newp;
  96. }
  97.  
  98. The reason for doing this with macros is that if the representation
  99. changes in the future (and Gary has already swapped CAR & CDR and
  100. eliminated 4 of the 8 bytes of overhead for a uvector), you can simply
  101. change the macros and recompile.
  102.  
  103. Clear as mud?
  104.