[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