Dear Camm,

Great! Many thanks for working on the issue of calling shared lib functions
from gcl. I have struggled some time ago with this issue, with moderate
success.
Actually, I tried to call a shared lib function from Aldor/Axiom via gcl.

My trails were based und the gcl-loader package, which looks quite similar
to your way of importing and calling C libs.

How can I use your functions (BTW I am FreeBSD user - unfortunately the
ports tree offers only 2.6.7). Yet I had no luck (and little time) to use a
more current version of gcl.

Actually the main problem of calling external C functions was to pass
variables from and to gcl. As of gsl (gnu scientific library), there are
numerous variations - int, float, double, pointers to any of them, arrays,
multi dimensional array, ...
Can you assist me with defining how to use all of these types properly?

Many thanks

Gernot





Camm Maguire writes:

Greetings, and thanks for including me in this thread.  Unfortunately,
axiom-developer mail is still not getting through my ISP for some
reason.


In my private tree Axiom is nicely working on top of sbcl and clisp.
The remaining known problems are sockets and writeablep function.

Great!  It is always nice to have more options.  But I do have a
general question here.  Work in this direction obviously makes sense
if 1) GCL is currently deficient for axiom use in some regard and 2)
we have difficulties addressing said deficiencies via changes to GCL.
If both of these are true, I would greatly appreciate you and/or
others letting me know the details, as it is and has been a goal of
mine to ensure that gcl remains optimal for axiom use.  As in the
past, I pledge that if axiom needs anything from GCL which is
currently unavailable, I will make sure said functionality works in
GCL.  What I would like to avoid is chasing every random package which
no one has any serious intention of deploying in a real shipped
program.

If either 1) or 2) above are not true, may I suggest that significant
work in this regard is a distraction from the real goals of the axiom
project -- to deliver the best symbolic algebra package in the open
source world.  In our company, we manage approx. $70 billion dollars
using open source software and code we've written on top of it.  We
would get nowhere if we spent any time at all making sure our code
works both on gcc and icc, etc.  Rather we pick a platform that
appears flexible, stick to it, and get the results we want out of it
quickly.  We do almost everything using gcc, gdb and emacs, not
because they are the slickest or hottest or even fastest, but because
they have good portable performance, they can be changed at the source
level if necessary, and they will be available forever, making our
payoff period for the learning curve essentially last a whole
lifetime.

I'd really love to help the axiom project by offering a similar setup
for use by the developers.  Even one better -- axiom has its own
personal compiler developer to tailor the compiler to its needs if
necessary.  This only pays off if my work on GCL frees axiom developer
hours for work on the core system.

Also, currently for clisp I need cl-fad library, which I consider
problematic.  Namely, cl-fad does not work with gcl, so for gcl
we need separate code.  We need only few functions from cl-fad,
to work around clisp weirdness (clisp makes strong distinction
between paths to files and paths to directories and refuses
to perform file operations on directories).  So my current plan
is to eliminate use of cl-fad and provide the needed functions
directly.  Related problem is performing operations on

I think this is a wise choice, but needless to say, if you need
cl-fad, I'll make sure it works.

I must say I'm less than enamored with the cl-foo library development
model. Its source level as opposed to binary, and there is no shared
library memory savings.  Beyond which, there really doesn't appear to
be much of anything available which is not provided elsewhere in
faster, smaller, shareable C libraries, though I haven't made any
exhaustive study here.

I love lisp, obviously, and primarily for the magnitude and quality of
AI-type code which has been developed and has recently entered into
the open source world.  But lisp is not going to compete with perl,
python, java, or C, IMHO.  The primary goal should be in fulfilling
the ansi-standard and supporting applications from the past, while
offering non-standard interfaces to newer functionality in external
shared C libraries.  Do we really think cl-fad has a thirty year
lifetime ahead of it?  How will we coordinate with all these cl-
library developers external to the axiom project when they move on to
other things in life?   Will we read all their source and maintain it
ourselves?

Thankfully, the ansi-standard is written down, and with all its warts,
will last > 30 years, IMHO.  If we need items outside the standard, we
should rely on implementations in C shared libraries, as these will
have a longer lifetime and in general will be technically superior.
We should then pick one again non-standard glue between lisp and C,
and stick to it, and call all the shared library routines from within
lisp.  These of course are just my opinions.

It is good you brought this up, as gclcvs has followed clisp-style
directory usage, at least at present.  We can undo this if required.
Pathnames with spaces are also fully supported in gclcvs.  These can
be backported to 2.6.8pre if necessary.

directories -- to gain portability between Unix and Windows
I tried to use Lisp code.  But each Lisp is doing them
differently (and apparently some operations sometimes are missing).
So I got a maze of conditionals over Lisp implementations.
Looking at resulting code I feel that it is better to
call operationg system utilities and have just use
conditionals to choose between Unix and Windows versions
of file utilities.

In C, we call this #ifdef hell.  There is no good reason for it, in my
experience.


Concerning sockets, we need Unix domain sockets and select.  It
seems that clisp provide both, but to get Unix domain sockets
one needs version including rawsock module, which is not included
in default clisp configuration.

sbcl offers sb-bsd-sockets which seem to have basic functions,
but I do not see select.

gcl documentation suggest that Unix domain sockets are unsupported.
Also, I see no traces of select.

gclcvs has a select/fork based parallel processing system:

SYSTEM>(walker::macroexpand-all '(p-let ((x (foo)) (y (bar))) (+ x y)))

(LET* (X Y)
  (LET* ((#:G2306 3)
         (#:G2301 (LIST (LET ((#:G2310 (FORK)))
                          (IF (EQL 0 (CAR #:G2310))
                              (PROGN
                                (WRITE-POINTER-OBJECT (FOO) #:G2310)
                                (BYE))
                              #:G2310))
                        (LET ((#:G2311 (FORK)))
                          (IF (EQL 0 (CAR #:G2311))
                              (PROGN
                                (WRITE-POINTER-OBJECT (BAR) #:G2311)
                                (BYE))
                              #:G2311)))))
    (DECLARE ((INTEGER 0 3) #:G2306))
    (UNWIND-PROTECT
      (DO () ((= #:G2306 0))
        (LET ((#:G2309 (SELECT-READ #:G2301 -1)))
          (DECLARE ((INTEGER 0 3) #:G2309))
          (DO ((#:G2299 0 (1+ #:G2299)) (#:G2307 1 (ASH #:G2307 1))
               (#:G2308 #:G2301 (CDR #:G2308)))
              ((= #:G2299 2) (SETQ #:G2306 (LOGANDC2 #:G2306 #:G2309)))
            (DECLARE ((INTEGER 0 2) #:G2299) ((INTEGER 1 4) #:G2307))
            (IF (/= 0 (LOGAND #:G2307 #:G2309))
                (PROGN
                  (LET ((#:G2300 (READ-POINTER-OBJECT (CAR #:G2308))))
                    (LET ((#:G2313 #:G2299))
                      (IF (EQL #:G2313 '0) (PROGN (SETQ X #:G2300))
                          (IF (EQL #:G2313 '1) (PROGN (SETQ Y #:G2300))
                              NIL)))))))))
      (DO* ((#:G2314 #:G2301 (CDR #:G2314)))
           ((ENDP #:G2314) (CDR #:G2301))
        (LET ((#:G2301 (CAR #:G2314))) (KILL #:G2301 0)))))
  (+ X Y))


This can be adapted to whatever other interface one may desire.

Do you mean dgram (UDP) sockets?  If you specify the interface, we'll
put them in.


There is "portable" cl-sockets library but the manual says it supports
Allegro CL, sbcl and cmucl.  The manual does not say anything about
Unix domain sockets or select.  The manual says that cl-sockets requires
UFFI, so presumably cl-sockets works on top of "portable" C library.

In short my finding is that portable Lisp sockets are a myth: all
implementations provide different interface and frequently miss
some essential services.  People who want portablity between Lisp
implementations interface to C.

Agreed!

I've been working on a better interface to external shared C
libraries for GCL.  The issue, as you may recall, is that GCL-compiled
code referring to external shared function addresses are statically
relocated to the value of said address at the time the .o file is
loaded. If one then saves the image and re-executes, the function is
likely in a different place.

I've figured out a persistent solution using dlopen.  Still working on
the precise interface, but you can see the idea here.  Comments are
marked with ***:

=============================================================================
GCL (GNU Common Lisp)  2.7.0 CLtL1    May 22 2007 16:39:58
Source License: LGPL(gcl,gmp,pargcl), GPL(unexec,bfd,xgcl)
Binary License:  GPL due to GPL'ed components: (XGCL READLINE BFD UNEXEC)
Modifications of this banner must retain notice of a compatible license
Dedicated to the memory of W. Schelter

Use (help) to get some basic information on how to use GCL.

Temporary directory for compiler files set to /tmp/

(in-package 'si)

#<"SYSTEM" package>

SYSTEM>(show-lib-syms)

NIL

SYSTEM>(mdlsym "cosf" "libm.so")

|libm|:|cosf| ;;*** package autmatically created, lib automatically dlopened

SYSTEM>(mdlsym "dgemv_" "libblas.so")

|libblas|:|dgemv_|

SYSTEM>(show-lib-syms)

(LIB:|libblas| 6730696 #<"libblas" package>) ;;*** value of package
                                                   symbol is dlopen handle
(|libblas|:|dgemv_| 1080730284 NIL)          ;;*** value of C symbol
                                                   is current address,
                                                   reset on system startup
(LIB:|libm| 1074174504 #<"libm" package>)
(|libm|:|cosf| 1094172320 NIL)
NIL

SYSTEM>(dladdr |libblas|:|dgemv_| ;;*** exact path resolution
)

#P"/usr/lib/atlas/sse2/libblas.so"

SYSTEM>(system "cat /tmp/dl2.l")
(in-package "libm")

(eval-when
 (compile eval)
 (defmacro defdl (sym)
   (let* ((sym  (si::mdlsym (string-downcase sym) "libm.so"))
          (fsym (si::mdlsym (concatenate 'string (string sym) "f") "libm.so")))
   `(progn
      (defun ,sym  (x) (si::dl-double-to-double ',sym x))
      (defun ,fsym (x) (si::dl-float-to-float   ',fsym x))))))

(defdl exp)
(defdl log)
(defdl sin)
(defdl cos)
(defdl tan)
(defdl asin)
(defdl acos)
(defdl atan)
(defdl sinh)
(defdl cosh)
(defdl tanh)
(defdl asinh)
(defdl acosh)
(defdl atanh)

SYSTEM>(load "/tmp/dl2.l")

;; Loading /tmp/dl2.l
;; Finished loading /tmp/dl2.l
T

SYSTEM>(show-lib-syms)

(LIB:|libblas| 6730696 #<"libblas" package>)
(|libblas|:|dgemv_| 1080730284 NIL)
(LIB:|libm| 1074174504 #<"libm" package>)
(|libm|:|atan| 1094141472
    #<interpreted-function (LAMBDA-BLOCK |libm|:|atan| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|atan| ;;***
                                                                   standard 
call to address denoted
                                                                   by symbol 
value, one double arg, returning one double
                                 |libm|::X))>)
(|libm|:|acosh| 1094146080
    #<interpreted-function (LAMBDA-BLOCK |libm|:|acosh| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|acosh|
                                 |libm|::X))>)
(|libm|:|expf| 1094176432
    #<interpreted-function (LAMBDA-BLOCK |libm|:|expf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|expf|
                                 |libm|::X))>)
(|libm|:|atanhf| 1094176064
    #<interpreted-function (LAMBDA-BLOCK |libm|:|atanhf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|atanhf|
                                 |libm|::X))>)
(|libm|:|acosf| 1094175504
    #<interpreted-function (LAMBDA-BLOCK |libm|:|acosf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|acosf|
                                 |libm|::X))>)
(|libm|:|exp| 1094146864
    #<interpreted-function (LAMBDA-BLOCK |libm|:|exp| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|exp|
                                 |libm|::X))>)
(|libm|:|atanh| 1094146512
    #<interpreted-function (LAMBDA-BLOCK |libm|:|atanh| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|atanh|
                                 |libm|::X))>)
(|libm|:|cosh| 1094146672
    #<interpreted-function (LAMBDA-BLOCK |libm|:|cosh| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|cosh|
                                 |libm|::X))>)
(|libm|:|cosf| 1094172320
    #<interpreted-function (LAMBDA-BLOCK |libm|:|cosf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|cosf|
                                 |libm|::X))>)
(|libm|:|atanf| 1094172032
    #<interpreted-function (LAMBDA-BLOCK |libm|:|atanf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|atanf|
                                 |libm|::X))>)
(|libm|:|cos| 1094141792
    #<interpreted-function (LAMBDA-BLOCK |libm|:|cos| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|cos|
                                 |libm|::X))>)
(|libm|:|tanh| 1094145584
    #<interpreted-function (LAMBDA-BLOCK |libm|:|tanh| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|tanh|
                                 |libm|::X))>)
(|libm|:|tanf| 1094175168
    #<interpreted-function (LAMBDA-BLOCK |libm|:|tanf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|tanf|
                                 |libm|::X))>)
(|libm|:|tan| 1094145536
    #<interpreted-function (LAMBDA-BLOCK |libm|:|tan| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|tan|
                                 |libm|::X))>)
(|libm|:|sinh| 1094150832
    #<interpreted-function (LAMBDA-BLOCK |libm|:|sinh| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|sinh|
                                 |libm|::X))>)
(|libm|:|asin| 1094146208
    #<interpreted-function (LAMBDA-BLOCK |libm|:|asin| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|asin|
                                 |libm|::X))>)
(|libm|:|sinf| 1094175120
    #<interpreted-function (LAMBDA-BLOCK |libm|:|sinf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|sinf|
                                 |libm|::X))>)
(|libm|:|sin| 1094145488
    #<interpreted-function (LAMBDA-BLOCK |libm|:|sin| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|sin|
                                 |libm|::X))>)
(|libm|:|coshf| 1094176224
    #<interpreted-function (LAMBDA-BLOCK |libm|:|coshf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|coshf|
                                 |libm|::X))>)
(|libm|:|tanhf| 1094175216
    #<interpreted-function (LAMBDA-BLOCK |libm|:|tanhf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|tanhf|
                                 |libm|::X))>)
(|libm|:|acoshf| 1094175632
    #<interpreted-function (LAMBDA-BLOCK |libm|:|acoshf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|acoshf|
                                 |libm|::X))>)
(|libm|:|asinh| 1094141232
    #<interpreted-function (LAMBDA-BLOCK |libm|:|asinh| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|asinh|
                                 |libm|::X))>)
(|libm|:|asinhf| 1094171792
    #<interpreted-function (LAMBDA-BLOCK |libm|:|asinhf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|asinhf|
                                 |libm|::X))>)
(|libm|:|sinhf| 1094180368
    #<interpreted-function (LAMBDA-BLOCK |libm|:|sinhf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|sinhf|
                                 |libm|::X))>)
(|libm|:|asinf| 1094175760
    #<interpreted-function (LAMBDA-BLOCK |libm|:|asinf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|asinf|
                                 |libm|::X))>)
(|libm|:|logf| 1094179104
    #<interpreted-function (LAMBDA-BLOCK |libm|:|logf| (|libm|::X)
                             (DL-FLOAT-TO-FLOAT '|libm|:|logf|
                                 |libm|::X))>)
(|libm|:|log| 1094149536
    #<interpreted-function (LAMBDA-BLOCK |libm|:|log| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|log|
                                 |libm|::X))>)
(|libm|:|acos| 1094145952
    #<interpreted-function (LAMBDA-BLOCK |libm|:|acos| (|libm|::X)
                             (DL-DOUBLE-TO-DOUBLE '|libm|:|acos|
                                 |libm|::X))>)
NIL

SYSTEM>(compile-file "/tmp/dl2.l")

;; Compiling /tmp/dl2.l.
;; End of Pass 1.
;; End of Pass 2.
;; OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3, 
(Debug quality ignored)
;; Finished compiling /tmp/dl2.o.
#P"/tmp/dl2.o"
NIL
NIL

SYSTEM>(load *)

;; Loading /tmp/dl2.o
 ;; start address -T 0x66f480 ;; Finished loading /tmp/dl2.o
1460

SYSTEM>(show-lib-syms)

(LIB:|libblas| 6730696 #<"libblas" package>)
(|libblas|:|dgemv_| 1080730284 NIL)
(LIB:|libm| 1074174504 #<"libm" package>)
(|libm|:|atan| 1094141472 #<compiled-function |libm|:|atan|>)
(|libm|:|acosh| 1094146080 #<compiled-function |libm|:|acosh|>)
(|libm|:|expf| 1094176432 #<compiled-function |libm|:|expf|>)
(|libm|:|atanhf| 1094176064 #<compiled-function |libm|:|atanhf|>)
(|libm|:|acosf| 1094175504 #<compiled-function |libm|:|acosf|>)
(|libm|:|exp| 1094146864 #<compiled-function |libm|:|exp|>)
(|libm|:|atanh| 1094146512 #<compiled-function |libm|:|atanh|>)
(|libm|:|cosh| 1094146672 #<compiled-function |libm|:|cosh|>)
(|libm|:|cosf| 1094172320 #<compiled-function |libm|:|cosf|>)
(|libm|:|atanf| 1094172032 #<compiled-function |libm|:|atanf|>)
(|libm|:|cos| 1094141792 #<compiled-function |libm|:|cos|>)
(|libm|:|tanh| 1094145584 #<compiled-function |libm|:|tanh|>)
(|libm|:|tanf| 1094175168 #<compiled-function |libm|:|tanf|>)
(|libm|:|tan| 1094145536 #<compiled-function |libm|:|tan|>)
(|libm|:|sinh| 1094150832 #<compiled-function |libm|:|sinh|>)
(|libm|:|asin| 1094146208 #<compiled-function |libm|:|asin|>)
(|libm|:|sinf| 1094175120 #<compiled-function |libm|:|sinf|>)
(|libm|:|sin| 1094145488 #<compiled-function |libm|:|sin|>)
(|libm|:|coshf| 1094176224 #<compiled-function |libm|:|coshf|>)
(|libm|:|tanhf| 1094175216 #<compiled-function |libm|:|tanhf|>)
(|libm|:|acoshf| 1094175632 #<compiled-function |libm|:|acoshf|>)
(|libm|:|asinh| 1094141232 #<compiled-function |libm|:|asinh|>)
(|libm|:|asinhf| 1094171792 #<compiled-function |libm|:|asinhf|>)
(|libm|:|sinhf| 1094180368 #<compiled-function |libm|:|sinhf|>)
(|libm|:|asinf| 1094175760 #<compiled-function |libm|:|asinf|>)
(|libm|:|logf| 1094179104 #<compiled-function |libm|:|logf|>)
(|libm|:|log| 1094149536 #<compiled-function |libm|:|log|>)
(|libm|:|acos| 1094145952 #<compiled-function |libm|:|acos|>)
NIL

SYSTEM>(disassemble '|libm|:|log|)

;; Compiling /tmp/gazonk_27499_0.lsp.
;; End of Pass 1.
;; End of Pass 2.
;; OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3, 
(Debug quality ignored)
;; Finished compiling /tmp/gazonk_27499_0.o.

#include "gazonk_27499_0.h"
void init_code(){do_init((void *)VV);}
/*      local entry for function CMP-ANON       */

static object LI1(V2)

object V2;
{        VMB1 VMS1 VMV1
        goto TTL;
TTL:;    ;;**** fast link C call to generic interface
        {object V3 = (/* DL-DOUBLE-TO-DOUBLE 
*/(*LnkLI1)(((object)VV[0]),(V2)));VMR1
        (V3);}
        return Cnil;
}
static object  LnkTLI1(object first,...){object V1;va_list 
ap;va_start(ap,first);V1=(object )call_proc_new(((object)VV[1]),0,0,(void **)(void 
*)&LnkLI1,2,first,ap);va_end(ap);return V1;} /* DL-DOUBLE-TO-DOUBLE */
#(#(log DL-DOUBLE-TO-DOUBLE
    (%INIT
     . #((LET ((*DISABLE-RECOMPILE* T))
           (MFSFUN 'CMP-ANON 0 1 0)
           (ADD-HASH 'CMP-ANON '((T) T)
               '((DL-DOUBLE-TO-DOUBLE (T T) T))
SYSTEMCOMPILERCMP-ANON /!.log DL-DOUBLE-TO-DOUBL,QUOTE1-
               '/tmp/gazonk_27499_0.lsp))
         (DO-RECOMPILE)))))
static object LI1();
#define VMB1
#define VMS1
#define VMV1
#define VMR1(VMT1) return(VMT1);
#define VM1 0
static void * VVi[3]={
#define Cdata VV[2]
(void *)(LI1)
};
#define VV (VVi)
static object  LnkTLI1(object,...);
static object  (*LnkLI1)() = (object (*)()) LnkTLI1;

/tmp/gazonk_27499_0.o:     file format elf32-i386

Disassembly of section .text:

00000000 <init_code>:
object
macro_def_int(object);

#include "gazonk_27499_0.h"
void init_code(){do_init((void *)VV);}
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   b8 00 00 00 00          mov    $0x0,%eax
   b:   89 04 24                mov    %eax,(%esp)
   e:   e8 fc ff ff ff          call   f <init_code+0xf>
  13:   c9                      leave
  14:   c3                      ret

00000015 <LI1>:
/*      local entry for function CMP-ANON       */

static object LI1(V2)

object V2;
{        VMB1 VMS1 VMV1
  15:   55                      push   %ebp
  16:   89 e5                   mov    %esp,%ebp
  18:   83 ec 18                sub    $0x18,%esp
        goto TTL;
TTL:;
        {object V3 = (/* DL-DOUBLE-TO-DOUBLE 
*/(*LnkLI1)(((object)VV[0]),(V2)));VMR1
  1b:   8b 0d 0c 00 00 00       mov    0xc,%ecx
  21:   a1 00 00 00 00          mov    0x0,%eax
  26:   89 c2                   mov    %eax,%edx
  28:   8b 45 08                mov    0x8(%ebp),%eax
  2b:   89 44 24 04             mov    %eax,0x4(%esp)
  2f:   89 14 24                mov    %edx,(%esp)
  32:   ff d1                   call   *%ecx
  34:   89 45 fc                mov    %eax,0xfffffffc(%ebp)
  37:   8b 45 fc                mov    0xfffffffc(%ebp),%eax
        (V3);}
        return Cnil;
}
  3a:   c9                      leave
  3b:   c3                      ret

0000003c <LnkTLI1>:
static object  LnkTLI1(object first,...){object V1;va_list 
ap;va_start(ap,first);V1=(object )call_proc_new(((object)VV[1]),0,0,(void **)(void 
*)&LnkLI1,2,first,ap);va_end(ap);return V1;} /* DL-DOUBLE-TO-DOUBLE */
  3c:   55                      push   %ebp
  3d:   89 e5                   mov    %esp,%ebp
  3f:   53                      push   %ebx
  40:   83 ec 34                sub    $0x34,%esp
  43:   8d 45 0c                lea    0xc(%ebp),%eax
  46:   89 45 f4                mov    %eax,0xfffffff4(%ebp)
  49:   8b 55 f4                mov    0xfffffff4(%ebp),%edx
  4c:   b9 0c 00 00 00          mov    $0xc,%ecx
  51:   a1 04 00 00 00          mov    0x4,%eax
  56:   89 c3                   mov    %eax,%ebx
  58:   89 54 24 18             mov    %edx,0x18(%esp)
  5c:   8b 45 08                mov    0x8(%ebp),%eax
  5f:   89 44 24 14             mov    %eax,0x14(%esp)
  63:   c7 44 24 10 02 00 00    movl   $0x2,0x10(%esp)
  6a:   00
  6b:   89 4c 24 0c             mov    %ecx,0xc(%esp)
  6f:   c7 44 24 08 00 00 00    movl   $0x0,0x8(%esp)
  76:   00
  77:   c7 44 24 04 00 00 00    movl   $0x0,0x4(%esp)
  7e:   00
  7f:   89 1c 24                mov    %ebx,(%esp)
  82:   e8 fc ff ff ff          call   83 <LnkTLI1+0x47>
  87:   89 45 f8                mov    %eax,0xfffffff8(%ebp)
  8a:   8b 45 f8                mov    0xfffffff8(%ebp),%eax
  8d:   83 c4 34                add    $0x34,%esp
  90:   5b                      pop    %ebx
  91:   5d                      pop    %ebp
  92:   c3                      ret
NIL

SYSTEM>(defun foo (x) (declare (long-float x)) (|libm|:|log| x))

FOO

SYSTEM>(disassemble 'foo)

;; Compiling /tmp/gazonk_27499_0.lsp.
;; End of Pass 1.
;; End of Pass 2.
;; OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3, 
(Debug quality ignored)
;; Finished compiling /tmp/gazonk_27499_0.o.

#include "gazonk_27499_0.h"
void init_code(){do_init((void *)VV);}
/*      local entry for function FOO    */

static double LI1(V2)

double V2;
{        VMB1 VMS1 VMV1
        goto TTL;
TTL:;
        /*(log X)*/
        {double V3;
        V3= V2;      ;;*** Automatic inlining through function pointer
        {double V4 = ((double (*)(double))DLlog)(V3);VMR1
        (V4);}}
        /* END (log X)*/
}
/*      global entry for the function FOO       */

static void L1()
{       register object *base=vs_base;
        base[0]=make_longfloat(LI1(lf(base[0])));
        vs_top=(vs_base=base)+1;
}
#(#(log
    (%INIT
     . #((LET ((*DISABLE-RECOMPILE* T))
           (MF 'FOO 0)
           (ADD-HASH 'FOO '((LONG-FLOAT) LONG-FLOAT) '((log (T) T))
LISPLAMBDA!!,DECLAR,OPTIMIZ,SAFETY
libmlog-
               '/tmp/gazonk_27499_0.lsp)
           (MDL 'log 'libm 1))  ;;*** function pointer set on load,
                                      and reset on image startup
         (DO-RECOMPILE)))))
static void L1();
static double LI1();
static void *DLlog;
#define VMB1
#define VMS1
#define VMV1
#define VMR1(VMT1) return(VMT1);
#define VM1 0
static void * VVi[2]={
#define Cdata VV[1]
(void *)(L1),
(void *)(&DLlog)
};
#define VV (VVi)

/tmp/gazonk_27499_0.o:     file format elf32-i386

Disassembly of section .text:

00000000 <init_code>:
object
macro_def_int(object);

#include "gazonk_27499_0.h"
void init_code(){do_init((void *)VV);}
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   b8 00 00 00 00          mov    $0x0,%eax
   b:   89 04 24                mov    %eax,(%esp)
   e:   e8 fc ff ff ff          call   f <init_code+0xf>
  13:   c9                      leave
  14:   c3                      ret

00000015 <LI1>:
/*      local entry for function FOO    */

static double LI1(V2)

double V2;
{        VMB1 VMS1 VMV1
  15:   55                      push   %ebp
  16:   89 e5                   mov    %esp,%ebp
  18:   83 ec 28                sub    $0x28,%esp
  1b:   8b 45 08                mov    0x8(%ebp),%eax
  1e:   89 45 e8                mov    %eax,0xffffffe8(%ebp)
  21:   8b 45 0c                mov    0xc(%ebp),%eax
  24:   89 45 ec                mov    %eax,0xffffffec(%ebp)
        goto TTL;
TTL:;
        /*(log X)*/
        {double V3;
        V3= V2;
  27:   dd 45 e8                fldl   0xffffffe8(%ebp)
  2a:   dd 5d f0                fstpl  0xfffffff0(%ebp)
        {double V4 = ((double (*)(double))DLlog)(V3);VMR1    ;;***
                                                                minimal call 
overhead possible
  2d:   a1 00 00 00 00          mov    0x0,%eax
  32:   dd 45 f0                fldl   0xfffffff0(%ebp)
  35:   dd 1c 24                fstpl  (%esp)
  38:   ff d0                   call   *%eax
  3a:   dd 5d f8                fstpl  0xfffffff8(%ebp)
  3d:   dd 45 f8                fldl   0xfffffff8(%ebp)
        (V4);}}
        /* END (log X)*/
}
  40:   c9                      leave
  41:   c3                      ret

00000042 <L1>:
/*      global entry for the function FOO       */

static void L1()
{       register object *base=vs_base;
  42:   55                      push   %ebp
  43:   89 e5                   mov    %esp,%ebp
  45:   53                      push   %ebx
  46:   83 ec 14                sub    $0x14,%esp
  49:   8b 1d 00 00 00 00       mov    0x0,%ebx
        base[0]=make_longfloat(LI1(lf(base[0])));
  4f:   8b 03                   mov    (%ebx),%eax
  51:   dd 40 04                fldl   0x4(%eax)
  54:   dd 1c 24                fstpl  (%esp)
  57:   e8 b9 ff ff ff          call   15 <LI1>
  5c:   dd 1c 24                fstpl  (%esp)
  5f:   e8 fc ff ff ff          call   60 <L1+0x1e>
  64:   89 03                   mov    %eax,(%ebx)
        vs_top=(vs_base=base)+1;
  66:   89 1d 00 00 00 00       mov    %ebx,0x0
  6c:   a1 00 00 00 00          mov    0x0,%eax
  71:   83 c0 04                add    $0x4,%eax
  74:   a3 00 00 00 00          mov    %eax,0x0
}
  79:   83 c4 14                add    $0x14,%esp
  7c:   5b                      pop    %ebx
  7d:   5d                      pop    %ebp
  7e:   c3                      ret
NIL

SYSTEM>
=============================================================================

Each code block stores a list of its dlsym function pointers and the
symbol denoting the address to which they must be relocated on each
image startup:

=============================================================================
GCL (GNU Common Lisp)  2.7.0 CLtL1    May 22 2007 16:39:58
Source License: LGPL(gcl,gmp,pargcl), GPL(unexec,bfd,xgcl)
Binary License:  GPL due to GPL'ed components: (XGCL READLINE BFD UNEXEC)
Modifications of this banner must retain notice of a compatible license
Dedicated to the memory of W. Schelter

Use (help) to get some basic information on how to use GCL.

Temporary directory for compiler files set to /tmp/

(in-package 'si)

#<"SYSTEM" package>

SYSTEM>(mdlsym "dgemv_" "libblas.so")

|libblas|:|dgemv_|

SYSTEM>(show-lib-syms)

(LIB:|libblas| 6603144 #<"libblas" package>)
(|libblas|:|dgemv_| 1080730284 NIL)
NIL

SYSTEM>(si::save-system "ff")
[EMAIL PROTECTED]:/fix/t1/camm/debian/gcl/tmp/tmp/foo1/unixport$ ldd 
saved_pre_gcl
        libSM.so.6 => /usr/lib/libSM.so.6 (0x41443000)
        libICE.so.6 => /usr/lib/libICE.so.6 (0x413d9000)
        libXmu.so.6 => /usr/lib/libXmu.so.6 (0x413f3000)
        libXt.so.6 => /usr/lib/libXt.so.6 (0x412d7000)
        libXext.so.6 => /usr/lib/libXext.so.6 (0x41433000)
        libXaw.so.7 => /usr/lib/libXaw.so.7 (0x4000f000)
        libX11.so.6 => /usr/lib/libX11.so.6 (0x41136000)
        libgmp.so.3 => /usr/lib/libgmp.so.3 (0x4006a000)
        libreadline.so.5 => /lib/libreadline.so.5 (0x400ad000)
        libncurses.so.5 => /lib/libncurses.so.5 (0x41329000)
        libm.so.6 => /lib/libm.so.6 (0x4136c000)
        libdl.so.2 => /lib/libdl.so.2 (0x4145f000)
        libc.so.6 => /lib/libc.so.6 (0x41019000)
        libXau.so.6 => /usr/lib/libXau.so.6 (0x41465000)
        libXpm.so.4 => /usr/lib/libXpm.so.4 (0x41421000)
        libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x41458000)
        /lib/ld-linux.so.2 (0x41000000)
[EMAIL PROTECTED]:/fix/t1/camm/debian/gcl/tmp/tmp/foo1/unixport$ ldd ff
        libSM.so.6 => /usr/lib/libSM.so.6 (0x41443000)
        libICE.so.6 => /usr/lib/libICE.so.6 (0x413d9000)
        libXmu.so.6 => /usr/lib/libXmu.so.6 (0x413f3000)
        libXt.so.6 => /usr/lib/libXt.so.6 (0x412d7000)
        libXext.so.6 => /usr/lib/libXext.so.6 (0x41433000)
        libXaw.so.7 => /usr/lib/libXaw.so.7 (0x4000f000)
        libX11.so.6 => /usr/lib/libX11.so.6 (0x41136000)
        libgmp.so.3 => /usr/lib/libgmp.so.3 (0x4006a000)
        libreadline.so.5 => /lib/libreadline.so.5 (0x400ad000)
        libncurses.so.5 => /lib/libncurses.so.5 (0x41329000)
        libm.so.6 => /lib/libm.so.6 (0x4136c000)
        libdl.so.2 => /lib/libdl.so.2 (0x4145f000)
        libc.so.6 => /lib/libc.so.6 (0x41019000)
        libXau.so.6 => /usr/lib/libXau.so.6 (0x41465000)
        libXpm.so.4 => /usr/lib/libXpm.so.4 (0x41421000)
        libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x41458000)
        /lib/ld-linux.so.2 (0x41000000)
./ff
GCL (GNU Common Lisp)  2.7.0 CLtL1    May 22 2007 16:39:58
Source License: LGPL(gcl,gmp,pargcl), GPL(unexec,bfd,xgcl)
Binary License:  GPL due to GPL'ed components: (XGCL READLINE BFD UNEXEC)
Modifications of this banner must retain notice of a compatible license
Dedicated to the memory of W. Schelter

Use (help) to get some basic information on how to use GCL.

Temporary directory for compiler files set to /tmp/

(in-package 'si)

#<"SYSTEM" package>

SYSTEM>(show-lib-syms)

(LIB:|libblas| 6800592 #<"libblas" package>)
(|libblas|:|dgemv_| 1080730284 NIL)
NIL

SYSTEM>
=============================================================================

Suggestions most welcome.  One thing I'm not planning at the moment is
"deregistering" dlopened libraries, but this is open to consultation.

Given that it seems that most reasonable way for Axiom is to use
existiong C code.  There is are drawbacks: we need to interface to
C and typical Lisp implementation can only interface to shared
libraries via dlopen.  So we need to handle issues related to making
shared library.

Hopefully, the above will be useful.  It appears that libdl is quite
portable, but may require cygwin.


But AFAICS we will need C interface anyway, so we need to resolve
problems of C interface and shared libraries.


Thoughts most appreciated.  The above was primarily motivated to
obsolete the plt.c mechanism, which appears fragile and is currently
broken on mips for example.  But the implications for lisp extensions
appear quite attractive.

Take care,

--
Camm Maguire                                            [EMAIL PROTECTED]
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah


_______________________________________________
Axiom-developer mailing list
Axiom-developer@nongnu.org
http://lists.nongnu.org/mailman/listinfo/axiom-developer




_______________________________________________
Axiom-developer mailing list
Axiom-developer@nongnu.org
http://lists.nongnu.org/mailman/listinfo/axiom-developer

Reply via email to