private ConstructorBuilder EmitConstructorForNonDefType(TypeBuilder fnTB, Type baseType)
{
ConstructorBuilder cb = fnTB.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, CtorTypes());
CljILGen gen = new CljILGen(cb.GetILGenerator());
GenContext.EmitDebugInfo(gen, SpanMap);
//Call base constructor
ConstructorInfo baseCtorInfo = baseType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Type.EmptyTypes, null);
if (baseCtorInfo == null)
throw new InvalidOperationException("Unable to find default constructor for " + baseType.FullName);
gen.EmitLoadArg(0);
gen.Emit(OpCodes.Call, baseCtorInfo);
// Store Meta
if (SupportsMeta)
{
gen.EmitLoadArg(0);
gen.EmitLoadArg(1);
gen.Emit(OpCodes.Castclass, typeof(IPersistentMap));
gen.EmitFieldSet(MetaField);
}
// store closed-overs in their fields
int a = 0;
int offset = !SupportsMeta ? 1 : 2;
for (ISeq s = RT.keys(Closes); s != null; s = s.next(), a++)
{
//LocalBinding lb = (LocalBinding)s.first();
FieldBuilder fb = ClosedOverFields[a];
bool isVolatile = IsVolatile(ClosedOverFieldsToBindingsMap[fb]);
gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0);
gen.EmitLoadArg(a + offset); // gen.Emit(OpCodes.Ldarg, a + 1);
gen.MaybeEmitVolatileOp(isVolatile);
gen.Emit(OpCodes.Stfld, fb);
}
gen.Emit(OpCodes.Ret);
return cb;
}