]> git.eshelyaron.com Git - emacs.git/commitdiff
working on comp.el
authorAndrea Corallo <andrea_corallo@yahoo.it>
Sun, 7 Jul 2019 10:30:03 +0000 (12:30 +0200)
committerAndrea Corallo <akrl@sdf.org>
Wed, 1 Jan 2020 10:33:49 +0000 (11:33 +0100)
lisp/emacs-lisp/byte-run.el
lisp/emacs-lisp/bytecomp.el
lisp/emacs-lisp/comp.el

index 6a49c60099d119c126119ba20db2afb8d8a9ace3..fedbd61ffd1ec49f3d2c8f9dd91cd8fb89746f52 100644 (file)
@@ -597,4 +597,6 @@ Otherwise, return nil.  For internal use only."
 (make-obsolete 'macro-declaration-function
                'macro-declarations-alist "24.3")
 
+(provide 'byte-run)
+
 ;;; byte-run.el ends here
index 2617142c622076d2fa323011d3fbc0f98c95ca12..fa3f5a7f9b9b6fb12d2a4c7f2edc1ece0ea6a753 100644 (file)
 (require 'backquote)
 (require 'macroexp)
 (require 'cconv)
+(require 'byte-run)
 (eval-when-compile (require 'compile))
 ;; Refrain from using cl-lib at run-time here, since it otherwise prevents
 ;; us from emitting warnings when compiling files which use cl-lib without
index d72127a6eb16d42a9006ecdb781295581944d9b0..9b3bb98e39a6c14d3560111c448861f874a02aa7 100644 (file)
 
 ;;; Code:
 
-(require 'disass)
+(require 'bytecomp)
 (eval-when-compile (require 'cl-lib))
 
 (defgroup comp nil
   "Emacs Lisp native compiler."
   :group 'lisp)
 
-(defun comp-recuparate-lap (fun)
-  "Compile FUN if necessary and recuparate its LAP rapresentation."
-  (byte-compile-close-variables
-   (byte-compile-top-level (byte-compile-preprocess fun))
-   byte-compile-lap-output))
+(defconst comp-debug t)
 
-(defun comp-compute-blocks (obj)
-  "Split OBJ in basic blocks."
-  obj)
+(defconst comp-passes '(comp-recuparate-lap
+                        comp-limplify)
+  "Passes to be executed in order.")
+
+(cl-defstruct comp-args
+  mandatory nonrest rest)
+
+(cl-defstruct (comp-func (:copier nil))
+  "Internal rapresentation for a function."
+  (symbol-name nil
+   :documentation "Function symbol's name")
+  (func nil
+   :documentation "Original form")
+  (byte-func nil
+   :documentation "Byte compiled version")
+  (ir nil
+      :documentation "Current intermediate rappresentation")
+  (args nil :type 'comp-args))
+
+(cl-defstruct (comp-meta-var (:copier nil))
+  "A frame slot into the meta-stack."
+  (slot nil :type fixnum
+        :documentation "Slot position into the meta-stack")
+  (const-vld nil
+             :documentation "Valid for the following slot")
+  (constant nil
+            :documentation "When const-vld non nil this is used for constant
+ propagation")
+  (type nil
+        :documentation "When non nil is used for type propagation"))
+
+(cl-defstruct (comp-limple-frame (:copier nil))
+  "A LIMPLE func."
+  (sp 0 :type 'fixnum
+      :documentation "Current stack pointer")
+  (frame nil :type 'vector
+         :documentation "Meta-stack used to flat LAP"))
+
+(defun comp-decrypt-lambda-list (x)
+  "Decript lambda list X."
+  (make-comp-args :rest (not (= (logand x 128) 0))
+                  :mandatory (logand x 127)
+                  :nonrest (ash x -8)))
+
+(defun comp-recuparate-lap (ir)
+  "Byte compile and recuparate LAP rapresentation for IR."
+  ;; FIXME block timers here, otherwise we could spill the wrong LAP.
+  (setf (comp-func-byte-func ir)
+        (byte-compile (comp-func-symbol-name ir)))
+  (when comp-debug
+    (cl-prettyprint byte-compile-lap-output))
+  (setf (comp-func-args ir)
+        (comp-decrypt-lambda-list (aref (comp-func-byte-func ir) 0)))
+  (setf (comp-func-ir ir) byte-compile-lap-output)
+  ir)
+
+(defmacro comp-sp ()
+  "Current stack pointer."
+  '(comp-limple-frame-sp frame))
+
+(defmacro comp-slot ()
+  "Current slot into the meta-stack pointed by sp."
+  '(aref (comp-limple-frame-frame frame) (comp-sp)))
+
+(defmacro comp-push (n)
+  "Push slot number N into frame."
+  `(progn
+     (cl-incf (comp-sp))
+     (list '= (comp-slot) ,n)))
+
+(defmacro comp-push-slot (n)
+  "Push slot number N into frame."
+  `(let ((src-slot (aref (comp-limple-frame-frame frame) ,n)))
+     (cl-incf (comp-sp))
+     (setf (comp-slot)
+           (copy-sequence src-slot))
+     (setf (comp-meta-var-slot (comp-slot)) (comp-sp))
+     (list '= (comp-slot) src-slot)))
+
+(defmacro comp-push-const (x)
+  "Push X into frame.
+X value is known at compile time."
+  `(progn
+     (cl-incf (comp-sp))
+     (setf (comp-slot) (make-comp-meta-var :slot (comp-sp)
+                                           :const-vld t
+                                           :constant ,x))
+     (list '= (comp-slot) ,x)))
+
+(defmacro comp-pop (n)
+  "Pop N elements from the meta-stack."
+  `(cl-decf (comp-sp) ,n))
+
+(defun comp-limplify-lap-inst (inst frame)
+  "Limplify LAP instruction INST in current FRAME."
+  (let ((op (car inst)))
+    (pcase op
+      ('byte-varref
+       (comp-push `(call Fsymbol_value ,(second inst))))
+      ('byte-constant
+       (comp-push-const (second inst)))
+      ('byte-stack-ref
+       (comp-push-slot (- (comp-sp) (cdr inst))))
+      ('byte-plus
+       (comp-pop 2)
+       (comp-push `(callref Fplus 2 ,(comp-sp))))
+      ('byte-return
+       `(return ,(comp-sp)))
+      (_ 'xxx))))
+
+(defun comp-limplify (ir)
+  "Take IR and return LIMPLE."
+  (let* ((frame-size (aref (comp-func-byte-func ir) 3))
+         (frame (make-comp-limple-frame
+                 :sp (1- (comp-args-mandatory (comp-func-args ir)))
+                 :frame (let ((v (make-vector frame-size nil)))
+                          (cl-loop for i below frame-size
+                                   do (aset v i (make-comp-meta-var :slot i)))
+                          v)))
+         (limple-ir
+          (cl-loop
+           for inst in (comp-func-ir ir)
+           collect (comp-limplify-lap-inst inst frame))))
+    (setf (comp-func-ir ir) limple-ir)
+    (when comp-debug
+      (cl-prettyprint (comp-func-ir ir)))
+    ir))
 
 (defun native-compile (fun)
   "FUN is the function definition to be compiled to native code."
+  (unless lexical-binding
+    (error "Can't compile a non lexical binded function"))
   (if-let ((f (symbol-function fun)))
-      (comp-recuparate-lap f)
+      (progn
+        (when (byte-code-function-p f)
+          (error "Can't native compile an already bytecompiled function"))
+        (cl-loop with ir = (make-comp-func :symbol-name fun
+                                           :func f)
+                 for pass in comp-passes
+                 do (funcall pass ir)
+                 finally return ir))
     (error "Trying to native compile not a function")))
 
 (provide 'comp)