[Openmcl-devel] Weird code

Ron Garret ron at flownet.com
Fri Sep 10 11:27:41 PDT 2010

I happened upon the following odd behavior while mucking with some reader macros:

? (set-macro-character #\m
  (lambda (stream c)
    (unread-char c stream)
    (let ((*readtable* (copy-readtable  nil)))
      (read stream))))
? 'moo
? (defun foo (a b) (#/sizeWithAttributes: a b))
> Error: Foreign function not found: X86-DARWIN64::MEMSET
> While executing: CCL::LOAD-EXTERNAL-FUNCTION, in process Listener(6).
> Type cmd-. to abort, cmd-\ for a list of available restarts.
> Type :? for other options.
1 > 
? (defun foo (a b) (#/sizeWithAttributes: a b))
;Compiler warnings :
;   In FOO: In the call to NEXTSTEP-FUNCTIONS:|sizeWithAttributes:| with arguments (A B),
;     2 arguments were provided, but at most 0 are accepted
;     by the current global definition of NEXTSTEP-FUNCTIONS:|sizeWithAttributes:|

I tracked the problem down to the following code in lib/macros.lisp:

(defun make-record-form (record-name allocator &rest initforms)
  (let* ((ftype (%foreign-type-or-record record-name))
         (ordinal (foreign-type-ordinal ftype))
         (ordinal-form (if (< ordinal max-canonical-foreign-type-ordinal)
                         `(foreign-type-ordinal (load-time-value (%foreign-type-or-record ',record-name)))))
         (bits (ensure-foreign-type-bits ftype))
	 (bytes (if bits
		  (ceiling bits 8)
		  (signal-program-error "Unknown size for foreign type ~S."
					(unparse-foreign-type ftype))))
	 (p (gensym))
	 (memset (read-from-string "#_memset")))    
    `(let* ((,p (,allocator ,bytes)))
      ,@(when (eq *host-backend* *target-backend*)
              `((%set-macptr-type ,p ,ordinal-form)))
      (,memset ,p 0 ,bytes)
      ,@(%foreign-record-field-forms p ftype record-name initforms)

and in particular, to this line:

	 (memset (read-from-string "#_memset")))

Is there a reason why read-from-string being invoked here instead of just doing, say, (let ((memset '#_memset)) ... ?  Or dispensing with the binding entirely and just doing (,#_memset ...) in the body of the LET?


More information about the Openmcl-devel mailing list