logo       

:malloc-free allocation -- here: instance methods: msg#00085

lisp.clisp.general

Subject: :malloc-free allocation -- here: instance methods

Aurelio Bignoli wrote:

>this problem could be solved by a program that translates C
>declarations into FFI declarations. Such a program is available for
>some Common Lisp implementations, e.g LispWorks.

I still don't like this approach.
It introduces a dependency between .fas and .h files.
I believe there are several unwritten coding/design rules about CLISP which I
have integrated during the 10 years I've lived with CLISP.
One was portability of user's .fas files. That's why e.g. with-keyboard is a
macro that encloses its body in a closure and calls an internal function. I
don't know whether other developers [still/ever] share this goal.
Having C constant offsets live in a .fas file destroys this portability.
Probably more than 80% of the users don't care about this portability, since
they work on a single system.

I still believe modules is a way to go to interface to foreign stuff. That
implies C code, be it automatically generated or not. This C code should then
contain the offsets and other architecture/platform dependent forms. Let the
.fas file and Lisp code remain free of that.

This rule (design goal) also serves as a design guideline itself, since it
answers what sort of code should go into either C or Lisp.

Another reason I don't like embedding C offsets in Lisp is that this approach
IMHO only suits well to a native code compiler like CMUCL or CormanLisp. There,
the offsets can be absent at the run-time. In CLISP, they could not. Also, tree
shaking of unneeded C structures works with native code. In CLISP it would not
(unless somebody implemented it *and* took care that it's easy to use). And one
of my goals, which profoundly influenced the design of my AFFI, was to *not*
reflect the myriads of C includes and structures of the Amiga in Lisp.
MS-Windows even has more of these.


>Another solution could be a C program which, using the offsetof macro,
>prints the offset of the relevant DB function pointer members. Its

A program close to this already exists: utils/modprep
I bet very few people know about it. It's not even mentioned in impnotes (well,
it has nothing to do with the implementation proper).
It allows to write C code with helpers macros for accessing Lisp objects. I
never used it myself...

Another approach which I had thought of is to extent FFI:C-LINES
(C-LINES :defun 'MEM-WRITE "LISPFUN(mem_write,3,1,norest,nokey,0,NIL)" "
{
// C or .d code of this function;
}")
would generate 3 pieces of code to go into the subr_table and maintain the
subr_count.
A similar extension to C:LINES would be needed for objects.

Maybe that would be most useful for your polymorphic db-get/put functions.


>returned function prototype could be a problem: every DB fuction has
>its own parameter list. Probably the C factory function should return
I don't understand this.
>a c-pointer which has to be casted to the appropriate FFI:C-FUNCTION
>type before APPLYing it.

I've been thinking about extending C-POINTER to allow (C-POINTER c-type) to
return a foreign-variable object of the given c-type. In other words, it
returns a typed reference to a foreign object.

It might be useful for BDB and other situations (e.g. errno). But it also has
its own set of problems (I'll talk about them another time).

(def-c-struct DB ; Beware: I don't know what the db struct looks like!
(get (c-function (:arguments (db c-pointer) (txn c-pointer)
(key c-pointer) (value c-pointer) (flags uint32))
(:return-type bool) (:language :stdc)))
(put (c-function (:arguments (db c-pointer) (txn c-pointer)
(key c-pointer) (value c-pointer) (flags uint32))
(:return-type bool) (:language :stdc)))
(close (c-function (:arguments (db c-pointer))
(:return-type nil) (:language :stdc))))
(def-call-out db-create
(:arguments ...)
(:return-type (c-pointer DB)))

(setq *db* (db-create ...))
(funcall (foreign-value (ffi::%slot *db* 'get)) ; TODO factory
*db* *txn* *key* ...)

(def-call-out __errno_location (:arguments) (:return-type (c-pointer int)))
(define-symbol-macro errno (foreign-value (__errno_location)))
; also works with setf errno!

I cannot recommend this implementation of errno, since every call would
generate a garbage FOREIGN-ADDRESS and -VARIABLE object.

(C-LINES :defun 'get_errno "LISPFUNN(get_errno,0)"
"{ values1=L_to_I((sintL)errno); mv_count=1; }")
would be just as easy to add to linux.lisp, and much more performant.

Regards,
Jorg Hohle.


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise