From: Harald Kucharek
Subject: Calling C function from LCL
Date: 
Message-ID: <Bt8G1E.229@iai.kfk.de>
I have the following little C program:

#include <stdio.h>
int 
ca(my_array)
	int             my_array[2][2];

{
	int             i, j;
	int             result = 0;
	for (i = 0; i < 2; ++i) {
		for (j = 0; j < 2; ++j) {
			printf("%d\n", my_array[i][j]);
			result += my_array[i][j];
		}
	} return (result);
}

which I want to call from LISP (I am using Lucid Common Lisp 4.0.1 on a SPARCstation330)
I define:

(def-foreign-function (run-ca (:return-type :signed-32bit)
			(:name "_ca")
			(:language :c))
	(my_array (:array :signed-32bit (4))))

(load-foreign-files "/home/harry/C/ca.o")

which gives the output:
;;; Loading foreign object file "C/ca.o"
;;; Reading library file "/lib/libc.a"
;;; Reading library file "/lib/libm.a"
;;; Warning: The following foreign symbols are undefined: (__DYNAMIC)
NIL


(setq a (make-array '(2 2) :element-type 'integer))

(loop for i from 0 to 1 do
	(loop for j from 0 to 1 do
		(setf (aref a i j) (+ i j))))

(run-ca a)

which outputs:

0
4
4
8
16

Questions:

1) What is this missing symbol __DYNAMIC
2) The contents of the array are all multiplied by 4. Has this something
   to do with the type of the lisp object? I always thought, it is coded in the high order
   bits of the data.
3) What is wrong in my declaration of the foreign function, that make all these things happen?

Thanks for any suggestions.

Harald

    Harald Kucharek ($B>.?M(J), Nuclear Research Center Karlsruhe, IDT
		7514 Eggenstein-Leopoldshafen, Germany
         Internet: ·····@issun1.kfk.de Phone: +49 7247 825706 

From: Doug Morgan
Subject: Re: Calling C function from LCL
Date: 
Message-ID: <DOUG.92Aug19092520@saturn.ads.com>
In article <··········@iai.kfk.de> ·····@issun1.kfk.de (Harald Kucharek) writes:
   I have the following little C program:
   ...
   ca(my_array)
	   int             my_array[2][2];
   ..
   which I want to call from LISP (I am using Lucid Common Lisp 4.0.1 on a SPARCstation330)
   I define:

   (def-foreign-function (run-ca (:return-type :signed-32bit)
	...(my_array (:array :signed-32bit (4))))
   ...
   (setq a (make-array '(2 2) :element-type 'integer))
   ...
   Questions:

   1) What is this missing symbol __DYNAMIC
   2) The contents of the array are all multiplied by 4. Has this something
      to do with the type of the lisp object? I always thought, it is coded in the high order
      bits of the data.
   3) What is wrong in my declaration of the foreign function, that make all these things happen?

   Harald

The problem should be in your make-array.  The type 'integer is very
general and results in all elements being tagged.  Instead, use
'(signed-byte 32).  Also, Lucid seems to use the low order two bits
for type tags.  I don't know what __DYNAMIC is.

Also, I don't think 'fixnum even gives you what you want.  Each fixnum
in the array will have tag bits.  (This is reaching back a ways for me
and could easily be wrong.)

doug
--------------------------------------------------------------------
Doug Morgan, ····@ads.com, (415) 960-7300
Advanced Decision Systems (a division of Booz-Allen & Hamilton Inc.)
1500 Plymouth St., Mountain View, CA 94043-1230
--------------------------------------------------------------------
From: Barry Margolin
Subject: Re: Calling C function from LCL
Date: 
Message-ID: <16u3jhINN9m1@early-bird.think.com>
In article <··········@iai.kfk.de> ·····@issun1.kfk.de writes:
>1) What is this missing symbol __DYNAMIC

You can ignore that.  It's related to Sun's dynamic linking implementation,
but Lucid's FFI only loads static libraries.

>2) The contents of the array are all multiplied by 4. Has this something
>   to do with the type of the lisp object? I always thought, it is coded in the high order
>   bits of the data.

C ints correspond to Lisp fixnums, but you passed an untyped array.  Lucid
(and many other Lisp implementations) puts some tag bits information in the
low-order two bits of objects; they're ordinarily unused, since all the
types that are accessed through pointers require full-word alignment.
Fixnums have the type tags 00 (positive fixnum) and 11 (negative fixnum);
this has the property that the tagged value is the result of an arithmetic
shift of the untagged value, which allows them to be added without
untagging, and multiplied by shifting the result rather than the arguments.

The arrays you pass to the foreign function must be created with

(make-array 4 :element-type 'fixnum)

>3) What is wrong in my declaration of the foreign function, that make all these things happen?

Nothing.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: ············@cs.cmu.edu
Subject: Re: Calling C function from LCL
Date: 
Message-ID: <4eYpN3W00jeiEkhC8z@cs.cmu.edu>
······@think.com (Barry Margolin) writes:
> Fixnums have the type tags 00 (positive fixnum) and 11 (negative fixnum);
> this has the property that the tagged value is the result of an arithmetic
> shift of the untagged value, which allows them to be added without
> untagging, and multiplied by shifting the result rather than the arguments.

Are those tags on the low end or high end of the word?  If they are on
the low end, then how does adding two negative fixnums result in
anything useful (xxx11 + xxx11 = xxx10)?  If they are on the high end,
where does the shift come in?

We [CMU Common Lisp, that is] use the low three bits as a type-tag,
but have 000 for even fixnums and 100 for odd fixnums.  In other
words, if the low two bits are 00 then it is a fixnum with the value
in the upper 30 bits.  The implicit multiplication by 4 is handy when
accessing arrays of word (4 byte) sized objects: it's pre-scaled.

-William Lott
CMU Common Lisp Group
From: Simon Leinen
Subject: Re: Calling C function from LCL
Date: 
Message-ID: <SIMON.92Aug20120853@liasg1.epfl.ch>
In article <··················@cs.cmu.edu> ············@cs.cmu.edu writes:

   We [CMU Common Lisp, that is] use the low three bits as a type-tag,
   but have 000 for even fixnums and 100 for odd fixnums.

That's exactly the same representation as in Lucid, at least on the
SPARC.

   The implicit multiplication by 4 is handy when accessing arrays of
   word (4 byte) sized objects: it's pre-scaled.

Yes; this can make vector-intensive code faster than corresponding C
code in many cases... (even if the code has been naively translated
from C to Common Lisp.  I think the "Triangle" Gabriel benchmark works
that way :-)
-- 
Simon.