ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor cv = cw;
cv.visit(V1_5, ACC_PUBLIC + ACC_SUPER, objx.internalName, null, "java/lang/Object", null);
//static load method
GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
Method.getMethod("void load ()"),
null,
null,
cv);
gen.visitCode();
for(Object r = LispReader.read(pushbackReader, false, EOF, false); r != EOF;
r = LispReader.read(pushbackReader, false, EOF, false))
{
LINE_AFTER.set(pushbackReader.getLineNumber());
compile1(gen, objx, r);
LINE_BEFORE.set(pushbackReader.getLineNumber());
}
//end of load
gen.returnValue();
gen.endMethod();
//static fields for constants
for(int i = 0; i < objx.constants.count(); i++)
{
cv.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, objx.constantName(i), objx.constantType(i).getDescriptor(),
null, null);
}
final int INITS_PER = 100;
int numInits = objx.constants.count() / INITS_PER;
if(objx.constants.count() % INITS_PER != 0)
++numInits;
for(int n = 0;n<numInits;n++)
{
GeneratorAdapter clinitgen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
Method.getMethod("void __init" + n + "()"),
null,
null,
cv);
clinitgen.visitCode();
try
{
Var.pushThreadBindings(RT.map(RT.PRINT_DUP, RT.T));
for(int i = n*INITS_PER; i < objx.constants.count() && i < (n+1)*INITS_PER; i++)
{
objx.emitValue(objx.constants.nth(i), clinitgen);
clinitgen.checkCast(objx.constantType(i));
clinitgen.putStatic(objx.objtype, objx.constantName(i), objx.constantType(i));
}
}
finally
{
Var.popThreadBindings();
}
clinitgen.returnValue();
clinitgen.endMethod();
}
//static init for constants, keywords and vars
GeneratorAdapter clinitgen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
Method.getMethod("void <clinit> ()"),
null,
null,
cv);
clinitgen.visitCode();
Label startTry = clinitgen.newLabel();
Label endTry = clinitgen.newLabel();
Label end = clinitgen.newLabel();
Label finallyLabel = clinitgen.newLabel();
// if(objx.constants.count() > 0)
// {
// objx.emitConstants(clinitgen);
// }
for(int n = 0;n<numInits;n++)
clinitgen.invokeStatic(objx.objtype, Method.getMethod("void __init" + n + "()"));
clinitgen.push(objx.internalName.replace('/','.'));
clinitgen.invokeStatic(CLASS_TYPE, Method.getMethod("Class forName(String)"));
clinitgen.invokeVirtual(CLASS_TYPE,Method.getMethod("ClassLoader getClassLoader()"));
clinitgen.invokeStatic(Type.getType(Compiler.class), Method.getMethod("void pushNSandLoader(ClassLoader)"));
clinitgen.mark(startTry);
clinitgen.invokeStatic(objx.objtype, Method.getMethod("void load()"));
clinitgen.mark(endTry);
clinitgen.invokeStatic(VAR_TYPE, Method.getMethod("void popThreadBindings()"));
clinitgen.goTo(end);
clinitgen.mark(finallyLabel);
//exception should be on stack
clinitgen.invokeStatic(VAR_TYPE, Method.getMethod("void popThreadBindings()"));
clinitgen.throwException();
clinitgen.mark(end);
clinitgen.visitTryCatchBlock(startTry, endTry, finallyLabel, null);
//end of static init
clinitgen.returnValue();
clinitgen.endMethod();
//end of class
cv.visitEnd();
writeClassFile(objx.internalName, cw.toByteArray());