internal static object AnnotationsToMap(ClassLoaderWrapper loader, object[] objAnn) { #if FIRST_PASS return(null); #else java.util.LinkedHashMap map = new java.util.LinkedHashMap(); if (objAnn != null) { foreach (object obj in objAnn) { java.lang.annotation.Annotation a = obj as java.lang.annotation.Annotation; if (a != null) { map.put(a.annotationType(), FreezeOrWrapAttribute(a)); } else if (obj is IKVM.Attributes.DynamicAnnotationAttribute) { a = (java.lang.annotation.Annotation)JVM.NewAnnotation(loader.GetJavaClassLoader(), ((IKVM.Attributes.DynamicAnnotationAttribute)obj).Definition); if (a != null) { map.put(a.annotationType(), a); } } } } return(map); #endif }
public static Stream ReadResourceFromAssemblyImpl(Assembly asm, string resource) { // chop off the leading slash resource = resource.Substring(1); string mangledName = JVM.MangleResourceName(resource); ManifestResourceInfo info = asm.GetManifestResourceInfo(mangledName); if (info != null && info.FileName != null) { return(asm.GetManifestResourceStream(mangledName)); } Stream s = asm.GetManifestResourceStream(mangledName); if (s == null) { Tracer.Warning(Tracer.ClassLoading, "Resource \"{0}\" not found in {1}", resource, asm.FullName); throw new FileNotFoundException("resource " + resource + " not found in assembly " + asm.FullName); } switch (s.ReadByte()) { case 0: Tracer.Info(Tracer.ClassLoading, "Reading resource \"{0}\" from {1}", resource, asm.FullName); return(s); case 1: Tracer.Info(Tracer.ClassLoading, "Reading compressed resource \"{0}\" from {1}", resource, asm.FullName); return(new System.IO.Compression.DeflateStream(s, System.IO.Compression.CompressionMode.Decompress, false)); default: Tracer.Error(Tracer.ClassLoading, "Resource \"{0}\" in {1} has an unsupported encoding", resource, asm.FullName); throw new IOException("Unsupported resource encoding for resource " + resource + " found in assembly " + asm.FullName); } }
static InterlockedMethods() { #if !WINRT Type type = JVM.Import(typeof(System.Threading.Interlocked)); AddInt32 = type.GetMethod("Add", new Type[] { Types.Int32.MakeByRefType(), Types.Int32 }); CompareExchangeInt32 = type.GetMethod("CompareExchange", new Type[] { Types.Int32.MakeByRefType(), Types.Int32, Types.Int32 }); CompareExchangeInt64 = type.GetMethod("CompareExchange", new Type[] { Types.Int64.MakeByRefType(), Types.Int64, Types.Int64 }); foreach (MethodInfo m in type.GetMethods()) { if (m.IsGenericMethodDefinition) { switch (m.Name) { case "CompareExchange": CompareExchangeOfT = m; break; case "Exchange": ExchangeOfT = m; break; } } } #else throw new NotImplementedException(); #endif }
public static bool findResourceInAssembly(Assembly asm, string resourceName) { if (ReflectUtil.IsDynamicAssembly(asm)) { return(false); } return(asm.GetManifestResourceInfo(JVM.MangleResourceName(resourceName)) != null); }
private static int GetObsoleteCount(MethodBase mb) { #if STUB_GENERATOR return(mb.__GetCustomAttributes(JVM.Import(typeof(ObsoleteAttribute)), false).Count); #else return(mb.GetCustomAttributes(typeof(ObsoleteAttribute), false).Length); #endif }
private static object[] GetAnnotation(CustomAttributeData cad) { if (cad.ConstructorArguments.Count == 1 && cad.ConstructorArguments[0].ArgumentType == typeof(object[]) && (cad.Constructor.DeclaringType.IsSubclassOf(JVM.Import(typeof([email protected]))) || cad.Constructor.DeclaringType == JVM.Import(typeof(DynamicAnnotationAttribute)))) { return(UnpackArray((IList <CustomAttributeTypedArgument>)cad.ConstructorArguments[0].Value)); } return(null); }
private static object[] BoxArgs(MethodWrapper mw, object[] args) { TypeWrapper[] paramTypes = mw.GetParameters(); for (int i = 0; i < paramTypes.Length; i++) { if (paramTypes[i].IsPrimitive) { args[i] = JVM.Box(args[i]); } } return(args); }
static void Main(string[] args) { //调试解析过程开关 Switchs.DebugParse = false; //调试解释执行过程 Switchs.DebugInterpret = true; ConsoleParam param = ReadParam.Read(); JVM jvm = new JVM(); jvm.StartJVM(param); Console.Read(); }
private static MethodInfo MakeCompareExchange(Type type) { MethodInfo interlockedCompareExchange = null; foreach (MethodInfo m in JVM.Import(typeof(System.Threading.Interlocked)).GetMethods()) { if (m.Name == "CompareExchange" && m.IsGenericMethodDefinition) { interlockedCompareExchange = m; break; } } return(interlockedCompareExchange.MakeGenericMethod(type)); }
public static object DynamicGetfield(object obj, string name, string sig, RuntimeTypeHandle type, string clazz, [email protected] callerID) { Profiler.Count("DynamicGetfield"); FieldWrapper fw = GetFieldWrapper(ClassLoaderWrapper.GetWrapperFromType(obj.GetType()), type, clazz, name, sig, false); java.lang.reflect.Field field = (java.lang.reflect.Field)fw.ToField(false); object val = field.get(obj, callerID); if (fw.FieldTypeWrapper.IsPrimitive) { val = JVM.Unbox(val); } return(val); }
private static Delegate ValidateDelegate(Delegate d) { #if DEBUG try { System.Runtime.CompilerServices.RuntimeHelpers.PrepareDelegate(d); } catch (Exception x) { JVM.CriticalFailure("Delegate failed to JIT", x); } #endif return(d); }
internal BootstrapBootstrapClassLoader() : base(CodeGenOptions.None, null) { TypeWrapper javaLangObject = new StubTypeWrapper(Modifiers.Public, "java.lang.Object", null, true); SetRemappedType(JVM.Import(typeof(object)), javaLangObject); SetRemappedType(JVM.Import(typeof(string)), new StubTypeWrapper(Modifiers.Public | Modifiers.Final, "java.lang.String", javaLangObject, true)); SetRemappedType(JVM.Import(typeof(Exception)), new StubTypeWrapper(Modifiers.Public, "java.lang.Throwable", javaLangObject, true)); SetRemappedType(JVM.Import(typeof(IComparable)), new StubTypeWrapper(Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.Comparable", null, true)); RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public, "java.lang.Enum", javaLangObject, false)); RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.annotation.Annotation", null, false)); RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public | Modifiers.Final, "java.lang.Class", javaLangObject, false)); }
public static object DynamicInvokevirtual(object obj, RuntimeTypeHandle type, string clazz, string name, string sig, object[] args, [email protected] callerID) { Profiler.Count("DynamicInvokevirtual"); MethodWrapper mw = GetMethodWrapper(obj, type, clazz, name, sig, false); java.lang.reflect.Method m = (java.lang.reflect.Method)mw.ToMethodOrConstructor(false); object val = m.invoke(obj, BoxArgs(mw, args), callerID); if (mw.ReturnType.IsPrimitive && mw.ReturnType != PrimitiveTypeWrapper.VOID) { val = JVM.Unbox(val); } return(val); }
public static object DynamicGetstatic(string name, string sig, RuntimeTypeHandle type, string clazz, [email protected] callerID) { Profiler.Count("DynamicGetstatic"); FieldWrapper fw = GetFieldWrapper(null, type, clazz, name, sig, true); java.lang.reflect.Field field = (java.lang.reflect.Field)fw.ToField(false); object val = field.get(null, callerID); if (fw.FieldTypeWrapper.IsPrimitive) { val = JVM.Unbox(val); } return(val); }
public static void DynamicPutstatic(object val, string name, string sig, RuntimeTypeHandle type, string clazz, [email protected] callerID) { Profiler.Count("DynamicPutstatic"); FieldWrapper fw = GetFieldWrapper(null, type, clazz, name, sig, true); if (fw.IsFinal) { throw new java.lang.IllegalAccessError("Field " + fw.DeclaringType.Name + "." + fw.Name + " is final"); } java.lang.reflect.Field field = (java.lang.reflect.Field)fw.ToField(false); if (fw.FieldTypeWrapper.IsPrimitive) { val = JVM.Box(val); } field.set(null, val, callerID); }
internal BootstrapBootstrapClassLoader() : base(CodeGenOptions.None, null) { TypeWrapper javaLangObject = new StubTypeWrapper(Modifiers.Public, "java.lang.Object", null, true); SetRemappedType(JVM.Import(typeof(object)), javaLangObject); SetRemappedType(JVM.Import(typeof(string)), new StubTypeWrapper(Modifiers.Public | Modifiers.Final, "java.lang.String", javaLangObject, true)); SetRemappedType(JVM.Import(typeof(Exception)), new StubTypeWrapper(Modifiers.Public, "java.lang.Throwable", javaLangObject, true)); SetRemappedType(JVM.Import(typeof(IComparable)), new StubTypeWrapper(Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.Comparable", null, true)); TypeWrapper tw = new StubTypeWrapper(Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.AutoCloseable", null, true); tw.SetMethods(new MethodWrapper[] { new SimpleCallMethodWrapper(tw, "close", "()V", JVM.Import(typeof(IDisposable)).GetMethod("Dispose"), PrimitiveTypeWrapper.VOID, TypeWrapper.EmptyArray, Modifiers.Public | Modifiers.Abstract, MemberFlags.None, SimpleOpCode.Callvirt, SimpleOpCode.Callvirt) }); SetRemappedType(JVM.Import(typeof(IDisposable)), tw); RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public, "java.lang.Enum", javaLangObject, false)); RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.annotation.Annotation", null, false)); RegisterInitiatingLoader(new StubTypeWrapper(Modifiers.Public | Modifiers.Final, "java.lang.Class", javaLangObject, false)); }
public override void Execute() { double a = 2; double b = 3; double c = Math.PI / 2; ImportPackage("JavaClass"); IJavaObject javaClass = JVM.New("JavaClass") as IJavaObject; IJavaObject res = (IJavaObject)javaClass.Invoke("helloWorld"); //string shall be converted because is not a native string hello = (string)res.ToPrimitive(); double result = (double)javaClass.Invoke("add", a, b); double sin = (double)javaClass.Invoke("sin", c); Console.WriteLine("{0} {1} + {2} = {3} and sin({4:0.0000000}) = {5:0.00000000}", hello, a, b, result, c, sin); Console.WriteLine("Press Enter to exit"); Console.ReadLine(); }
private static void DumpAllJavaThreads() { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); java.util.Map traces = java.lang.Thread.getAllStackTraces(); Console.WriteLine("Full thread dump IKVM.NET {0} ({1} bit):", JVM.SafeGetAssemblyVersion(Assembly.GetExecutingAssembly()), IntPtr.Size * 8); java.util.Iterator entries = traces.entrySet().iterator(); while (entries.hasNext()) { java.util.Map.Entry entry = (java.util.Map.Entry)entries.next(); java.lang.Thread thread = (java.lang.Thread)entry.getKey(); Console.WriteLine("\n\"{0}\"{1} prio={2} tid=0x{3:X8}", thread.getName(), thread.isDaemon() ? " daemon" : "", thread.getPriority(), thread.getId()); Console.WriteLine(" java.lang.Thread.State: " + thread.getState()); java.lang.StackTraceElement[] trace = (java.lang.StackTraceElement[])entry.getValue(); for (int i = 0; i < trace.Length; i++) { Console.WriteLine("\tat {0}", trace[i]); } } Console.WriteLine(); }
public static object createDelegate(MethodType newType, MethodHandle mh, int argnum, object argument) { #if FIRST_PASS return(null); #else Delegate del = (Delegate)mh.vmtarget; if (argnum == 0 && del.Target == null // we don't have to check for instance methods on a Value Type, because DirectMethodHandle can't use a direct delegate for that anyway && (!del.Method.IsStatic || !del.Method.GetParameters()[0].ParameterType.IsValueType) && !ReflectUtil.IsDynamicMethod(del.Method)) { return(Delegate.CreateDelegate(MethodHandleUtil.CreateDelegateType(newType), argument, del.Method)); } else { // slow path where we're generating a DynamicMethod if (mh.type().parameterType(argnum).isPrimitive()) { argument = JVM.Unbox(argument); } MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("BoundMethodHandle", newType, mh, argument); for (int i = 0, count = mh.type().parameterCount(), pos = 0; i < count; i++) { if (i == argnum) { dm.LoadValue(); } else { dm.Ldarg(pos++); } } dm.CallTarget(); dm.Ret(); return(dm.CreateDelegate()); } #endif }
public static object[][] getParameterAnnotationsImpl(object methodOrConstructor) { #if FIRST_PASS return(null); #else MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(methodOrConstructor); object[][] objAnn = mw.DeclaringType.GetParameterAnnotations(mw); if (objAnn == null) { return(null); } java.lang.annotation.Annotation[][] ann = new java.lang.annotation.Annotation[objAnn.Length][]; for (int i = 0; i < ann.Length; i++) { List <java.lang.annotation.Annotation> list = new List <java.lang.annotation.Annotation>(); foreach (object obj in objAnn[i]) { java.lang.annotation.Annotation a = obj as java.lang.annotation.Annotation; if (a != null) { list.Add(Java_java_lang_Class.FreezeOrWrapAttribute(a)); } else if (obj is IKVM.Attributes.DynamicAnnotationAttribute) { a = (java.lang.annotation.Annotation)JVM.NewAnnotation(mw.DeclaringType.GetClassLoader().GetJavaClassLoader(), ((IKVM.Attributes.DynamicAnnotationAttribute)obj).Definition); if (a != null) { list.Add(a); } } } ann[i] = list.ToArray(); } return(ann); #endif }
private static CustomAttributeData GetAnnotationDefault(MethodBase mb) { #if STUB_GENERATOR IList <CustomAttributeData> attr = CustomAttributeData.__GetCustomAttributes(mb, JVM.LoadType(typeof(AnnotationDefaultAttribute)), false); return(attr.Count == 1 ? attr[0] : null); #else foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(mb)) { if (cad.Constructor.DeclaringType == typeof(AnnotationDefaultAttribute)) { return(cad); } } return(null); #endif }
internal static void WriteClass(Stream stream, TypeWrapper tw, bool includeNonPublicInterfaces, bool includeNonPublicMembers, bool includeSerialVersionUID) { string name = tw.Name.Replace('.', '/'); string super = null; if (tw.IsInterface) { super = "java/lang/Object"; } else if (tw.BaseTypeWrapper != null) { super = tw.BaseTypeWrapper.Name.Replace('.', '/'); } ClassFileWriter writer = new ClassFileWriter(tw.Modifiers, name, super, 0, 49); foreach (TypeWrapper iface in tw.Interfaces) { if (iface.IsPublic || includeNonPublicInterfaces) { writer.AddInterface(iface.Name.Replace('.', '/')); } } InnerClassesAttribute innerClassesAttribute = null; if (tw.DeclaringTypeWrapper != null) { TypeWrapper outer = tw.DeclaringTypeWrapper; string innername = name; int idx = name.LastIndexOf('$'); if (idx >= 0) { innername = innername.Substring(idx + 1); } innerClassesAttribute = new InnerClassesAttribute(writer); innerClassesAttribute.Add(name, outer.Name.Replace('.', '/'), innername, (ushort)tw.ReflectiveModifiers); } foreach (TypeWrapper inner in tw.InnerClasses) { if (inner.IsPublic) { if (innerClassesAttribute == null) { innerClassesAttribute = new InnerClassesAttribute(writer); } string namePart = inner.Name; namePart = namePart.Substring(namePart.LastIndexOf('$') + 1); innerClassesAttribute.Add(inner.Name.Replace('.', '/'), name, namePart, (ushort)inner.ReflectiveModifiers); } } if (innerClassesAttribute != null) { writer.AddAttribute(innerClassesAttribute); } string genericTypeSignature = tw.GetGenericSignature(); if (genericTypeSignature != null) { writer.AddStringAttribute("Signature", genericTypeSignature); } AddAnnotations(writer, writer, tw.TypeAsBaseType); writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw)); if (tw.TypeAsBaseType.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false)) { writer.AddAttribute(new DeprecatedAttribute(writer)); } foreach (MethodWrapper mw in tw.GetMethods()) { if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected || includeNonPublicMembers)) { FieldOrMethod m; if (mw.Name == "<init>") { m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/')); CodeAttribute code = new CodeAttribute(writer); code.MaxLocals = (ushort)(mw.GetParameters().Length * 2 + 1); code.MaxStack = 3; ushort index1 = writer.AddClass("java/lang/UnsatisfiedLinkError"); ushort index2 = writer.AddString("ikvmstub generated stubs can only be used on IKVM.NET"); ushort index3 = writer.AddMethodRef("java/lang/UnsatisfiedLinkError", "<init>", "(Ljava/lang/String;)V"); code.ByteCode = new byte[] { 187, (byte)(index1 >> 8), (byte)index1, // new java/lang/UnsatisfiedLinkError 89, // dup 19, (byte)(index2 >> 8), (byte)index2, // ldc_w "..." 183, (byte)(index3 >> 8), (byte)index3, // invokespecial java/lang/UnsatisfiedLinkError/init()V 191 // athrow }; m.AddAttribute(code); } else { Modifiers mods = mw.Modifiers; if ((mods & Modifiers.Abstract) == 0) { mods |= Modifiers.Native; } m = writer.AddMethod(mods, mw.Name, mw.Signature.Replace('.', '/')); if (mw.IsOptionalAttributeAnnotationValue) { m.AddAttribute(new AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, mw.ReturnType))); } } MethodBase mb = mw.GetMethod(); if (mb != null) { ThrowsAttribute throws = AttributeHelper.GetThrows(mb); if (throws == null) { string[] throwsArray = mw.GetDeclaredExceptions(); if (throwsArray != null && throwsArray.Length > 0) { ExceptionsAttribute attrib = new ExceptionsAttribute(writer); foreach (string ex in throwsArray) { attrib.Add(ex.Replace('.', '/')); } m.AddAttribute(attrib); } } else { ExceptionsAttribute attrib = new ExceptionsAttribute(writer); if (throws.classes != null) { foreach (string ex in throws.classes) { attrib.Add(ex.Replace('.', '/')); } } if (throws.types != null) { foreach (Type ex in throws.types) { attrib.Add(ClassLoaderWrapper.GetWrapperFromType(ex).Name.Replace('.', '/')); } } m.AddAttribute(attrib); } if (mb.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false) // HACK the instancehelper methods are marked as Obsolete (to direct people toward the ikvm.extensions methods instead) // but in the Java world most of them are not deprecated (and to keep the Japi results clean we need to reflect this) && (!mb.Name.StartsWith("instancehelper_") || mb.DeclaringType.FullName != "java.lang.String" // the Java deprecated methods actually have two Obsolete attributes || GetObsoleteCount(mb) == 2)) { m.AddAttribute(new DeprecatedAttribute(writer)); } CustomAttributeData attr = GetAnnotationDefault(mb); if (attr != null) { m.AddAttribute(new AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, attr.ConstructorArguments[0]))); } } string sig = tw.GetGenericMethodSignature(mw); if (sig != null) { m.AddAttribute(writer.MakeStringAttribute("Signature", sig)); } AddAnnotations(writer, m, mw.GetMethod()); AddParameterAnnotations(writer, m, mw.GetMethod()); } } bool hasSerialVersionUID = false; foreach (FieldWrapper fw in tw.GetFields()) { if (!fw.IsHideFromReflection) { bool isSerialVersionUID = includeSerialVersionUID && fw.Name == "serialVersionUID" && fw.FieldTypeWrapper == PrimitiveTypeWrapper.LONG; hasSerialVersionUID |= isSerialVersionUID; if (fw.IsPublic || fw.IsProtected || isSerialVersionUID || includeNonPublicMembers) { object constant = null; if (fw.GetField() != null && fw.GetField().IsLiteral&& (fw.FieldTypeWrapper.IsPrimitive || fw.FieldTypeWrapper == CoreClasses.java.lang.String.Wrapper)) { constant = fw.GetField().GetRawConstantValue(); if (fw.GetField().FieldType.IsEnum) { constant = EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(fw.GetField().FieldType), constant); } } FieldOrMethod f = writer.AddField(fw.Modifiers, fw.Name, fw.Signature.Replace('.', '/'), constant); string sig = tw.GetGenericFieldSignature(fw); if (sig != null) { f.AddAttribute(writer.MakeStringAttribute("Signature", sig)); } if (fw.GetField() != null && fw.GetField().IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false)) { f.AddAttribute(new DeprecatedAttribute(writer)); } AddAnnotations(writer, f, fw.GetField()); } } } if (includeSerialVersionUID && !hasSerialVersionUID && IsSerializable(tw)) { // class is serializable but doesn't have an explicit serialVersionUID, so we add the field to record // the serialVersionUID as we see it (mainly to make the Japi reports more realistic) writer.AddField(Modifiers.Private | Modifiers.Static | Modifiers.Final, "serialVersionUID", "J", SerialVersionUID.Compute(tw)); } AddMetaAnnotations(writer, tw); writer.Write(stream); }
private static void WriteClass(TypeWrapper tw) { string name = tw.Name.Replace('.', '/'); string super = null; if (tw.IsInterface) { super = "java/lang/Object"; } else if (tw.BaseTypeWrapper != null) { super = tw.BaseTypeWrapper.Name.Replace('.', '/'); } IKVM.StubGen.ClassFileWriter writer = new IKVM.StubGen.ClassFileWriter(tw.Modifiers, name, super, 0, 49); foreach (TypeWrapper iface in tw.Interfaces) { if (iface.IsPublic) { writer.AddInterface(iface.Name.Replace('.', '/')); } } IKVM.StubGen.InnerClassesAttribute innerClassesAttribute = null; if (tw.DeclaringTypeWrapper != null) { TypeWrapper outer = tw.DeclaringTypeWrapper; string innername = name; int idx = name.LastIndexOf('$'); if (idx >= 0) { innername = innername.Substring(idx + 1); } innerClassesAttribute = new IKVM.StubGen.InnerClassesAttribute(writer); innerClassesAttribute.Add(name, outer.Name.Replace('.', '/'), innername, (ushort)tw.ReflectiveModifiers); } foreach (TypeWrapper inner in tw.InnerClasses) { if (inner.IsPublic) { if (innerClassesAttribute == null) { innerClassesAttribute = new IKVM.StubGen.InnerClassesAttribute(writer); } string namePart = inner.Name; namePart = namePart.Substring(namePart.LastIndexOf('$') + 1); innerClassesAttribute.Add(inner.Name.Replace('.', '/'), name, namePart, (ushort)inner.ReflectiveModifiers); } } if (innerClassesAttribute != null) { writer.AddAttribute(innerClassesAttribute); } string genericTypeSignature = tw.GetGenericSignature(); if (genericTypeSignature != null) { writer.AddStringAttribute("Signature", genericTypeSignature); } writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw)); if (tw.TypeAsBaseType.IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false)) { writer.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer)); } foreach (MethodWrapper mw in tw.GetMethods()) { if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected)) { IKVM.StubGen.FieldOrMethod m; if (mw.Name == "<init>") { m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/')); IKVM.StubGen.CodeAttribute code = new IKVM.StubGen.CodeAttribute(writer); code.MaxLocals = (ushort)(mw.GetParameters().Length * 2 + 1); code.MaxStack = 3; ushort index1 = writer.AddClass("java/lang/UnsatisfiedLinkError"); ushort index2 = writer.AddString("ikvmstub generated stubs can only be used on IKVM.NET"); ushort index3 = writer.AddMethodRef("java/lang/UnsatisfiedLinkError", "<init>", "(Ljava/lang/String;)V"); code.ByteCode = new byte[] { 187, (byte)(index1 >> 8), (byte)index1, // new java/lang/UnsatisfiedLinkError 89, // dup 19, (byte)(index2 >> 8), (byte)index2, // ldc_w "..." 183, (byte)(index3 >> 8), (byte)index3, // invokespecial java/lang/UnsatisfiedLinkError/init()V 191 // athrow }; m.AddAttribute(code); } else { Modifiers mods = mw.Modifiers; if ((mods & Modifiers.Abstract) == 0) { mods |= Modifiers.Native; } m = writer.AddMethod(mods, mw.Name, mw.Signature.Replace('.', '/')); if (mw.IsOptionalAttributeAnnotationValue) { m.AddAttribute(new IKVM.StubGen.AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, mw.ReturnType))); } } MethodBase mb = mw.GetMethod(); if (mb != null) { ThrowsAttribute throws = AttributeHelper.GetThrows(mb); if (throws == null) { string[] throwsArray = mw.GetDeclaredExceptions(); if (throwsArray != null && throwsArray.Length > 0) { IKVM.StubGen.ExceptionsAttribute attrib = new IKVM.StubGen.ExceptionsAttribute(writer); foreach (string ex in throwsArray) { attrib.Add(ex.Replace('.', '/')); } m.AddAttribute(attrib); } } else { IKVM.StubGen.ExceptionsAttribute attrib = new IKVM.StubGen.ExceptionsAttribute(writer); if (throws.classes != null) { foreach (string ex in throws.classes) { attrib.Add(ex.Replace('.', '/')); } } if (throws.types != null) { foreach (Type ex in throws.types) { attrib.Add(ClassLoaderWrapper.GetWrapperFromType(ex).Name.Replace('.', '/')); } } m.AddAttribute(attrib); } if (mb.IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false)) { m.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer)); } IList <CustomAttributeData> attr = CustomAttributeData.__GetCustomAttributes(mb, JVM.LoadType(typeof(AnnotationDefaultAttribute)), false); if (attr.Count == 1) { m.AddAttribute(new IKVM.StubGen.AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, attr[0].ConstructorArguments[0]))); } } string sig = tw.GetGenericMethodSignature(mw); if (sig != null) { m.AddAttribute(writer.MakeStringAttribute("Signature", sig)); } } } bool hasSerialVersionUID = false; foreach (FieldWrapper fw in tw.GetFields()) { if (!fw.IsHideFromReflection) { bool isSerialVersionUID = includeSerialVersionUID && fw.Name == "serialVersionUID" && fw.FieldTypeWrapper == PrimitiveTypeWrapper.LONG; hasSerialVersionUID |= isSerialVersionUID; if (fw.IsPublic || fw.IsProtected || isSerialVersionUID) { object constant = null; if (fw.GetField() != null && fw.GetField().IsLiteral&& (fw.FieldTypeWrapper.IsPrimitive || fw.FieldTypeWrapper == CoreClasses.java.lang.String.Wrapper)) { constant = fw.GetField().GetRawConstantValue(); if (fw.GetField().FieldType.IsEnum) { constant = EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(fw.GetField().FieldType), constant); } } IKVM.StubGen.FieldOrMethod f = writer.AddField(fw.Modifiers, fw.Name, fw.Signature.Replace('.', '/'), constant); string sig = tw.GetGenericFieldSignature(fw); if (sig != null) { f.AddAttribute(writer.MakeStringAttribute("Signature", sig)); } if (fw.GetField() != null && fw.GetField().IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false)) { f.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer)); } } } } if (includeSerialVersionUID && !hasSerialVersionUID && IsSerializable(tw)) { // class is serializable but doesn't have an explicit serialVersionUID, so we add the field to record // the serialVersionUID as we see it (mainly to make the Japi reports more realistic) writer.AddField(Modifiers.Private | Modifiers.Static | Modifiers.Final, "serialVersionUID", "J", IKVM.StubGen.SerialVersionUID.Compute(tw)); } AddMetaAnnotations(writer, tw); zipCount++; MemoryStream mem = new MemoryStream(); writer.Write(mem); ZipEntry entry = new ZipEntry(name + ".class"); entry.Size = mem.Position; zipFile.PutNextEntry(entry); mem.WriteTo(zipFile); }