aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/lux.lux6
-rw-r--r--src/lux/base.clj35
-rw-r--r--src/lux/compiler/base.clj26
-rw-r--r--src/lux/type.clj2
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'" ""