Пример #1
0
    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
    }
Пример #2
0
        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);
            }
        }
Пример #3
0
    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
    }
Пример #4
0
 public static bool findResourceInAssembly(Assembly asm, string resourceName)
 {
     if (ReflectUtil.IsDynamicAssembly(asm))
     {
         return(false);
     }
     return(asm.GetManifestResourceInfo(JVM.MangleResourceName(resourceName)) != null);
 }
Пример #5
0
        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
        }
Пример #6
0
 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);
 }
Пример #7
0
 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);
 }
Пример #8
0
        static void Main(string[] args)
        {
            //调试解析过程开关
            Switchs.DebugParse = false;
            //调试解释执行过程
            Switchs.DebugInterpret = true;
            ConsoleParam param = ReadParam.Read();
            JVM          jvm   = new JVM();

            jvm.StartJVM(param);

            Console.Read();
        }
Пример #9
0
    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));
    }
Пример #10
0
        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);
        }
Пример #11
0
    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);
    }
Пример #12
0
    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));
    }
Пример #13
0
        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);
        }
Пример #14
0
        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);
        }
Пример #15
0
        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);
        }
Пример #16
0
    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));
    }
Пример #17
0
        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();
        }
Пример #18
0
 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();
 }
Пример #19
0
    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
    }
Пример #20
0
    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
    }
Пример #21
0
        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
        }
Пример #22
0
        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);
        }
Пример #23
0
    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);
    }