internal TypeWrapper DoLoad(string name) { TypeWrapper tw = assemblyLoader.DoLoad(name); if (tw != null) { return(RegisterInitiatingLoader(tw)); } LazyInitExports(); if (exports != null) { List <int> assemblies; if (exports.TryGetValue(JVM.PersistableHash(name), out assemblies)) { foreach (int index in assemblies) { AssemblyLoader loader = TryGetLoaderByIndex(index); if (loader != null) { tw = loader.DoLoad(name); if (tw != null) { return(RegisterInitiatingLoader(tw)); } } } } } return(null); }
internal virtual TypeWrapper GetWrapperFromAssemblyType(Type type) { //Tracer.Info(Tracer.Runtime, "GetWrapperFromAssemblyType: {0}", type.FullName); Debug.Assert(!type.Name.EndsWith("[]"), "!type.IsArray", type.FullName); Debug.Assert(AssemblyClassLoader.FromAssembly(type.Assembly) == this); TypeWrapper wrapper = GetLoader(type.Assembly).CreateWrapperForAssemblyType(type); if (wrapper != null) { if (type.IsGenericType && !type.IsGenericTypeDefinition) { // in the case of "magic" implementation generic type instances we'll end up here as well, // but then wrapper.GetClassLoader() will return this anyway wrapper = wrapper.GetClassLoader().RegisterInitiatingLoader(wrapper); } else { wrapper = RegisterInitiatingLoader(wrapper); } if (wrapper.TypeAsTBD != type && (!wrapper.IsRemapped || wrapper.TypeAsBaseType != type)) { // this really shouldn't happen, it means that we have two different types in our assembly that both // have the same Java name #if STATIC_COMPILER throw new FatalCompilerErrorException(Message.AssemblyContainsDuplicateClassNames, type.FullName, wrapper.TypeAsTBD.FullName, wrapper.Name, type.Assembly.FullName); #else string msg = String.Format("\nType \"{0}\" and \"{1}\" both map to the same name \"{2}\".\n", type.FullName, wrapper.TypeAsTBD.FullName, wrapper.Name); JVM.CriticalFailure(msg, null); #endif } return(wrapper); } return(null); }
internal static void LoadRemappedTypes() { // if we're compiling the core, coreAssembly will be null Assembly coreAssembly = JVM.CoreAssembly; if (coreAssembly != null) { try { Tracer.Info(Tracer.Runtime, "Core assembly: {0}", coreAssembly.Location); } catch (System.Security.SecurityException) { } RemappedClassAttribute[] remapped = AttributeHelper.GetRemappedClasses(coreAssembly); if (remapped.Length > 0) { foreach (RemappedClassAttribute r in remapped) { Tracer.Info(Tracer.Runtime, "Remapping type {0} to {1}", r.RemappedType, r.Name); remappedTypes.Add(r.RemappedType, r.Name); } } else { JVM.CriticalFailure("Failed to find core classes in core library", null); } } }
internal static void AddGetObjectData(TypeBuilder tb) { string name = tb.IsSealed ? "System.Runtime.Serialization.ISerializable.GetObjectData" : "GetObjectData"; MethodAttributes attr = tb.IsSealed ? MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final : MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; tb.AddInterfaceImplementation(JVM.Import(typeof(ISerializable))); MethodBuilder getObjectData = tb.DefineMethod(name, attr, null, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) }); getObjectData.SetCustomAttribute(securityCriticalAttribute); AttributeHelper.HideFromJava(getObjectData); //TODO: We need to review this for .NET Core //getObjectData.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter); tb.DefineMethodOverride(getObjectData, JVM.Import(typeof(ISerializable)).GetMethod("GetObjectData")); CodeEmitter ilgen = CodeEmitter.Create(getObjectData); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); TypeWrapper serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization"); MethodWrapper mw = serializationHelper.GetMethodWrapper("writeObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false); mw.Link(); mw.EmitCall(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); }
private static void AddReadResolve(DynamicTypeWrapper wrapper, TypeBuilder tb) { MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false); if (mw != null && !wrapper.IsSubTypeOf(iobjectreference)) { tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference))); MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) }); getRealObject.SetCustomAttribute(securityCriticalAttribute); AttributeHelper.HideFromJava(getRealObject); tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject")); CodeEmitter ilgen = CodeEmitter.Create(getRealObject); mw.Link(); if (!wrapper.IsFinal) { // readResolve is only applicable if it exists on the actual type of the object, so if we're a subclass don't call it ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod); ilgen.Emit(OpCodes.Ldtoken, wrapper.TypeAsBaseType); ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod); CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Beq_S, label); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(label); } ilgen.Emit(OpCodes.Ldarg_0); mw.EmitCall(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } }
private static ConstructorBuilder DefineThreadLocalType(DynamicTypeWrapper.FinishContext context, int opcodeIndex, MethodWrapper caller) { TypeWrapper threadLocal = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicThreadLocal"); TypeBuilder tb = caller.DeclaringType.TypeAsBuilder.DefineNestedType("__<tls>_" + opcodeIndex, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, threadLocal.TypeAsBaseType); FieldBuilder fb = tb.DefineField("field", Types.Object, FieldAttributes.Private | FieldAttributes.Static); fb.SetCustomAttribute(new CustomAttributeBuilder(JVM.Import(typeof(ThreadStaticAttribute)).GetConstructor(Type.EmptyTypes), new object[0])); MethodBuilder mbGet = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, Types.Object, Type.EmptyTypes); ILGenerator ilgen = mbGet.GetILGenerator(); ilgen.Emit(OpCodes.Ldsfld, fb); ilgen.Emit(OpCodes.Ret); MethodBuilder mbSet = tb.DefineMethod("set", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, null, new Type[] { Types.Object }); ilgen = mbSet.GetILGenerator(); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Stsfld, fb); ilgen.Emit(OpCodes.Ret); ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes); CodeEmitter ctorilgen = CodeEmitter.Create(cb); ctorilgen.Emit(OpCodes.Ldarg_0); MethodWrapper basector = threadLocal.GetMethodWrapper("<init>", "()V", false); basector.Link(); basector.EmitCall(ctorilgen); ctorilgen.Emit(OpCodes.Ret); ctorilgen.DoEmit(); context.RegisterPostFinishProc(delegate { threadLocal.Finish(); tb.CreateType(); }); return(cb); }
private static void EmitLoadCharArrayLiteral(CodeEmitter ilgen, string str, TypeWrapper tw) { ModuleBuilder mod = tw.GetClassLoader().GetTypeWrapperFactory().ModuleBuilder; // FXBUG on .NET 1.1 & 2.0 the value type that Ref.Emit automatically generates is public, // so we pre-create a non-public type with the right name here and it will "magically" use // that instead. // If we're running on Mono this isn't necessary, but for simplicitly we'll simply create // the type as well (it is useless, but all it does is waste a little space). int length = str.Length * 2; string typename = "$ArrayType$" + length; Type type = mod.GetType(typename, false, false); if (type == null) { if (tw.GetClassLoader().GetTypeWrapperFactory().ReserveName(typename)) { TypeBuilder tb = mod.DefineType(typename, TypeAttributes.Sealed | TypeAttributes.Class | TypeAttributes.ExplicitLayout | TypeAttributes.NotPublic, Types.ValueType, PackingSize.Size1, length); AttributeHelper.HideFromJava(tb); type = tb.CreateType(); } } if (type == null || !type.IsValueType || type.StructLayoutAttribute.Pack != 1 || type.StructLayoutAttribute.Size != length) { // the type that we found doesn't match (must mean we've compiled a Java type with that name), // so we fall back to the string approach ilgen.Emit(OpCodes.Ldstr, str); ilgen.Emit(OpCodes.Call, Types.String.GetMethod("ToCharArray", Type.EmptyTypes)); return; } ilgen.Emit(OpCodes.Ldc_I4, str.Length); ilgen.Emit(OpCodes.Newarr, Types.Char); ilgen.Emit(OpCodes.Dup); byte[] data = new byte[length]; for (int j = 0; j < str.Length; j++) { data[j * 2 + 0] = (byte)(str[j] >> 0); data[j * 2 + 1] = (byte)(str[j] >> 8); } // NOTE we define a module field, because type fields on Mono don't use the global $ArrayType$<n> type. // NOTE this also means that this will only work during static compilation, because ModuleBuilder.CreateGlobalFunctions() must // be called before the field can be used. FieldBuilder fb = mod.DefineInitializedData("__<str>", data, FieldAttributes.Static | FieldAttributes.PrivateScope); // MONOBUG Type.Equals(Type) is broken on Mono. We have to use the virtual method that ends up in our implementation if (!fb.FieldType.Equals((object)type)) { // this is actually relatively harmless, but I would like to know about it, so we abort and hope that users report this when they encounter it JVM.CriticalFailure("Unsupported runtime: ModuleBuilder.DefineInitializedData() field type mispredicted", null); } ilgen.Emit(OpCodes.Ldtoken, fb); ilgen.Emit(OpCodes.Call, JVM.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers)).GetMethod("InitializeArray", new Type[] { Types.Array, JVM.Import(typeof(RuntimeFieldHandle)) })); }
internal static TypeWrapper LoadClassCritical(string name) { try { return(GetBootstrapClassLoader().LoadClassByDottedName(name)); } catch (Exception x) { JVM.CriticalFailure("Loading of critical class failed", x); return(null); } }
internal Assembly FindResourceAssembliesImpl(string unmangledName, string name, bool firstOnly, ref List <Assembly> list) { if (ReflectUtil.IsDynamicAssembly(assemblyLoader.Assembly)) { return(null); } if (assemblyLoader.Assembly.GetManifestResourceInfo(name) != null) { if (firstOnly) { return(assemblyLoader.Assembly); } list = new List <Assembly>(); list.Add(assemblyLoader.Assembly); } LazyInitExports(); if (exports != null) { List <int> assemblies; if (exports.TryGetValue(JVM.PersistableHash(unmangledName), out assemblies)) { foreach (int index in assemblies) { AssemblyLoader loader = exportedAssemblies[index]; if (loader == null) { Assembly asm = LoadAssemblyOrClearName(ref exportedAssemblyNames[index], true); if (asm == null) { continue; } loader = exportedAssemblies[index] = GetLoaderForExportedAssembly(asm); } if (loader.Assembly.GetManifestResourceInfo(name) != null) { if (firstOnly) { return(loader.Assembly); } if (list == null) { list = new List <Assembly>(); } list.Add(loader.Assembly); } } } } return(null); }
private static void RemoveReadResolve(TypeBuilder tb) { tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference))); MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) }); getRealObject.SetCustomAttribute(securityCriticalAttribute); AttributeHelper.HideFromJava(getRealObject); tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject")); CodeEmitter ilgen = CodeEmitter.Create(getRealObject); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); }
internal AssemblyLoader(Assembly assembly) { this.assembly = assembly; modules = assembly.GetModules(false); isJavaModule = new bool[modules.Length]; for (int i = 0; i < modules.Length; i++) { object[] attr; try { attr = AttributeHelper.GetJavaModuleAttributes(modules[i]); } catch (Exception x) { // HACK we handle exceptions here, because there is at least one obfuscator that produces // invalid assemblies that cause Module.GetCustomAttributes() to throw an exception JVM.CriticalFailure("Unexpected exception", x); throw null; } if (attr.Length > 0) { isJavaModule[i] = true; foreach (JavaModuleAttribute jma in attr) { string[] map = jma.GetClassMap(); if (map != null) { if (nameMap == null) { nameMap = new Dictionary <string, string>(); } for (int j = 0; j < map.Length; j += 2) { string key = map[j]; string val = map[j + 1]; // TODO if there is a name clash between modules, this will throw. // Figure out how to handle that. nameMap.Add(key, val); } } } } else { hasDotNetModule = true; } } }
private static bool CallerID_getCallerID(EmitIntrinsicContext eic) { if (eic.Caller.HasCallerID) { int arg = eic.Caller.GetParametersForDefineMethod().Length - 1; if (!eic.Caller.IsStatic) { arg++; } eic.Emitter.Emit(OpCodes.Ldarg, (short)arg); return(true); } else { JVM.CriticalFailure("CallerID.getCallerID() requires a HasCallerID annotation", null); } return(false); }
private static bool CallerID_getCallerID(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags) { if (caller.HasCallerID) { int arg = caller.GetParametersForDefineMethod().Length - 1; if (!caller.IsStatic) { arg++; } ilgen.Emit(OpCodes.Ldarg, (short)arg); return(true); } else { JVM.CriticalFailure("CallerID.getCallerID() requires a HasCallerID annotation", null); } return(false); }
private static void AddReadResolve(TypeWrapper wrapper) { MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false); if (mw != null && !wrapper.IsSubTypeOf(iobjectreference)) { TypeBuilder tb = wrapper.TypeAsBuilder; tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference))); MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) }); getRealObject.SetCustomAttribute(securityCriticalAttribute); AttributeHelper.HideFromJava(getRealObject); tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject")); CodeEmitter ilgen = CodeEmitter.Create(getRealObject); mw.Link(); ilgen.Emit(OpCodes.Ldarg_0); mw.EmitCall(ilgen); ilgen.Emit(OpCodes.Ret); } }
internal static void LoadRemappedTypes() { // if we're compiling the core, coreAssembly will be null Assembly coreAssembly = JVM.CoreAssembly; if (coreAssembly != null && remappedTypes.Count == 0) { RemappedClassAttribute[] remapped = AttributeHelper.GetRemappedClasses(coreAssembly); if (remapped.Length > 0) { foreach (RemappedClassAttribute r in remapped) { remappedTypes.Add(r.RemappedType, r.Name); } } else { JVM.CriticalFailure("Failed to find core classes in core library", null); } } }
private static bool CallerID_getCallerID(EmitIntrinsicContext eic) { if (eic.Caller.HasCallerID) { int arg = eic.Caller.GetParametersForDefineMethod().Length - 1; if (!eic.Caller.IsStatic) { arg++; } eic.Emitter.Emit(OpCodes.Ldarg, (short)arg); return(true); } else { #if STATIC_COMPILER throw new FatalCompilerErrorException(Message.CallerIDRequiresHasCallerIDAnnotation); #else JVM.CriticalFailure("CallerID.getCallerID() requires a HasCallerID annotation", null); return(false); #endif } }
private static void AddGetObjectData(TypeWrapper wrapper) { TypeBuilder tb = wrapper.TypeAsBuilder; tb.AddInterfaceImplementation(JVM.Import(typeof(ISerializable))); MethodBuilder getObjectData = tb.DefineMethod("GetObjectData", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot, null, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) }); getObjectData.SetCustomAttribute(securityCriticalAttribute); AttributeHelper.HideFromJava(getObjectData); getObjectData.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter); tb.DefineMethodOverride(getObjectData, JVM.Import(typeof(ISerializable)).GetMethod("GetObjectData")); CodeEmitter ilgen = CodeEmitter.Create(getObjectData); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); TypeWrapper serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization"); MethodWrapper mw = serializationHelper.GetMethodWrapper("writeObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false); mw.Link(); mw.EmitCall(ilgen); ilgen.Emit(OpCodes.Ret); }
internal TypeWrapper DoLoad(string name) { TypeWrapper tw = assemblyLoader.DoLoad(name); if (tw != null) { return(RegisterInitiatingLoader(tw)); } LazyInitExports(); if (exports != null) { List <int> assemblies; if (exports.TryGetValue(JVM.PersistableHash(name), out assemblies)) { foreach (int index in assemblies) { AssemblyLoader loader = exportedAssemblies[index]; if (loader == null) { Assembly asm = LoadAssemblyOrClearName(ref exportedAssemblyNames[index], true); if (asm == null) { continue; } loader = exportedAssemblies[index] = GetLoaderForExportedAssembly(asm); } tw = loader.DoLoad(name); if (tw != null) { return(RegisterInitiatingLoader(tw)); } } } } return(null); }
private static MethodBuilder AddConstructor(TypeBuilder tb, MethodWrapper defaultConstructor, MethodBase serializationConstructor, bool callReadObject) { MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Family, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) }); AttributeHelper.HideFromJava(ctor); CodeEmitter ilgen = CodeEmitter.Create(ctor); ilgen.Emit(OpCodes.Ldarg_0); if (defaultConstructor != null) { defaultConstructor.EmitCall(ilgen); } else { ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldarg_2); ilgen.Emit(OpCodes.Call, serializationConstructor); } if (callReadObject) { ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); TypeWrapper serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization"); MethodWrapper mw = serializationHelper.GetMethodWrapper("readObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false); mw.Link(); mw.EmitCall(ilgen); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); return(ctor); }
internal Assembly[] FindResourceAssemblies(string unmangledName, bool firstOnly) { List <Assembly> list = null; string name = JVM.MangleResourceName(unmangledName); Assembly first = FindResourceAssembliesImpl(unmangledName, name, firstOnly, ref list); if (first != null) { return(new Assembly[] { first }); } LazyInitExports(); for (int i = 0; i < delegates.Length; i++) { if (delegates[i] == null) { Assembly asm = LoadAssemblyOrClearName(ref references[i], false); if (asm != null) { delegates[i] = AssemblyClassLoader.FromAssembly(asm); } } if (delegates[i] != null) { first = delegates[i].FindResourceAssembliesImpl(unmangledName, name, firstOnly, ref list); if (first != null) { return(new Assembly[] { first }); } } } if (!assemblyLoader.HasJavaModule) { if (firstOnly) { return(GetBootstrapClassLoader().FindResourceAssemblies(unmangledName, firstOnly)); } else { Assembly[] assemblies = GetBootstrapClassLoader().FindResourceAssemblies(unmangledName, firstOnly); if (assemblies != null) { foreach (Assembly asm in assemblies) { if (list == null) { list = new List <Assembly>(); } if (!list.Contains(asm)) { list.Add(asm); } } } } } if (list == null) { return(null); } return(list.ToArray()); }
private IEnumerable <java.net.URL> GetResourcesImpl(string unmangledName, bool getFromDelegates) { if (ReflectUtil.IsDynamicAssembly(assemblyLoader.Assembly)) { yield break; } #if !FIRST_PASS java.util.Enumeration urls = assemblyLoader.FindResources(unmangledName); while (urls.hasMoreElements()) { yield return((java.net.URL)urls.nextElement()); } #endif string name = JVM.MangleResourceName(unmangledName); if (assemblyLoader.Assembly.GetManifestResourceInfo(name) != null) { yield return(MakeResourceURL(assemblyLoader.Assembly, name)); } LazyInitExports(); if (exports != null) { List <int> assemblies; if (exports.TryGetValue(JVM.PersistableHash(unmangledName), out assemblies)) { foreach (int index in assemblies) { AssemblyLoader loader = exportedAssemblies[index]; if (loader == null) { Assembly asm = LoadAssemblyOrClearName(ref exportedAssemblyNames[index], true); if (asm == null) { continue; } loader = exportedAssemblies[index] = GetLoaderForExportedAssembly(asm); } #if !FIRST_PASS urls = loader.FindResources(unmangledName); while (urls.hasMoreElements()) { yield return((java.net.URL)urls.nextElement()); } #endif if (loader.Assembly.GetManifestResourceInfo(name) != null) { yield return(MakeResourceURL(loader.Assembly, name)); } } } } if (!getFromDelegates) { yield break; } for (int i = 0; i < delegates.Length; i++) { if (delegates[i] == null) { Assembly asm = LoadAssemblyOrClearName(ref references[i], false); if (asm != null) { delegates[i] = AssemblyClassLoader.FromAssembly(asm); } } if (delegates[i] != null) { foreach (java.net.URL url in delegates[i].FindResources(unmangledName)) { yield return(url); } } } if (!assemblyLoader.HasJavaModule) { foreach (java.net.URL url in GetBootstrapClassLoader().FindResources(unmangledName)) { yield return(url); } } }
private static ConstructorInfo AddConstructor(TypeBuilder tb, MethodWrapper defaultConstructor, ConstructorInfo serializationConstructor, bool callReadObject) { ConstructorBuilder ctor = tb.DefineConstructor(MethodAttributes.Family, CallingConventions.Standard, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) }); AttributeHelper.HideFromJava(ctor); ctor.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter); CodeEmitter ilgen = CodeEmitter.Create(ctor); ilgen.Emit(OpCodes.Ldarg_0); if (defaultConstructor != null) { defaultConstructor.EmitCall(ilgen); } else { ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldarg_2); ilgen.Emit(OpCodes.Call, serializationConstructor); } if (callReadObject) { ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); TypeWrapper serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization"); MethodWrapper mw = serializationHelper.GetMethodWrapper("readObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false); mw.Link(); mw.EmitCall(ilgen); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); return(ctor); }