diff options
author | Rich Hickey <richhickey@gmail.com> | 2008-05-03 19:39:34 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2008-05-03 19:39:34 +0000 |
commit | ab789fc2a395d19c1a8670765578fcda736e121c (patch) | |
tree | 93f771c37623d1d0432142f0946f3d1e2b827a45 | |
parent | 51ad6e94d9d4dc1818e9f730ef7c32d5a7227c2d (diff) |
gen-class, gen-and-load-class, gen-and-save-class
-rw-r--r-- | src/genclass.clj | 61 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 20 |
2 files changed, 52 insertions, 29 deletions
diff --git a/src/genclass.clj b/src/genclass.clj index 85a24241..7ef57a5b 100644 --- a/src/genclass.clj +++ b/src/genclass.clj @@ -154,7 +154,7 @@ (. obj-type getDescriptor) nil nil))) - ;static init to set up var fields + ;static init to set up var fields and load clj (let [gen (new GeneratorAdapter (+ (Opcodes.ACC_PUBLIC) (Opcodes.ACC_STATIC)) (Method.getMethod "void <clinit> ()") nil nil cv)] @@ -163,7 +163,12 @@ (. gen push name) (. gen push v) (. gen (invokeStatic rt-type (. Method (getMethod "clojure.lang.Var var(String,String)")))) - (. gen putStatic ctype (var-name v) var-type)) + (. gen putStatic ctype (var-name v) var-type)) + + (. gen push ctype) + (. gen push (str (name.replace \. (java.io.File.separatorChar)) ".clj")) + (. gen (invokeStatic rt-type (. Method (getMethod "void loadResourceScript(Class,String)")))) + (. gen (returnValue)) (. gen (endMethod))) @@ -316,6 +321,18 @@ (. cv (visitEnd)) {:name name :bytecode (. cv (toByteArray))})) +(defn gen-and-load-class [name & options] + (let [{:keys [name bytecode]} + (apply gen-class (str name) options)] + (.. clojure.lang.RT ROOT_CLASSLOADER (defineClass (str name) bytecode)))) + +(defn gen-and-save-class [path name & options] + (let [{:keys [name bytecode]} (apply gen-class (str name) options) + file (java.io.File. path (str (name.replace \. (java.io.File.separatorChar)) ".class"))] + (.createNewFile file) + (with-open f (java.io.FileOutputStream. file) + (.write f bytecode)))) + (comment ;usage (gen-class @@ -323,28 +340,28 @@ ;all below are optional :extends aclass :implements [interface ...] - :constructors {[param-types] [super-param-types], ...} - :methods [[name [param-types] return-type], ...] + :constructors {[param-types] [super-param-types], } + :methods [[name [param-types] return-type], ] :main boolean :factory name :state name :init name - :exposes {protected-field {:get name :set name}, ...}) - -(let [{:keys [name bytecode]} - (gen-class (str (gensym "fred.lucy.Ethel__")) - :extends clojure.lang.Box ;APersistentMap - :implements [IPersistentMap] - :state 'state - ;:constructors {[Object] [Object]} - ;:init 'init - :main true - :factory 'create - :methods [['foo [Object] Object] - ['foo [] Object]] - :exposes {'val {:get 'getVal :set 'setVal}} - )] - (.. clojure.lang.RT ROOT_CLASSLOADER (defineClass name bytecode))) + :exposes {protected-field {:get name :set name}, }) + +;(gen-and-load-class +(clojure/gen-and-save-class + "/Users/rich/Downloads" + 'fred.lucy.Ethel + :extends clojure.lang.Box ;APersistentMap + :implements [clojure.lang.IPersistentMap] + :state 'state + ;:constructors {[Object] [Object]} + ;:init 'init + :main true + :factory 'create + :methods [['foo [Object] Object] + ['foo [] Object]] + :exposes {'val {:get 'getVal :set 'setVal}}) (in-ns 'fred.lucy.Ethel__2276) (clojure/refer 'clojure :exclude '(assoc seq count cons)) @@ -362,8 +379,10 @@ (.foo ethel) (.getVal ethel) (.setVal ethel 12) -) (gen-class org.clojure.MyComparator :implements [Comparator]) (in-ns 'org.clojure.MyComparator) (defn compare [this x y] ...) + +) + diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 74bc58d5..ff522462 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -262,10 +262,14 @@ static public Var var(String ns, String name){ } public static void loadResourceScript(String name) throws Exception{ - InputStream ins = RT.class.getResourceAsStream("/" + name); + loadResourceScript(RT.class, name); +} + +public static void loadResourceScript(Class c, String name) throws Exception{ + InputStream ins = c.getResourceAsStream("/" + name); if(ins != null) { - Compiler.load(new InputStreamReader(ins), RT.class.getResource("/" + name).toString(), name); + Compiler.load(new InputStreamReader(ins), c.getResource("/" + name).toString(), name); ins.close(); } } @@ -275,11 +279,11 @@ static public void init() throws Exception{ } static void doInit() throws Exception{ - loadResourceScript("boot.clj"); - loadResourceScript("proxy.clj"); - loadResourceScript("zip.clj"); - loadResourceScript("xml.clj"); - loadResourceScript("set.clj"); + loadResourceScript(RT.class,"boot.clj"); + loadResourceScript(RT.class,"proxy.clj"); + loadResourceScript(RT.class,"zip.clj"); + loadResourceScript(RT.class,"xml.clj"); + loadResourceScript(RT.class,"set.clj"); Var.pushThreadBindings( RT.map(CURRENT_NS, CURRENT_NS.get(), @@ -293,7 +297,7 @@ static void doInit() throws Exception{ Var refer = var("clojure", "refer"); in_ns.invoke(USER); refer.invoke(CLOJURE); - loadResourceScript("user.clj"); + loadResourceScript(RT.class,"user.clj"); } finally { |