cv.visitField(ACC_PRIVATE, cachedProtoFnName(i), AFUNCTION_TYPE.getDescriptor(), null, null);
cv.visitField(ACC_PRIVATE, cachedProtoImplName(i), IFN_TYPE.getDescriptor(), null, null);
}
//ctor that takes closed-overs and inits base + fields
Method m = new Method("<init>", Type.VOID_TYPE, ctorTypes());
GeneratorAdapter ctorgen = new GeneratorAdapter(ACC_PUBLIC,
m,
null,
null,
cv);
Label start = ctorgen.newLabel();
Label end = ctorgen.newLabel();
ctorgen.visitCode();
ctorgen.visitLineNumber(line, ctorgen.mark());
ctorgen.visitLabel(start);
ctorgen.loadThis();
// if(superName != null)
ctorgen.invokeConstructor(Type.getObjectType(superName), voidctor);
// else if(isVariadic()) //RestFn ctor takes reqArity arg
// {
// ctorgen.push(variadicMethod.reqParms.count());
// ctorgen.invokeConstructor(restFnType, restfnctor);
// }
// else
// ctorgen.invokeConstructor(aFnType, voidctor);
if(!isDeftype())
{
ctorgen.loadThis();
ctorgen.visitVarInsn(IPERSISTENTMAP_TYPE.getOpcode(Opcodes.ILOAD), 1);
ctorgen.putField(objtype, "__meta", IPERSISTENTMAP_TYPE);
}
int a = isDeftype()?1:2;
for(ISeq s = RT.keys(closes); s != null; s = s.next(), ++a)
{
LocalBinding lb = (LocalBinding) s.first();
ctorgen.loadThis();
Class primc = lb.getPrimitiveType();
if(primc != null)
{
ctorgen.visitVarInsn(Type.getType(primc).getOpcode(Opcodes.ILOAD), a);
ctorgen.putField(objtype, lb.name, Type.getType(primc));
if(primc == Long.TYPE || primc == Double.TYPE)
++a;
}
else
{
ctorgen.visitVarInsn(OBJECT_TYPE.getOpcode(Opcodes.ILOAD), a);
ctorgen.putField(objtype, lb.name, OBJECT_TYPE);
}
closesExprs = closesExprs.cons(new LocalBindingExpr(lb, null));
}
ctorgen.visitLabel(end);
ctorgen.returnValue();
ctorgen.endMethod();
if(altCtorDrops > 0)
{
//ctor that takes closed-overs and inits base + fields
Type[] ctorTypes = ctorTypes();
Type[] altCtorTypes = new Type[ctorTypes.length-altCtorDrops];
for(int i=0;i<altCtorTypes.length;i++)
altCtorTypes[i] = ctorTypes[i];
Method alt = new Method("<init>", Type.VOID_TYPE, altCtorTypes);
ctorgen = new GeneratorAdapter(ACC_PUBLIC,
alt,
null,
null,
cv);
ctorgen.visitCode();
ctorgen.loadThis();
ctorgen.loadArgs();
for(int i=0;i<altCtorDrops;i++)
ctorgen.visitInsn(Opcodes.ACONST_NULL);
ctorgen.invokeConstructor(objtype, new Method("<init>", Type.VOID_TYPE, ctorTypes));
ctorgen.returnValue();
ctorgen.endMethod();
}
if(!isDeftype())
{
//ctor that takes closed-overs but not meta
Type[] ctorTypes = ctorTypes();
Type[] noMetaCtorTypes = new Type[ctorTypes.length-1];
for(int i=1;i<ctorTypes.length;i++)
noMetaCtorTypes[i-1] = ctorTypes[i];
Method alt = new Method("<init>", Type.VOID_TYPE, noMetaCtorTypes);
ctorgen = new GeneratorAdapter(ACC_PUBLIC,
alt,
null,
null,
cv);
ctorgen.visitCode();
ctorgen.loadThis();
ctorgen.visitInsn(Opcodes.ACONST_NULL); //null meta
ctorgen.loadArgs();
ctorgen.invokeConstructor(objtype, new Method("<init>", Type.VOID_TYPE, ctorTypes));
ctorgen.returnValue();
ctorgen.endMethod();
//meta()
Method meth = Method.getMethod("clojure.lang.IPersistentMap meta()");
GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC,
meth,
null,
null,
cv);
gen.visitCode();
gen.loadThis();
gen.getField(objtype,"__meta",IPERSISTENTMAP_TYPE);
gen.returnValue();
gen.endMethod();
//withMeta()
meth = Method.getMethod("clojure.lang.IObj withMeta(clojure.lang.IPersistentMap)");
gen = new GeneratorAdapter(ACC_PUBLIC,
meth,
null,
null,
cv);
gen.visitCode();
gen.newInstance(objtype);
gen.dup();
gen.loadArg(0);
for(ISeq s = RT.keys(closes); s != null; s = s.next(), ++a)
{
LocalBinding lb = (LocalBinding) s.first();
gen.loadThis();
Class primc = lb.getPrimitiveType();
if(primc != null)
{
gen.getField(objtype, lb.name, Type.getType(primc));
}
else
{
gen.getField(objtype, lb.name, OBJECT_TYPE);
}
}
gen.invokeConstructor(objtype, new Method("<init>", Type.VOID_TYPE, ctorTypes));
gen.returnValue();
gen.endMethod();
}
emitMethods(cv);
if(keywordCallsites.count() > 0)
{
Method meth = Method.getMethod("void swapThunk(int,clojure.lang.ILookupThunk)");
GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC,
meth,
null,
null,