// // create default parameterless constructor. (it will be called at the // top of any method which allocates a value type local.) and note that // if this is a generic value type, this new constructor will be further // modified in GenericUtil.MakeGenericClass.FixConstructorsInFrom // static void CreateDefaultConstructor(JavaClass valueClass, CilType fromType, int numCastableInterfaces, bool initFields) { foreach (var oldMethod in valueClass.Methods) { if (oldMethod.Name == "<init>") { return; } } var code = CilMethod.CreateConstructor(valueClass, fromType.GenericParametersCount, true); if (fromType.HasGenericParameters) { code.StackMap = new JavaStackMap(); var genericMark = CilMain.GenericStack.Mark(); CilMain.GenericStack.EnterMethod(fromType, code.Method, true); // initialize the generic type field GenericUtil.InitializeTypeField(fromType, code); CilMain.GenericStack.Release(genericMark); code.MaxStack = code.StackMap.GetMaxStackSize(CilMain.Where); } // init the array of generic interfaces InterfaceBuilder.InitInterfaceArrayField( fromType, numCastableInterfaces, code, 0); if (initFields) { var oldLabel = code.SetLabel(0xFFFF); InitializeInstanceFields(valueClass, fromType, null, code); code.SetLabel(oldLabel); } code.NewInstruction(0x19 /* aload */, null, (int)0); code.NewInstruction(0xB7 /* invokespecial */, new JavaType(0, 0, valueClass.Super), new JavaMethodRef("<init>", JavaType.VoidType)); code.MaxStack = code.StackMap.GetMaxStackSize(CilMain.Where); if (code.MaxStack < 1) { code.MaxStack = 1; } code.NewInstruction(JavaType.VoidType.ReturnOpcode, null, null); }
void InsertMethodInitCode() { if (method.IsStatic) { if ((!method.IsConstructor) && method.DeclType.HasGenericParameters) { // in a static method in a generic class, if the class has // a static initializer, then we want to start with a call to // GetType(), to force initialization of the static data class foreach (var m in defMethod.DeclaringType.Methods) { if (m.IsConstructor && m.IsStatic) { GenericUtil.LoadMaybeGeneric(method.DeclType, code); code.NewInstruction(0x57 /* pop */, null, null); code.StackMap.PopStack(CilMain.Where); break; } } } } else if (method.IsConstructor) { if (method.DeclType.HasGenericParameters) { // in a constructor of a generic class, we want to start // with a call to GetType() and store the result in the // $type field GenericUtil.InitializeTypeField(method.DeclType, code); } // init the array of generic interfaces InterfaceBuilder.InitInterfaceArrayField( method.DeclType, numCastableInterfaces, code, 0); // in any constructor, we want to allocate boxed instance fields ValueUtil.InitializeInstanceFields(newMethod.Class, method.DeclType, defMethodBody.Instructions, code); } }