[Openmcl-devel] Weird code

Gail Zacharias gz at clozure.com
Fri Sep 10 13:25:32 PDT 2010


On Fri, Sep 10, 2010 at 2:27 PM, Ron Garret <ron at flownet.com> wrote:
> 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))))
> T
> ? 'moo
> 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:|
> FOO
> ?
>
>
> 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)
>                         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)
>      ,p)))
>
> 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?

It's so that the side-effects happen at runtime rather than compile
time.  But it's a bug that it's just using whatever readtable happens
to be in force at the time.

>
> rg
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>



More information about the Openmcl-devel mailing list