summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-05-03 19:39:34 +0000
committerRich Hickey <richhickey@gmail.com>2008-05-03 19:39:34 +0000
commitab789fc2a395d19c1a8670765578fcda736e121c (patch)
tree93f771c37623d1d0432142f0946f3d1e2b827a45
parent51ad6e94d9d4dc1818e9f730ef7c32d5a7227c2d (diff)
gen-class, gen-and-load-class, gen-and-save-class
-rw-r--r--src/genclass.clj61
-rw-r--r--src/jvm/clojure/lang/RT.java20
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
{