[Ecls-list] Bug in argument checking based on function proclamation

Matthew Mondor mm_lists at pulsar-zone.net
Tue Jun 29 02:13:05 UTC 2010


On Mon, 28 Jun 2010 19:12:04 -0500
Gabriel Dos Reis <gdr at integrable-solutions.net> wrote:

> 1. The argument-type in the function proclamation is simple enough
>     that ECL should not be confused.
> 
> 2. ECL pretends that there are too few arguments for proclaimed
>     BEGIN-DOLLAR-P.  Yet, the function was proclaimed to be
>     of arity 1, and there is exactly one argument supplied in the call.
> 
> What are the notes about propagating FUNCALL and C-INLINE about?

I rebuilt an ECL from ECL HEAD to test these new changes.
While building some code which uses function proclamations, there also
was a new problem:


;;; Compiling /home/mmondor/work/mmsoftware/cl/test/ecl-unix.lisp.
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=3
;;;
;;; Note:
;;;   in file ecl-unix.lisp, position 51123
;;;   at (DEFINE-C-STRUCTURE-ACCESSORS FLOCK)
;;;   Unknown type (FLOCK). Assuming it is T.

In function CEILING, the value of the first argument is
  FLOCK
which is not of the expected type REAL
Available restarts:

1. (ABORT) ABORT
2. (ABORT) Abort compilation.
3. (ABORT) Return to SLIME's top level.
4. (CLOSE-CONNECTION) Close SLIME connection
5. (RESTART-TOPLEVEL) Go back to Top-Level REPL.

Broken at CEILING. In: #<process SI:TOP-LEVEL 0810afc0>.
UNIX>> 

And somehow slime couldn't enter the debugger at that point, and the
inferior-lisp buffer was unresponsive, so slime-restart-inferior-lisp
had to be used.  The following code was the one failing to build, and
commenting out the declarations indeed resumes a normal build (which
declarations are commented in the following code as well for
convenience):

(defmacro define-c-structure-accessors (struct)
  "Generates a set of GETF/SETF accessor functions for a previously defined
C structure using DEFINE-C-STRUCTURE.  Note that to use these, it is expected
that a CL DEFSTRUCT form is also created by the user code, holding at least
one field: POINTER, which should hold the foreign :POINTER-VOID data pointer.
We do not create this structure automatically because user code might want
to also provide additional custom fields (notably for pointers to other
objects)."
  (check-type struct symbol)
  (destructuring-bind
	(struct-name c-struct-name &rest fields)
      (gethash struct *c-structures*)
    `(progn
       ,@(mapcar
	  #'(lambda (field)
	      (destructuring-bind
		    (field-name ffi-type c-field-name) field
		(let ((accessor (intern (format nil "~A-~A"
						(symbol-name struct-name)
						(symbol-name field-name))))
		      (pointer (intern (format nil "~A-POINTER"
					       (symbol-name struct-name)))))
		  `(progn
;		     (declaim
;		      (optimize (speed 3) (safety 0) (debug 0))
;		      (ftype (function (,struct-name) integer) ,accessor)
;		      (inline ,accessor))
		     (defun ,accessor (object)
		       (c-inline2 ((,pointer object))
				  (:pointer-void)
				  ,ffi-type
				  ,(format nil "(((~A *)#0)->~A)"
					   c-struct-name c-field-name)
				  :one-liner t :side-effects nil))
;		     (declaim
;		      (optimize (speed 3) (safety 0) (debug 0))
;		      (ftype (function (integer ,struct-name) integer)
;			     (setf ,accessor))
;		      (inline (setf ,accessor)))
		     (defun (setf ,accessor) (value object)
		       (c-inline2 (value (,pointer object))
				  (,ffi-type :pointer-void)
				  ,ffi-type
				  ,(format nil "(((~A *)#1)->~A = #0)"
					   c-struct-name c-field-name)
				  :one-liner t :side-effects t))))))
	  fields))))

Another interesting point is that in no way the above code expands into
a CEILING funtion call, even if that was what the error was about.

Thanks,
-- 
Matt




More information about the ecl-devel mailing list