From 639c9385219e143fd7a6161c57fda34293b81055 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Tue, 26 May 2015 22:35:58 -0400 Subject: - Now using an in-memory class-loader. --- source/lux.lux | 6 ++++-- src/lux/base.clj | 35 +++++++++++++++++++++++++++++------ src/lux/compiler/base.clj | 26 +++++++++++++++++--------- src/lux/type.clj | 2 +- 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/source/lux.lux b/source/lux.lux index ac47e81eb..ac28bf372 100644 --- a/source/lux.lux +++ b/source/lux.lux @@ -206,11 +206,13 @@ ## (deftype HostState ## (& #writer (^ org.objectweb.asm.ClassWriter) -## #loader (^ java.net.URLClassLoader))) +## #loader (^ java.net.URLClassLoader) +## #classes (^ clojure.lang.Atom))) (_lux_def HostState (#RecordT (#Cons [["lux;writer" (#DataT "org.objectweb.asm.ClassWriter")] (#Cons [["lux;loader" (#DataT "java.lang.ClassLoader")] - #Nil])]))) + (#Cons [["lux;classes" (#DataT "clojure.lang.Atom")] + #Nil])])]))) ## (deftype (DefData' m) ## (| #TypeD diff --git a/src/lux/base.clj b/src/lux/base.clj index 7f551cdb0..c4aab9ec6 100644 --- a/src/lux/base.clj +++ b/src/lux/base.clj @@ -15,8 +15,9 @@ (def $NAME 3) ;; Host -(def $LOADER 0) -(def $WRITER 1) +(def $CLASSES 0) +(def $LOADER 1) +(def $WRITER 2) ;; CompilerState (def $ENVS 0) @@ -422,6 +423,10 @@ (fn [state] (return* state (->> state (get$ $HOST) (get$ $LOADER))))) +(def classes + (fn [state] + (return* state (->> state (get$ $HOST) (get$ $CLASSES))))) + (def +init-bindings+ (R ;; "lux;counter" 0 @@ -439,11 +444,29 @@ name )) +(let [define-class (doto (.getDeclaredMethod java.lang.ClassLoader "defineClass" (into-array [String + (class (byte-array [])) + Integer/TYPE + Integer/TYPE])) + (.setAccessible true))] + (defn memory-class-loader [store] + (proxy [java.lang.ClassLoader] + [] + (findClass [^String class-name] + ;; (prn 'findClass class-name) + (if-let [bytecode (get @store class-name)] + (.invoke define-class this (to-array [class-name bytecode (int 0) (int (alength bytecode))])) + (throw (IllegalStateException. (str "[Class Loader] Unknown class: " class-name)))))))) + (defn host [_] - (R ;; "lux;loader" - (-> (java.io.File. "./output/") .toURL vector into-array java.net.URLClassLoader.) - ;; "lux;writer" - (V "lux;None" nil))) + (let [store (atom {})] + (R ;; "lux;classes" + store + ;; "lux;loader" + (memory-class-loader store) + ;; (-> (java.io.File. "./output/") .toURL vector into-array java.net.URLClassLoader.) + ;; "lux;writer" + (V "lux;None" nil)))) (defn init-state [_] (R ;; "lux;envs" diff --git a/src/lux/compiler/base.clj b/src/lux/compiler/base.clj index a7886ab48..24f342469 100644 --- a/src/lux/compiler/base.clj +++ b/src/lux/compiler/base.clj @@ -15,18 +15,26 @@ (def closure-prefix "c") (def apply-signature "(Ljava/lang/Object;)Ljava/lang/Object;") -(defn write-file [^String file ^bytes data] - (with-open [stream (java.io.BufferedOutputStream. (java.io.FileOutputStream. file))] - (.write stream data))) +;; (defn write-file [^String file ^bytes data] +;; (with-open [stream (java.io.BufferedOutputStream. (java.io.FileOutputStream. file))] +;; (.write stream data))) -(defn write-class [name data] - (write-file (str "output/" name ".class") data)) +;; (defn write-class [name data] +;; (write-file (str "output/" name ".class") data)) (defn load-class! [^ClassLoader loader name] (.loadClass loader name)) +;; (defn save-class! [name bytecode] +;; (|do [loader &/loader +;; :let [_ (write-class name bytecode) +;; _ (load-class! loader (string/replace name #"/" "."))]] +;; (return nil))) + (defn save-class! [name bytecode] - (|do [loader &/loader - :let [_ (write-class name bytecode) - _ (load-class! loader (string/replace name #"/" "."))]] - (return nil))) + (let [real-name (string/replace name #"/" ".")] + (|do [loader &/loader + !classes &/classes + :let [_ (swap! !classes assoc real-name bytecode) + _ (load-class! loader real-name)]] + (return nil)))) diff --git a/src/lux/type.clj b/src/lux/type.clj index 25e3e1053..d5be5a7c6 100644 --- a/src/lux/type.clj +++ b/src/lux/type.clj @@ -126,7 +126,7 @@ (&/V "lux;RecordT" (&/|list (&/T "lux;writer" (&/V "lux;DataT" "org.objectweb.asm.ClassWriter")) (&/T "lux;loader" (&/V "lux;DataT" "java.lang.ClassLoader")) - ))) + (&/T "lux;classes" (&/V "lux;DataT" "clojure.lang.Atom"))))) (def DefData* (fAll "lux;DefData'" "" -- cgit v1.2.3