Changeset 12672


Ignore:
Timestamp:
05/12/10 22:52:33 (13 years ago)
Author:
astalla
Message:

FASL loader implemented. Has serious bugs (tests fail to compile), but can serve as a basis for further work.

Location:
branches/less-reflection/abcl/src/org/armedbear/lisp
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/less-reflection/abcl/src/org/armedbear/lisp/Autoload.java

    r12630 r12672  
    9898                                                  "org.armedbear.lisp.".concat(className)));
    9999    }
    100 
     100   
    101101    public void load()
    102102    {
  • branches/less-reflection/abcl/src/org/armedbear/lisp/FaslClassLoader.java

    r12631 r12672  
    3939
    4040public class FaslClassLoader extends JavaClassLoader {
     41
     42    private final LispObject[] functions;
     43    private String baseName;
     44    private LispObject loader; //The function used to load FASL functions by number
     45    private final JavaObject boxedThis = new JavaObject(this);
    4146   
     47    public FaslClassLoader(int functionCount, String baseName, boolean useLoaderFunction) {
     48  functions = new LispObject[functionCount];
     49  this.baseName = baseName;
     50  if(useLoaderFunction) {
     51      try {
     52    this.loader = (LispObject) loadClass(baseName + "_0").newInstance();
     53      } catch(Exception e) {
     54    //e.printStackTrace();
     55    Debug.trace("useLoaderFunction = true but couldn't fully init FASL loader, will fall back to reflection!");
     56      }
     57  }
     58    }
     59
    4260    protected Class<?> findClass(String name) throws ClassNotFoundException {
    4361  try {
     
    5270    }
    5371
    54     //TODO have compiler generate subclass, TEST ONLY!!!
    55     protected Map<String, LispObject> functions = new HashMap<String, LispObject>();
    56 
    57     public LispObject loadFunction(String className) {
     72    public LispObject loadFunction(int fnNumber) {
    5873  try {
    59       LispObject o = (LispObject) loadClass(className).newInstance();
    60       functions.put(className, o);
     74      //Function name is fnIndex + 1
     75      LispObject o = (LispObject) loadClass(baseName + "_" + (fnNumber + 1)).newInstance();
     76      functions[fnNumber] = o;
    6177      return o;
    6278  } catch(Exception e) {
     
    6783    }
    6884   
    69     public LispObject getFunction(final String className) {
    70   LispObject o = functions.get(className);
     85    public LispObject getFunction(int fnNumber) {
     86  if(fnNumber >= functions.length) {
     87      return error(new LispError("Compiled function not found: " + baseName + "_" + (fnNumber + 1) + " " + Symbol.LOAD_TRUENAME.symbolValue()));
     88  }
     89  LispObject o = functions[fnNumber];
    7190  if(o == null) {
    72       o = loadFunction(className);
     91      if(loader != null) {
     92    loader.execute(boxedThis, Fixnum.getInstance(fnNumber));
     93    return functions[fnNumber];
     94      } else { //Fallback to reflection
     95    return loadFunction(fnNumber);
     96      }
     97  } else {
     98      return o;
    7399  }
    74   return o;
    75100    }
    76101
    77     public static LispObject faslLoadFunction(String className) {
    78   FaslClassLoader cl = (FaslClassLoader) LispThread.currentThread().safeSymbolValue(_FASL_LOADER_).javaInstance();
    79   return cl.getFunction(className);
     102    public LispObject putFunction(int fnNumber, LispObject fn) {
     103  functions[fnNumber] = fn;
     104  return fn;
    80105    }
    81106
     
    83108    private static final class pf_make_fasl_class_loader extends Primitive {
    84109  pf_make_fasl_class_loader() {
    85             super("make-fasl-class-loader", PACKAGE_SYS, false, "");
     110            super("make-fasl-class-loader", PACKAGE_SYS, false, "function-count base-name");
    86111        }
    87112
    88113        @Override
    89         public LispObject execute() {
    90             return new JavaObject(new FaslClassLoader());
     114        public LispObject execute(LispObject functionCount, LispObject baseName) {
     115            return execute(functionCount, baseName, T);
     116        }
     117
     118        @Override
     119        public LispObject execute(LispObject functionCount, LispObject baseName, LispObject init) {
     120            return new FaslClassLoader(functionCount.intValue(), baseName.getStringValue(), init != NIL).boxedThis;
    91121        }
    92122    };
     
    95125    private static final class pf_get_fasl_function extends Primitive {
    96126  pf_get_fasl_function() {
    97             super("get-fasl-function", PACKAGE_SYS, false, "loader class-name");
     127            super("get-fasl-function", PACKAGE_SYS, false, "loader function-number");
    98128        }
    99129
    100130        @Override
    101         public LispObject execute(LispObject loader, LispObject className) {
     131        public LispObject execute(LispObject loader, LispObject fnNumber) {
    102132            FaslClassLoader l = (FaslClassLoader) loader.javaInstance(FaslClassLoader.class);
    103       return l.getFunction("org.armedbear.lisp." + className.getStringValue());
     133      return l.getFunction(fnNumber.intValue());
    104134        }
    105135    };
  • branches/less-reflection/abcl/src/org/armedbear/lisp/Function.java

    r12288 r12672  
    179179    public LispObject execute()
    180180    {
    181         return error(new WrongNumberOfArgumentsException(this));
     181        return error(new WrongNumberOfArgumentsException(this, 0));
    182182    }
    183183
     
    185185    public LispObject execute(LispObject arg)
    186186    {
    187         return error(new WrongNumberOfArgumentsException(this));
     187        return error(new WrongNumberOfArgumentsException(this, 1));
    188188    }
    189189
     
    192192
    193193    {
    194         return error(new WrongNumberOfArgumentsException(this));
     194        return error(new WrongNumberOfArgumentsException(this, 2));
    195195    }
    196196
     
    200200
    201201    {
    202         return error(new WrongNumberOfArgumentsException(this));
     202        return error(new WrongNumberOfArgumentsException(this, 3));
    203203    }
    204204
     
    208208
    209209    {
    210         return error(new WrongNumberOfArgumentsException(this));
     210        return error(new WrongNumberOfArgumentsException(this, 4));
    211211    }
    212212
     
    217217
    218218    {
    219         return error(new WrongNumberOfArgumentsException(this));
     219        return error(new WrongNumberOfArgumentsException(this, 5));
    220220    }
    221221
     
    226226
    227227    {
    228         return error(new WrongNumberOfArgumentsException(this));
     228        return error(new WrongNumberOfArgumentsException(this, 6));
    229229    }
    230230
     
    236236
    237237    {
    238         return error(new WrongNumberOfArgumentsException(this));
     238        return error(new WrongNumberOfArgumentsException(this, 7));
    239239    }
    240240
     
    246246
    247247    {
    248         return error(new WrongNumberOfArgumentsException(this));
     248        return error(new WrongNumberOfArgumentsException(this, 8));
    249249    }
    250250
  • branches/less-reflection/abcl/src/org/armedbear/lisp/Interpreter.java

    r12597 r12672  
    282282                            sb.append(separator);
    283283                            System.err.print(sb.toString());
     284          System.err.println("backtrace: ");
     285          evaluate("(princ (sys::backtrace))");
    284286                            System.exit(2);
    285287                        }
  • branches/less-reflection/abcl/src/org/armedbear/lisp/Lisp.java

    r12638 r12672  
    12441244              input = url.openStream();
    12451245          } catch (IOException e) {
     1246        System.err.println("Failed to read class bytes from boot class " + url);
    12461247              error(new LispError("Failed to read class bytes from boot class " + url));
    12471248          }
  • branches/less-reflection/abcl/src/org/armedbear/lisp/Load.java

    r12630 r12672  
    253253    }
    254254
     255    private static final Symbol FASL_LOADER = PACKAGE_SYS.intern("*FASL-LOADER*");
    255256    static final LispObject COMPILE_FILE_INIT_FASL_TYPE = new SimpleString("_");
    256257
     
    333334            final SpecialBindingsMark mark = thread.markSpecialBindings();
    334335            thread.bindSpecial(_WARN_ON_REDEFINITION_, NIL);
     336      thread.bindSpecial(FASL_LOADER, NIL);
    335337            try {
    336338                Stream stream = new Stream(Symbol.SYSTEM_STREAM, in, Symbol.CHARACTER);
     
    558560                if (obj == EOF)
    559561                    break;
    560                 result = eval(obj, env, thread);
     562    result = eval(obj, env, thread);
    561563                if (print) {
    562564                    Stream out =
  • branches/less-reflection/abcl/src/org/armedbear/lisp/compile-file.lisp

    r12630 r12672  
    4141(defvar *output-file-pathname*)
    4242
     43(defvar *function-packages* nil "An alist containing mappings (function-number . package). Every time an (IN-PACKAGE pkg) form is found at top-level, (*class-number* . pkg) is pushed onto this list.")
     44
     45(defun base-classname (&optional (output-file-pathname *output-file-pathname*))
     46  (sanitize-class-name (pathname-name output-file-pathname)))
     47
     48(defun fasl-loader-classname (&optional (output-file-pathname *output-file-pathname*))
     49  (%format nil "~A_0" (base-classname output-file-pathname)))
     50
    4351(declaim (ftype (function (t) t) compute-classfile-name))
    4452(defun compute-classfile-name (n &optional (output-file-pathname
     
    5260
    5361(defun sanitize-class-name (name)
    54   (dotimes (i (length name))
     62  (let ((name (copy-seq name)))
     63    (dotimes (i (length name))
    5564      (declare (type fixnum i))
    5665      (when (or (char= (char name i) #\-)
     
    5867    (char= (char name i) #\Space))
    5968        (setf (char name i) #\_)))
    60   name)
     69    name))
    6170 
    6271
     
    125134          ((IN-PACKAGE DEFPACKAGE)
    126135           (note-toplevel-form form)
     136     (if (eq operator 'in-package)
     137         (push (cons (1+ *class-number*) (cadr form)) *function-packages*))
    127138           (setf form (precompiler:precompile-form form nil *compile-file-environment*))
    128139           (eval form)
     
    157168                 (let* ((expr `(lambda ,lambda-list
    158169                                 ,@decls (block ,block-name ,@body)))
     170      (saved-class-number *class-number*)
    159171                        (classfile (next-classfile-name))
    160172                        (internal-compiler-errors nil)
     
    182194                            `(fset ',name
    183195           (sys::get-fasl-function *fasl-loader*
    184                  ,(pathname-name classfile))
     196                 ,saved-class-number)
    185197;                                   (proxy-preloaded-function ',name ,(file-namestring classfile))
    186198                                   ,*source-position*
     
    240252             (eval form)
    241253             (let* ((expr (function-lambda-expression (macro-function name)))
     254        (saved-class-number *class-number*)
    242255                    (classfile (next-classfile-name)))
    243256         (with-open-file
     
    259272                                               ; '(macro-function ,name)
    260273                                               ; ,(file-namestring classfile))
    261                  (sys::get-fasl-function *fasl-loader* ,(pathname-name classfile))))
     274                 (sys::get-fasl-function *fasl-loader* ,saved-class-number)))
    262275                             `(fset ',name
    263276                                    (make-macro ',name
     
    265278                                                ; '(macro-function ,name)
    266279                                                ; ,(file-namestring classfile))
    267             (sys::get-fasl-function *fasl-loader* ,(pathname-name classfile)))
     280            (sys::get-fasl-function *fasl-loader* ,saved-class-number))
    268281                                    ,*source-position*
    269282                                    ',(third form)))))))))
     
    367380  (when compile-time-too
    368381    (let ((*load-truename* *output-file-pathname*)
    369     (*fasl-loader* (make-fasl-class-loader)))
     382    (*fasl-loader* (make-fasl-class-loader
     383        *class-number*
     384        (concatenate 'string "org.armedbear.lisp." (base-classname))
     385        nil)))
    370386      (eval form))))
    371387
     
    384400      (let ((lambda-expression (cadr function-form)))
    385401        (jvm::with-saved-compiler-policy
    386           (let* ((classfile (next-classfile-name))
     402          (let* ((saved-class-number *class-number*)
     403     (classfile (next-classfile-name))
    387404                 (result
    388405      (with-open-file
     
    397414            (cond (compiled-function
    398415                   (setf (getf tail key)
    399        `(sys::get-fasl-function *fasl-loader* ,(pathname-name classfile))))
     416       `(sys::get-fasl-function *fasl-loader* ,saved-class-number)))
    400417;;                         `(load-compiled-function ,(file-namestring classfile))))
    401418                  (t
     
    431448      (precompiler:precompile-form form nil *compile-file-environment*)))
    432449  (let* ((expr `(lambda () ,form))
     450   (saved-class-number *class-number*)
    433451         (classfile (next-classfile-name))
    434452         (result
     
    444462    (setf form
    445463          (if compiled-function
    446               `(funcall (sys::get-fasl-function *fasl-loader* ,(pathname-name classfile)));(load-compiled-function ,(file-namestring classfile)))
     464              `(funcall (sys::get-fasl-function *fasl-loader* ,saved-class-number))
    447465              (precompiler:precompile-form form nil *compile-file-environment*)))))
    448466
     
    531549             (*source* *compile-file-truename*)
    532550             (*class-number* 0)
     551       (*function-packages* nil)
    533552             (namestring (namestring *compile-file-truename*))
    534553             (start (get-internal-real-time))
     
    593612              (%stream-terpri out)
    594613
    595         ;;TODO FAKE TEST ONLY!!!
    596614        (when (> *class-number* 0)
     615    (let* ((basename (base-classname))
     616           (expr `(lambda (fasl-loader fn-index)
     617        (identity fasl-loader) ;;to avoid unused arg
     618        ;;Ugly: should export & import JVM:: symbols
     619        #|(let ((*package* *package*))
     620        ,(let ((x (cdr (assoc 0 *function-packages*)))) ;;in-package before any function was defined
     621          (when x
     622            `(in-package ,(string x))))|#
     623        (ecase fn-index
     624          ,@(loop
     625               :for i :from 1 :to *class-number*
     626               :collect
     627           (let ((class (%format nil "org/armedbear/lisp/~A_~A" basename i)))
     628             `(,(1- i) (jvm::with-inline-code ()
     629          ;(jvm::emit 'jvm::ldc (jvm::pool-string (symbol-name 'sys::*fasl-loader*)))
     630          ;(jvm::emit 'jvm::ldc (jvm::pool-string (string :system)))
     631          ;(jvm::emit-invokestatic jvm::+lisp-class+ "internInPackage"
     632          ;(list jvm::+java-string+ jvm::+java-string+) jvm::+lisp-symbol+)
     633          ;(jvm::emit-push-current-thread)
     634          ;           (jvm::emit-invokevirtual jvm::+lisp-symbol-class+ "symbolValue"
     635          ;                  (list jvm::+lisp-thread+) jvm::+lisp-object+)
     636              (jvm::emit 'jvm::aload 1)
     637              (jvm::emit-invokevirtual jvm::+lisp-object-class+ "javaInstance"
     638                     nil jvm::+java-object+)
     639              (jvm::emit 'jvm::checkcast "org/armedbear/lisp/FaslClassLoader")
     640              (jvm::emit 'jvm::dup)
     641              (jvm::emit-push-constant-int ,(1- i))
     642              (jvm::emit 'jvm::new ,class)
     643              (jvm::emit 'jvm::dup)
     644              (jvm::emit-invokespecial-init ,class '())
     645              (jvm::emit-invokevirtual "org/armedbear/lisp/FaslClassLoader" "putFunction"
     646                     (list "I" jvm::+lisp-object+) jvm::+lisp-object+)
     647              (jvm::emit 'jvm::pop))
     648            t))))))
     649           (classname (fasl-loader-classname))
     650           (classfile (namestring (merge-pathnames (make-pathname :name classname :type "cls")
     651                     *output-file-pathname*))))
     652      (jvm::with-saved-compiler-policy
     653          (jvm::with-file-compilation
     654        (with-open-file
     655            (f classfile
     656         :direction :output
     657         :element-type '(unsigned-byte 8)
     658         :if-exists :supersede)
     659          (jvm:compile-defun nil expr nil
     660                 classfile f nil)))))
    597661    (write (list 'setq '*fasl-loader*
    598            '(sys::make-fasl-class-loader)) :stream out)
     662           `(sys::make-fasl-class-loader
     663             ,*class-number*
     664             ,(concatenate 'string "org.armedbear.lisp." (base-classname)))) :stream out)
    599665    (%stream-terpri out))
    600666#|        (dump-form
     
    634700                           (merge-pathnames (make-pathname :type type)
    635701                                            output-file)))
    636                  (pathnames ()))
     702                 (pathnames (list (namestring (merge-pathnames (make-pathname :name (fasl-loader-classname) :type "cls")
     703                     output-file)))))
    637704            (dotimes (i *class-number*)
    638705              (let* ((pathname (compute-classfile-name (1+ i))))
  • branches/less-reflection/abcl/src/org/armedbear/lisp/precompiler.lisp

    r12638 r12672  
    959959                                  'precompiler))))
    960960    (unless (and handler (fboundp handler))
    961       (error "No handler for ~S." symbol))
     961      (error "No handler for ~S." (let ((*package* (find-package :keyword)))
     962            (format nil "~S" symbol))))
    962963    (setf (get symbol 'precompile-handler) handler)))
    963964
Note: See TracChangeset for help on using the changeset viewer.