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