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 _______________________________________________ Gcl-devel mailing list Gcl-devel@gnu.org http://lists.gnu.org/mailman/listinfo/gcl-devel