summaryrefslogtreecommitdiff
path: root/src/jvm
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-11-29 18:42:17 +0000
committerRich Hickey <richhickey@gmail.com>2008-11-29 18:42:17 +0000
commita4f923670d89fd7f4d72f39ec85ec8f46ea43bdc (patch)
tree020f7f0b93170b65c7d2a4f33772178a91172875 /src/jvm
parent09c2d0dd2eff4fbe7962d6f68492d3dc1e07d4ff (diff)
enhancements to AOT/gen-class
AOT now only produces __init.class by default, load uses that class only must have at least (:gen-class) ns clause to create named class for ns gen-class can now be called stand-alone new options allow for control of mapping to implementing namespace, name of class, loading of implementing namespace, and method name prefix (doc ns) and (doc gen-class) and http://clojure.org/compilation for details
Diffstat (limited to 'src/jvm')
-rw-r--r--src/jvm/clojure/lang/Compile.java14
-rw-r--r--src/jvm/clojure/lang/Compiler.java58
-rw-r--r--src/jvm/clojure/lang/RT.java151
3 files changed, 16 insertions, 207 deletions
diff --git a/src/jvm/clojure/lang/Compile.java b/src/jvm/clojure/lang/Compile.java
index d31b3569..7dbf6822 100644
--- a/src/jvm/clojure/lang/Compile.java
+++ b/src/jvm/clojure/lang/Compile.java
@@ -45,18 +45,16 @@ public static void main(String[] args) throws Exception{
{
Var.pushThreadBindings(RT.map(compile_path, path));
- out.write("Compiling " + count + " " +
- ((count == 1) ? "lib" : "libs") +
- " to " + path);
- out.flush();
-
for(String lib : args)
- compile.invoke(Symbol.intern(lib));
-
- Var.popThreadBindings();
+ {
+ out.write("Compiling " + lib + " to " + path + "\n");
+ out.flush();
+ compile.invoke(Symbol.intern(lib));
+ }
}
finally
{
+ Var.popThreadBindings();
try
{
out.flush();
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 5d5c7b9e..aee53673 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -4061,6 +4061,8 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti
return analyze(context, me, name);
Object op = RT.first(form);
+ if(op == null)
+ throw new IllegalArgumentException("Can't call nil");
IFn inline = isInline(op, RT.count(RT.rest(form)));
if(inline != null)
return analyze(context, inline.applyTo(RT.rest(form)));
@@ -4498,43 +4500,10 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t
try
{
- //use genclass for the stub
- String classname = sourcePath.substring(0, sourcePath.lastIndexOf('.')).replace('/', '.');
- Object r = LispReader.read(pushbackReader, false, EOF, false);
- Object genclassArgs = null;
- if(r instanceof IPersistentList
- && (Util.equal(RT.first(r), Symbol.create("ns"))
- || Util.equal(RT.first(r), Symbol.create("clojure.core", "ns"))))
- {
- Keyword gk = Keyword.intern(null, "gen-class");
- Symbol nssym = (Symbol) RT.second(r);
- if(!nssym.toString().replace('-','_').equals(classname))
- throw new Exception(String.format("Namespace name must match file, had: %s and %s",
- nssym, sourcePath));
- for(ISeq s = RT.rest(RT.rest(r)); s != null; s = s.rest())
- {
- Object entry = s.first();
- if(RT.first(entry).equals(gk))
- {
- genclassArgs = RT.rest(entry);
- break;
- }
- }
- }
-
- if(genclassArgs == null)
- genclassArgs = RT.list(Keyword.intern(null, "main"), RT.T);
-
- genclassArgs = RT.cons(classname, genclassArgs);
- Var genclass = RT.var("clojure.core", "gen-class");
- IPersistentMap gret = (IPersistentMap) genclass.applyTo(RT.seq(genclassArgs));
- writeClassFile(sourcePath.substring(0, sourcePath.lastIndexOf('.')),
- (byte[]) RT.get(gret, Keyword.intern(null, "bytecode")));
-
//generate loader class
FnExpr fn = new FnExpr(null);
fn.internalName = sourcePath.replace(File.separator, "/").substring(0, sourcePath.lastIndexOf('.'))
- + "__init";
+ + RT.LOADER_SUFFIX;
fn.fntype = Type.getObjectType(fn.internalName);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
@@ -4549,7 +4518,7 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t
cv);
gen.visitCode();
- for(; r != EOF;
+ for(Object r = LispReader.read(pushbackReader, false, EOF, false); r != EOF;
r = LispReader.read(pushbackReader, false, EOF, false))
{
LINE_AFTER.set(pushbackReader.getLineNumber());
@@ -4606,25 +4575,6 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t
clinitgen.returnValue();
clinitgen.endMethod();
- //main
-// GeneratorAdapter maingen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
-// Method.getMethod("void main (String[])"),
-// null,
-// null,
-// cv);
-// maingen.visitCode();
-// maingen.push(fn.internalName.replace('/', '.'));
-// maingen.push("main");
-// maingen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.Var var(String,String)"));
-// maingen.loadArgs();
-// maingen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.ISeq seq(Object)"));
-// maingen.invokeInterface(IFN_TYPE, new Method("applyTo", OBJECT_TYPE, new Type[]{Type.getType(ISeq.class)}));
-// maingen.pop();
-//
-// //end of main
-// maingen.returnValue();
-// maingen.endMethod();
-
//end of class
cv.visitEnd();
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index f6139d1b..aca1bee2 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -34,6 +34,7 @@ public class RT{
static final public Boolean T = Boolean.TRUE;//Keyword.intern(Symbol.create(null, "t"));
static final public Boolean F = Boolean.FALSE;//Keyword.intern(Symbol.create(null, "t"));
+static final public String LOADER_SUFFIX = "__init";
//simple-symbol->class
final static IPersistentMap DEFAULT_IMPORTS = map(
@@ -193,9 +194,6 @@ final static public Var USE_CONTEXT_CLASSLOADER =
final static Symbol LOAD_FILE = Symbol.create("load-file");
final static Symbol IN_NAMESPACE = Symbol.create("in-ns");
final static Symbol NAMESPACE = Symbol.create("ns");
-//final static Symbol EXPORTS = Symbol.create("*exports*");
-//final static Var EXPORTS_VAR = Var.intern(CLOJURE_NS, EXPORTS, PersistentHashMap.EMPTY);
-//final static Symbol EQL_REF = Symbol.create("eql-ref?");
static final Symbol IDENTICAL = Symbol.create("identical?");
final static Var CMD_LINE_ARGS = Var.intern(CLOJURE_NS, Symbol.create("*command-line-args*"), null);
//symbol
@@ -219,16 +217,6 @@ final static IFn inNamespace = new AFn(){
Symbol nsname = (Symbol) arg1;
Namespace ns = Namespace.findOrCreate(nsname);
CURRENT_NS.set(ns);
-// Var refers = Var.intern(null,Symbol.intern(nsname.name, "*refers*"));
-//
-// Var imports = Var.intern(null,Symbol.intern(nsname.name, "*imports*"), DEFAULT_IMPORTS, false);
-// NS_REFERS.set(refers);
-// NS_IMPORTS.set(imports);
-// if(!refers.isBound())
-// {
-// refers.bindRoot(PersistentHashMap.EMPTY);
-// Compiler.eval(list(Symbol.create("clojure.core", "refer"), EXPORTS));
-// }
return ns;
}
};
@@ -243,28 +231,7 @@ public static List<String> processCommandLine(String[] args){
}
return arglist;
}
-//simple-symbol->var
-//final static Var REFERS =
-// Var.intern(CLOJURE_NS, Symbol.create("*refers*"),
-// map(
-// IN_NAMESPACE, Var.intern(CLOJURE_NS, IN_NAMESPACE, inNamespace),
-// LOAD_FILE, Var.intern(CLOJURE_NS, LOAD_FILE,
-// new AFn(){
-// public Object invoke(Object arg1) throws Exception{
-// return Compiler.loadFile((String) arg1);
-// }
-// }),
-// IDENTICAL, Var.intern(CLOJURE_NS, IDENTICAL,
-// new AFn(){
-// public Object invoke(Object arg1, Object arg2)
-// throws Exception{
-// return arg1 == arg2 ? RT.T : RT.F;
-// }
-// })
-// ));
-
-//static Var NS_IMPORTS = Var.intern(CLOJURE_NS,Symbol.create("*ns-imports*"), IMPORTS);
-//static Var NS_REFERS = Var.intern(CLOJURE_NS,Symbol.create("*ns-refers*"), REFERS);
+
static public final Object[] EMPTY_ARRAY = new Object[]{};
static public final Comparator DEFAULT_COMPARATOR = new Comparator(){
public int compare(Object o1, Object o2){
@@ -272,7 +239,6 @@ static public final Comparator DEFAULT_COMPARATOR = new Comparator(){
}
};
-//static public final Character[] chars;
static AtomicInteger id = new AtomicInteger(1);
static final public DynamicClassLoader ROOT_CLASSLOADER = new DynamicClassLoader();
@@ -291,7 +257,8 @@ static
AGENT.setTag(Symbol.create("clojure.lang.Agent"));
MATH_CONTEXT.setTag(Symbol.create("java.math.MathContext"));
//during bootstrap ns same as in-ns
- Var.intern(CLOJURE_NS, NAMESPACE, inNamespace);
+ Var nv = Var.intern(CLOJURE_NS, NAMESPACE, inNamespace);
+ nv.setMacro();
Var v;
v = Var.intern(CLOJURE_NS, IN_NAMESPACE, inNamespace);
v.setMeta(map(dockw, "Sets *ns* to the namespace named by the symbol, creating it if needed.",
@@ -313,16 +280,6 @@ static
});
v.setMeta(map(dockw, "Tests if 2 arguments are the same object",
arglistskw, list(vector(Symbol.create("x"), Symbol.create("y")))));
-// try
-// {
-// InputStream ins = RT.class.getResourceAsStream("/boot.clj");
-// Compiler.load(new InputStreamReader(ins));
-// }
-// catch(Exception e)
-// {
-// throw new IllegalStateException("Error loading boot.clj", e);
-// }
-
try
{
doInit();
@@ -332,12 +289,6 @@ static
throw new RuntimeException(e);
}
}
-//static
-// {
-// chars = new Character[256];
-// for(int i = 0; i < chars.length; i++)
-// chars[i] = new Character((char) i);
-// }
static public Var var(String ns, String name){
@@ -425,7 +376,7 @@ static public void load(String scriptbase) throws Exception{
}
static public void load(String scriptbase, boolean failIfNotFound) throws Exception{
- String classfile = scriptbase + ".class";
+ String classfile = scriptbase + LOADER_SUFFIX + ".class";
String cljfile = scriptbase + ".clj";
URL classURL = baseLoader().getResource(classfile);
URL cljURL = baseLoader().getResource(cljfile);
@@ -439,7 +390,7 @@ static public void load(String scriptbase, boolean failIfNotFound) throws Except
Var.pushThreadBindings(
RT.map(CURRENT_NS, CURRENT_NS.get(),
WARN_ON_REFLECTION, WARN_ON_REFLECTION.get()));
- loadClassForName(scriptbase.replace('/','.'));
+ loadClassForName(scriptbase.replace('/','.') + LOADER_SUFFIX);
}
finally
{
@@ -462,23 +413,6 @@ static void doInit() throws Exception{
load("clojure/zip",false);
load("clojure/xml",false);
load("clojure/set",false);
-// try
-// {
-// Reflector.invokeStaticMethod("clojure.core", "load", EMPTY_ARRAY);
-// Reflector.invokeStaticMethod("clojure.zip", "load", EMPTY_ARRAY);
-// Reflector.invokeStaticMethod("clojure.xml", "load", EMPTY_ARRAY);
-// Reflector.invokeStaticMethod("clojure.set", "load", EMPTY_ARRAY);
-// }
-// finally
-// {
-// Var.popThreadBindings();
-// }
-// loadResourceScript(RT.class, "clojure/core.clj");
-// loadResourceScript(RT.class, "clojure/proxy.clj", false);
-// loadResourceScript(RT.class, "clojure/genclass.clj", false);
-// loadResourceScript(RT.class, "clojure/zip.clj", false);
-// loadResourceScript(RT.class, "clojure/xml.clj", false);
-// loadResourceScript(RT.class, "clojure/set.clj", false);
Var.pushThreadBindings(
RT.map(CURRENT_NS, CURRENT_NS.get(),
@@ -504,38 +438,6 @@ static public int nextID(){
return id.getAndIncrement();
}
-//static public Object eq(Object arg1, Object arg2){
-// return (arg1 == arg2) ? Boolean.TRUE : null;
-//}
-//
-//static public Object eql(Object arg1, Object arg2){
-// if(arg1 == arg2)
-// return Boolean.TRUE;
-// if(arg1 == null || arg2 == null)
-// return null;
-// if(arg1 instanceof Num
-// && arg1.getClass() == arg2.getClass()
-// && arg1.equals(arg2))
-// return Boolean.TRUE;
-// if(arg1.getClass() == Character.class
-// && arg2.getClass() == Character.class
-// && arg1.equals(arg2))
-// return Boolean.TRUE;
-// return null;
-//}
-
-// static public Object equal(Object arg1, Object arg2) {
-// if(arg1 == null)
-// return arg2 == null ? Boolean.TRUE : null;
-// else if(arg2 == null)
-// return null;
-// return (eql(arg1,arg2) != null
-// || (arg1.getClass() == Cons.class
-// && arg2.getClass() == Cons.class
-// && equal(((Cons)arg1)._first,((Cons)arg2)._first)!=null
-// && equal(((Cons)arg1)._rest,((Cons)arg2)._rest)!=null))
-// ?Boolean.TRUE:null;
-// }
////////////// Collections support /////////////////////////////////
@@ -559,10 +461,6 @@ static ISeq seqFrom(Object coll){
return StringSeq.create((String) coll);
else if(coll instanceof Map)
return seq(((Map) coll).entrySet());
-// else if(coll instanceof Iterator)
-// return IteratorSeq.create((Iterator) coll);
-// else if(coll instanceof Enumeration)
-// return EnumerationSeq.create(((Enumeration) coll));
else
throw new IllegalArgumentException("Don't know how to create ISeq from: " + coll.getClass().getSimpleName());
}
@@ -680,7 +578,6 @@ static public Object get(Object coll, Object key){
}
return null;
- //throw new UnsupportedOperationException("get not supported on this type");
}
static public Object get(Object coll, Object key, Object notFound){
@@ -709,7 +606,6 @@ static public Object get(Object coll, Object key, Object notFound){
}
return notFound;
-// throw new UnsupportedOperationException("get not supported on this type");
}
static public Associative assoc(Object coll, Object key, Object val){
@@ -736,7 +632,6 @@ static public Object contains(Object coll, Object key){
return n >= 0 && n < count(coll);
}
return F;
- //throw new UnsupportedOperationException("contains not supported on this type");
}
static public Object find(Object coll, Object key){
@@ -890,24 +785,6 @@ static public Object assocN(int n, Object val, Object coll){
return null;
}
-/*
-static public Iter iter(Object coll){
- if(coll == null || coll instanceof Iter)
- return (Iter) coll;
- else if(coll instanceof Iterator)
- {
- Iterator i = (Iterator) coll;
- if(i.hasNext())
- return new IteratorIter(i);
- return null;
- }
- else if(coll instanceof Iterable)
- return new IteratorIter(((Iterable) coll).iterator());
-
- else
- throw new IllegalArgumentException("Don't know how to create Iter from arg");
-}
- */
static boolean hasTag(Object o, Object tag){
if(!(o instanceof IObj))
return false;
@@ -1357,12 +1234,6 @@ static public void print(Object x, Writer w) throws Exception{
w.write('"');
}
}
-// else if(x instanceof ArgVector)
-// {
-// w.write('|');
-// printInnerSeq(seq(x), w);
-// w.write('|');
-// }
else if(x instanceof IPersistentMap)
{
w.write('{');
@@ -1400,16 +1271,6 @@ static public void print(Object x, Writer w) throws Exception{
}
w.write('}');
}
-// else if(x instanceof Map.Entry)
-// {
-// Map.Entry e = (Map.Entry) x;
-// w.write('{');
-// print(e.getKey(),w);
-// w.write(' ');
-// print(e.getValue(),w);
-//
-// w.write('}');
-// }
else if(x instanceof Character)
{
char c = ((Character) x).charValue();