Ejemplo n.º 1
0
        private void CompileDelegateCtor(InterType type)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            result.Name        = ClassNames.JavaConstructorMethodName;

            string methodPointerType;

            if (Program.MethodPointersType == MethodPointerImplementation.Fast)
            {
                methodPointerType = ((INamesController)this).GetMethodPointerInterface(
                    type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault());

                methodPointerType = "L" + TypeNameToJava(methodPointerType) + ";";
            }
            else
            {
                methodPointerType = Program.AsX64 ? "J" : "I";
            }

            result.Descriptor = "(L" + TypeNameToJava(ClassNames.JavaObject) + ";" + methodPointerType + ")V";

            MethodRef baseInitRef = new MethodRef(currentJavaClass.SuperClass, ClassNames.JavaConstructorMethodName,
                                                  "(L" + TypeNameToJava(ClassNames.JavaObject) + ";L" + TypeNameToJava(ClassNames.JavaObject) + ";)V");

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            codeWriter
            .Add(OpCodes.aload_0)
            .Add(OpCodes.aload_1);

            if (Program.MethodPointersType == MethodPointerImplementation.Fast)
            {
                codeWriter.Add(OpCodes.aload_2);
            }
            else
            {
                codeWriter
                .Add(Program.AsX64 ? OpCodes.lload_2 : OpCodes.iload_2)
                .Add(OpCodes.invokestatic, Program.AsX64 ? ClassNames.JavaLongBox : ClassNames.JavaIntegerBox);
            }

            result.Attributes.Add(codeWriter
                                  .Add(OpCodes.invokespecial, baseInitRef)
                                  .Add(OpCodes._return)
                                  .End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }
Ejemplo n.º 2
0
        private void GenerateBaseByRefType(JavaPrimitiveType type)
        {
            if ((baseTypesGenerated & (1 << (int)type)) != 0)
            {
                return;
            }

            Java.Class javaClass = new Java.Class();
            javaClass.AccessFlag = Java.ClassAccessFlag.Abstract | Java.ClassAccessFlag.Public | Java.ClassAccessFlag.Super;
            javaClass.ThisClass  = TypeNameToJava(new JavaByRefType(ByRefPlace.Unknown, type).ToString());
            javaClass.SuperClass = TypeNameToJava(ClassNames.JavaObject);

            Java.Method ctor = new Java.Method();
            ctor.AccessFlags = Java.MethodAccessFlags.Public;
            ctor.Name        = ClassNames.JavaConstructorMethodName;
            ctor.Descriptor  = "()V";

            JavaBytecodeWriter ctorCodeGenerator = new JavaBytecodeWriter();

            ctorCodeGenerator
            .AddLocalVarInstruction(LocalVarInstruction.Load, JavaPrimitiveType.Ref, 0, null)
            .AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef))
            .AddReturn(JavaPrimitiveType.Void, null);
            Java.Attributes.Code ctorCode = new Java.Attributes.Code();
            ctorCode.CodeBytes = ctorCodeGenerator.Link(javaClass.ConstantPool);
            ctorCode.MaxLocals = 1;
            ctorCode.MaxStack  = 1;
            ctor.Attributes.Add(ctorCode);
            javaClass.Methods.Add(ctor);

            Java.Method getValue = new Java.Method();
            getValue.AccessFlags = Java.MethodAccessFlags.Abstract | Java.MethodAccessFlags.Public;
            getValue.Name        = ClassNames.ByRef.GetValueMethodName;
            getValue.Descriptor  = GetByRefGetValueDescriptor(type);
            javaClass.Methods.Add(getValue);

            Java.Method setValue = new Java.Method();
            setValue.AccessFlags = Java.MethodAccessFlags.Abstract | Java.MethodAccessFlags.Public;
            setValue.Name        = ClassNames.ByRef.SetValueMethodName;
            setValue.Descriptor  = GetByRefSetValueDescriptor(type);
            javaClass.Methods.Add(setValue);

            WriteClass(javaClass);

            baseTypesGenerated |= (1 << (int)type);
        }
Ejemplo n.º 3
0
        private void GenerateStaticCtor(InterType type)
        {
            Method ctor = new Method();

            ctor.AccessFlags = MethodAccessFlags.Static;
            ctor.Name        = "<clinit>";
            ctor.Descriptor  = "()V";

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            var threadLocalFields = type.Fields.Where(F => F.IsThreadLocal && F.IsStatic);

            foreach (InterField fld in threadLocalFields)
            {
                FieldRef fldRef = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name),
                                               "L" + TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";");

                codeWriter
                .Add(OpCodes._new, new Java.Constants.Class(TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName)))
                .Add(OpCodes.dup)
                .Add(OpCodes.invokespecial, ClassNames.JavaLangThreadLocal.CtorMethodRef)
                .Add(OpCodes.putstatic, fldRef);
            }

            var staticValueTypeFields = type.Fields.Where(F => ((F.IsStatic) && (F.FieldType.IsValueType)));

            foreach (InterField fld in staticValueTypeFields)
            {
                Java.Constants.Class fldTypeRef     = new Java.Constants.Class(TypeNameToJava(fld.FieldType.Fullname));
                MethodRef            fldTypeInitRef = new MethodRef(fldTypeRef.Value, ClassNames.JavaConstructorMethodName, "()V");
                FieldRef             fldRef         = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name),
                                                                   GetFieldDescriptor(fld.FieldType));

                codeWriter
                .Add(OpCodes._new, fldTypeRef)
                .Add(OpCodes.dup)
                .Add(OpCodes.invokespecial, fldTypeInitRef)
                .Add(OpCodes.putstatic, fldRef);
            }

            codeWriter.AddReturn(JavaPrimitiveType.Void);

            ctor.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(ctor);
        }
Ejemplo n.º 4
0
        private void GenerateFieldAccessors(InterType type)
        {
            for (int i = 0; i < type.FieldAccessors.Count; i++)
            {
                FieldAccessor fld          = type.FieldAccessors[i];
                string        fldTypeDescr = GetFieldDescriptor(fld.Field.FieldType);
                if ((fld.Field.IsStatic) && (fld.Field.IsThreadLocal))
                {
                    fldTypeDescr = "L" + TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";";
                }

                JavaPrimitiveType javaFldType = JavaHelpers.InterTypeToJavaPrimitive(fld.Field.FieldType);
                FieldRef          fldRef      = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Field.Name), fldTypeDescr);

                Method result = new Method();
                result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Static;
                result.Name        = ClassNames.FieldAccessorPrefix + i.ToString();

                JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();
                if (!fld.Field.IsStatic)
                {
                    codeWriter.Add(OpCodes.aload_0);
                }

                if (fld.Type == FieldAccessorType.Getter)
                {
                    result.Descriptor = "(" + (fld.Field.IsStatic ? "" : GetFieldDescriptor(type)) + ")" + fldTypeDescr;
                    codeWriter
                    .Add(fld.Field.IsStatic ? OpCodes.getstatic : OpCodes.getfield, fldRef)
                    .AddReturn(javaFldType);
                }
                else
                {
                    result.Descriptor = "(" + (fld.Field.IsStatic ? "" : GetFieldDescriptor(type)) + fldTypeDescr + ")V";
                    codeWriter
                    .AddLoad(javaFldType, 1)
                    .Add(fld.Field.IsStatic ? OpCodes.putstatic : OpCodes.putfield, fldRef)
                    .Add(OpCodes._return);
                }

                result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));
                currentJavaClass.Methods.Add(result);
            }
        }
Ejemplo n.º 5
0
        private void CompileDelegateBeginInvoke(InterType type)
        {
            InterMethod beginInvokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateBeginInvokeMethodName).FirstOrDefault();

            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final;
            result.Name        = ClassNames.DelegateBeginInvokeMethodName;
            result.Descriptor  = GetMethodDescriptor(beginInvokeMethod);

            string runnerName = currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName;

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            codeWriter
            .Add(OpCodes._new, new Java.Constants.Class(TypeNameToJava(ClassNames.SystemRuntimeRemotingMessagingAsyncResult.ClassName)))
            .Add(OpCodes.dup)
            .Add(OpCodes._new, new Java.Constants.Class(runnerName))
            .Add(OpCodes.dup)
            .Add(OpCodes.aload_0);

            int    paramsCount       = beginInvokeMethod.Parameters.Count;
            string paramsDescriptors = "";

            for (int i = 0; i < paramsCount - 2; i++)
            {
                InterType paramType = beginInvokeMethod.Parameters[i].Type;

                codeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(paramType), i + 1);
                paramsDescriptors += GetFieldDescriptor(paramType);
            }

            codeWriter
            .Add(OpCodes.invokespecial, new MethodRef(runnerName, ClassNames.JavaConstructorMethodName,
                                                      "(" + GetFieldDescriptor(type) + paramsDescriptors + ")V"))
            .Add(OpCodes.aload_0)
            .AddLoad(JavaPrimitiveType.Ref, paramsCount - 1)
            .AddLoad(JavaPrimitiveType.Ref, paramsCount)
            .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeRemotingMessagingAsyncResult.CtorMethodRef)
            .Add(OpCodes.areturn);
            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }
Ejemplo n.º 6
0
        private void GenerateValueTypeCopyTo(InterType type)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            result.Name        = ClassNames.ValueTypeCopyTo;
            result.Descriptor  = "(" + GetFieldDescriptor(type) + ")V";

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            foreach (InterField fld in type.Fields.Where(F => !F.IsStatic))
            {
                FieldRef fldRef = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name),
                                               GetFieldDescriptor(fld.FieldType));

                if (fld.FieldType.IsValueType)
                {
                    MethodRef fldCopyToRef = new MethodRef(TypeNameToJava(fld.FieldType.Fullname), ClassNames.ValueTypeCopyTo,
                                                           "(" + GetFieldDescriptor(fld.FieldType) + ")V");

                    codeWriter
                    .Add(OpCodes.aload_0)
                    .Add(OpCodes.getfield, fldRef)
                    .Add(OpCodes.aload_1)
                    .Add(OpCodes.getfield, fldRef)
                    .Add(OpCodes.invokevirtual, fldCopyToRef);
                }
                else
                {
                    codeWriter
                    .Add(OpCodes.aload_1)
                    .Add(OpCodes.aload_0)
                    .Add(OpCodes.getfield, fldRef)
                    .Add(OpCodes.putfield, fldRef);
                }
            }

            codeWriter.AddReturn(JavaPrimitiveType.Void);

            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(result);
        }
Ejemplo n.º 7
0
        private void GenerateValueTypeZeroFill(InterType type)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            result.Name        = ClassNames.ValueTypeZeroFill;
            result.Descriptor  = "()V";

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            foreach (InterField fld in type.Fields)
            {
                FieldRef fldRef = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name),
                                               GetFieldDescriptor(fld.FieldType));

                if (fld.FieldType.IsValueType)
                {
                    MethodRef fldZeroFill = new MethodRef(TypeNameToJava(fld.FieldType.Fullname), ClassNames.ValueTypeZeroFill,
                                                          "()V");

                    codeWriter
                    .Add(OpCodes.aload_0)
                    .Add(OpCodes.getfield, fldRef)
                    .Add(OpCodes.invokevirtual, fldZeroFill);
                }
                else
                {
                    codeWriter
                    .Add(OpCodes.aload_0)
                    .AddDefaultValue(JavaHelpers.InterTypeToJavaPrimitive(fld.FieldType))
                    .Add(OpCodes.putfield, fldRef);
                }
            }

            codeWriter.AddReturn(JavaPrimitiveType.Void);

            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(result);
        }
Ejemplo n.º 8
0
        private void GenerateValueTypeDefaultCtor(InterType type)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            result.Name        = ClassNames.JavaConstructorMethodName;
            result.Descriptor  = "()V";

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            codeWriter
            .Add(OpCodes.aload_0)
            .Add(OpCodes.invokespecial, ClassNames.ValueTypeCtor);

            foreach (InterField fld in type.Fields)
            {
                if ((fld.FieldType.IsValueType) && (!fld.IsStatic))
                {
                    Java.Constants.Class fldTypeClassRef = new Java.Constants.Class(TypeNameToJava(fld.FieldType.Fullname));
                    MethodRef            fldTypeCtorRef  = new MethodRef(fldTypeClassRef.Value, "<init>", "()V");
                    FieldRef             fldRef          = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name),
                                                                        GetFieldDescriptor(fld.FieldType));

                    codeWriter
                    .Add(OpCodes.aload_0)
                    .Add(OpCodes._new, fldTypeClassRef)
                    .Add(OpCodes.dup)
                    .Add(OpCodes.invokespecial, fldTypeCtorRef)
                    .Add(OpCodes.putfield, fldRef);
                }
            }

            codeWriter.AddReturn(JavaPrimitiveType.Void);

            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(result);
        }
Ejemplo n.º 9
0
        private void GenerateInterfaceMethodAccessor(InterMethod ifaceMethod, InterMethod typeMethod)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            if (ifaceMethod.IsVarArg)
            {
                result.AccessFlags |= MethodAccessFlags.VarArgs;
            }
            result.Name       = MethodNameToJava(ifaceMethod.NewName);
            result.Descriptor = GetMethodDescriptor(ifaceMethod);

            JavaBytecodeWriter code = new JavaBytecodeWriter();

            code.Add(OpCodes.aload_0);

            for (int i = 0; i < ifaceMethod.Parameters.Count; i++)
            {
                code.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(ifaceMethod.Parameters[i].Type), i + 1);
            }

            MethodRef typeMethodRef = new MethodRef(TypeNameToJava(typeMethod.DeclaringType.Fullname),
                                                    MethodNameToJava(typeMethod.NewName), GetMethodDescriptor(typeMethod));

            if (typeMethod.IsPrivate)
            {
                code.Add(OpCodes.invokespecial, typeMethodRef);
            }
            else
            {
                code.Add(OpCodes.invokevirtual, typeMethodRef);
            }
            code.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(ifaceMethod.ReturnParameter.Type));
            result.Attributes.Add(code.End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }
Ejemplo n.º 10
0
        private void CompileDelegateEndInvoke(InterType type)
        {
            InterMethod endInvokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateEndInvokeMethodName).FirstOrDefault();

            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final;
            result.Name        = ClassNames.DelegateEndInvokeMethodName;
            result.Descriptor  = GetMethodDescriptor(endInvokeMethod);

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            codeWriter
            .Add(OpCodes.aload_1)
            .Add(OpCodes.checkcast, new Java.Constants.Class(TypeNameToJava(ClassNames.SystemRuntimeRemotingMessagingAsyncResult.ClassName)))
            .Add(OpCodes.invokevirtual, ClassNames.SystemRuntimeRemotingMessagingAsyncResult.EndInvokeMethodRef);

            if (endInvokeMethod.ReturnParameter.Type.PrimitiveType == PrimitiveType.Void)
            {
                codeWriter.Add(OpCodes.pop);
            }
            else
            {
                codeWriter
                .Add(OpCodes.checkcast, new Java.Constants.Class(currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName))
                .Add(OpCodes.getfield, new Java.Constants.FieldRef(
                         currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName,
                         ClassNames.DelegateRunnerResultFieldName,
                         GetFieldDescriptor(endInvokeMethod.ReturnParameter.Type)));
            }
            codeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(endInvokeMethod.ReturnParameter.Type));

            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }
Ejemplo n.º 11
0
        private string GenerateMethodPointerClass(InterMethod operand)
        {
            string mpInterfaceName = namesController.GetMethodPointerInterface(operand);

            string anonClassName = namesController.GetAnonimousClassName();

            Java.Class anonClass = new Java.Class();
            anonClass.AccessFlag = Java.ClassAccessFlag.Super | ClassAccessFlag.Public;
            anonClass.ThisClass  = namesController.TypeNameToJava(anonClassName);
            anonClass.SuperClass = namesController.TypeNameToJava(ClassNames.JavaObject);
            anonClass.Interfaces.Add(namesController.TypeNameToJava(mpInterfaceName));

            Method invokeMethod = new Method();

            invokeMethod.AccessFlags = MethodAccessFlags.Public;
            invokeMethod.Name        = ClassNames.MethodPointerInvokeName;
            invokeMethod.Descriptor  = "(L" + namesController.TypeNameToJava(ClassNames.JavaObject)
                                       + ";" + namesController.GetMethodDescriptor(operand).Substring(1);

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            if (!operand.IsStatic)
            {
                codeWriter
                .Add(OpCodes.aload_1)
                .Add(OpCodes.checkcast, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType)));
            }

            for (int i = 0; i < operand.Parameters.Count; i++)
            {
                codeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(operand.Parameters[i].Type), i + 2);
            }

            MethodRef invokingMethodRef = new MethodRef(namesController.TypeNameToJava(operand.DeclaringType),
                                                        namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand));;

            if (!operand.IsPublic)
            {
                Method access = namesController.GetAnonumousAccessMethod();
                access.AccessFlags = MethodAccessFlags.Public;

                if (operand.IsStatic)
                {
                    access.AccessFlags |= MethodAccessFlags.Static;
                }

                access.Descriptor = namesController.GetMethodDescriptor(operand);

                JavaBytecodeWriter accessCodeWriter = new JavaBytecodeWriter();

                if (!operand.IsStatic)
                {
                    accessCodeWriter.Add(OpCodes.aload_0);
                }

                int firstParameter = operand.IsStatic ? 0 : 1;

                for (int i = 0; i < operand.Parameters.Count; i++)
                {
                    accessCodeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(operand.Parameters[i].Type), i + firstParameter);
                }

                if (operand.IsStatic)
                {
                    accessCodeWriter.Add(OpCodes.invokestatic, invokingMethodRef);
                }
                else if (operand.IsPrivate)
                {
                    accessCodeWriter.Add(OpCodes.invokespecial, invokingMethodRef);
                }
                else
                {
                    accessCodeWriter.Add(OpCodes.invokevirtual, invokingMethodRef);
                }

                access.Attributes.Add(accessCodeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(
                                                                     operand.ReturnParameter.Type)).End(this.constsPool));

                invokingMethodRef = new MethodRef(namesController.TypeNameToJava(operand.DeclaringType),
                                                  access.Name, namesController.GetMethodDescriptor(operand));
            }

            if (operand.IsStatic)
            {
                codeWriter.Add(OpCodes.invokestatic, invokingMethodRef);
            }
            else if (operand.DeclaringType.IsInterface)
            {
                codeWriter.Add(OpCodes.invokeinterface, invokingMethodRef);
            }
            else
            {
                codeWriter.Add(OpCodes.invokevirtual, invokingMethodRef);
            }

            invokeMethod.Attributes.Add(codeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(operand.ReturnParameter.Type))
                                        .End(anonClass.ConstantPool));
            anonClass.Methods.Add(invokeMethod);

            Method ctor = new Method();

            ctor.AccessFlags = MethodAccessFlags.Public;
            ctor.Name        = ClassNames.JavaConstructorMethodName;
            ctor.Descriptor  = "()V";
            ctor.Attributes.Add(new JavaBytecodeWriter()
                                .Add(OpCodes.aload_0)
                                .Add(OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef)
                                .Add(OpCodes._return).End(anonClass.ConstantPool));
            anonClass.Methods.Add(ctor);

            namesController.WriteAnonumousClass(anonClass);

            return(anonClassName);
        }
Ejemplo n.º 12
0
        private void GenerateValueTypeEquals(InterType type)
        {
            if (type.Methods.Where(M => ((M.Name == "Equals") && (M.Parameters.Count == 1) &&
                                         (M.Parameters[0].Type.Fullname == ClassNames.JavaObject))).Count() > 0)
            {
                return;
            }

            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            result.Name        = "equals";
            result.Descriptor  = "(L" + TypeNameToJava(ClassNames.JavaObject) + ";)Z";

            Java.Constants.Class thisTypeRef = new Java.Constants.Class(TypeNameToJava(type.Fullname));

            JavaBytecodeWriter codeGenerator = new JavaBytecodeWriter();

            codeGenerator
            .Add(OpCodes.aload_1)
            .Add(OpCodes.instanceof, thisTypeRef)
            .Add(OpCodes.ifeq, "false")
            .Add(OpCodes.aload_1)
            .Add(OpCodes.checkcast, thisTypeRef)
            .Add(OpCodes.astore_1);

            foreach (InterField fld in type.Fields)
            {
                FieldRef fldRef = new FieldRef(thisTypeRef.Value, FieldNameToJava(fld.Name), GetFieldDescriptor(fld.FieldType));

                codeGenerator
                .Add(OpCodes.aload_0)
                .Add(OpCodes.getfield, fldRef)
                .Add(OpCodes.aload_1)
                .Add(OpCodes.getfield, fldRef);

                if ((fld.FieldType.IsPrimitive) || (fld.FieldType.IsEnum))
                {
                    switch (JavaHelpers.InterTypeToJavaPrimitive(fld.FieldType))
                    {
                    case JavaPrimitiveType.Bool:
                    case JavaPrimitiveType.Byte:
                    case JavaPrimitiveType.Char:
                    case JavaPrimitiveType.Int:
                    case JavaPrimitiveType.Short:
                        codeGenerator.Add(OpCodes.if_icmpne, "false");
                        break;

                    case JavaPrimitiveType.Long:
                        codeGenerator.Add(OpCodes.lcmp).Add(OpCodes.ifne, "false");
                        break;

                    case JavaPrimitiveType.Float:
                        codeGenerator.Add(OpCodes.fcmpg).Add(OpCodes.ifne, "false");
                        break;

                    case JavaPrimitiveType.Double:
                        codeGenerator.Add(OpCodes.dcmpg).Add(OpCodes.ifne, "false");
                        break;
                    }
                }
                else if (fld.FieldType.IsValueType)
                {
                    MethodRef equalMethod = new MethodRef(TypeNameToJava(fld.FieldType.Fullname), result.Name, result.Descriptor);
                    codeGenerator.Add(OpCodes.invokevirtual, equalMethod).Add(OpCodes.ifeq, "false");
                }
                else
                {
                    codeGenerator.Add(OpCodes.if_acmpne, "false");
                }
            }

            codeGenerator
            .Add(OpCodes.iconst_1)
            .Add(OpCodes._goto, "exit")
            .Label("false")
            .Add(OpCodes.iconst_0)
            .Label("exit")
            .Add(OpCodes.ireturn);

            result.Attributes.Add(codeGenerator.End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(result);
        }
Ejemplo n.º 13
0
        private byte[] GenerateMethodProlog()
        {
            codeGenerator = new JavaBytecodeWriter();

            if (thisMethod.IsConstructor)
            {
                if (firstCall != null)
                {
                    CompileExpression(firstCall, ExpectType.Any);
                }
                else if (!thisMethod.IsStatic)
                {
                    string typeName = namesController.TypeNameToJava(thisMethod.DeclaringType.BaseType);
                    if ((thisMethod.DeclaringType.IsValueType) && (thisMethod.Parameters.Count > 0))
                    {
                        //call to this() to initialize all fields
                        typeName = namesController.TypeNameToJava(thisMethod.DeclaringType);
                    }

                    MethodRef superCall = new MethodRef(typeName, ClassNames.JavaConstructorMethodName, "()V");
                    codeGenerator
                    .Add(OpCodes.aload_0)
                    .Add(OpCodes.invokespecial, superCall);
                }

                if (thisMethod.IsStatic)
                {
                    var threadLocalFields = thisMethod.DeclaringType.Fields.Where(F => F.IsStatic && F.IsThreadLocal);

                    foreach (InterField fld in threadLocalFields)
                    {
                        FieldRef fldRef = new FieldRef(
                            namesController.TypeNameToJava(fld.DeclaringType.Fullname),
                            namesController.FieldNameToJava(fld.Name),
                            "L" + namesController.TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";");

                        codeGenerator
                        .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName)))
                        .Add(OpCodes.dup)
                        .Add(OpCodes.invokespecial, ClassNames.JavaLangThreadLocal.CtorMethodRef)
                        .Add(OpCodes.putstatic, fldRef);
                    }
                }

                var valueTypeFields = thisMethod.DeclaringType.Fields
                                      .Where(F => ((F.FieldType.IsValueType) && (F.IsStatic == thisMethod.IsStatic)));
                OpCodes putfield = thisMethod.IsStatic ? OpCodes.putstatic : OpCodes.putfield;

                foreach (InterField fld in valueTypeFields)
                {
                    Java.Constants.Class fldTypeRef = new Java.Constants.Class(
                        namesController.TypeNameToJava(fld.FieldType));
                    MethodRef ctorRef = new MethodRef(fldTypeRef.Value, ClassNames.JavaConstructorMethodName, "()V");
                    FieldRef  fldRef  = new FieldRef(namesController.TypeNameToJava(fld.DeclaringType),
                                                     namesController.FieldNameToJava(fld.Name), namesController.GetFieldDescriptor(fld.FieldType));

                    if (!thisMethod.IsStatic)
                    {
                        codeGenerator.Add(OpCodes.aload_0);
                    }

                    codeGenerator
                    .Add(OpCodes._new, fldTypeRef)
                    .Add(OpCodes.dup)
                    .Add(OpCodes.invokespecial, ctorRef)
                    .Add(putfield, fldRef);
                }
            }

            foreach (ValueTypeVar v in valueTypesVars)
            {
                Java.Constants.Class     typeRef = new Java.Constants.Class(namesController.TypeNameToJava(v.varType));
                Java.Constants.MethodRef ctorRef = new Java.Constants.MethodRef(typeRef.Value,
                                                                                ClassNames.JavaConstructorMethodName, "()V");

                codeGenerator
                .Add(Java.OpCodes._new, typeRef)
                .Add(Java.OpCodes.dup)
                .Add(Java.OpCodes.invokespecial, ctorRef)
                .AddStore(JavaPrimitiveType.Ref, v.varIndex);
            }

            return(codeGenerator.End(constsPool).CodeBytes);
        }
Ejemplo n.º 14
0
        public void Compile()
        {
            MethodDefinition methodDef = thisMethod.Body.Method;

            Messages.Verbose("      Generating IL graph...");

            ILAstBuilder builder = new ILAstBuilder();

            ilBody = new ILBlock();

            DecompilerContext context = new DecompilerContext(methodDef.Module)
            {
                CurrentType = methodDef.DeclaringType, CurrentMethod = methodDef
            };

            Utils.SetDecompillerSettings(context.Settings);

            ilBody.Body = builder.Build(methodDef, true, context);
            new ILAstOptimizer().Optimize(context, ilBody);

            FillVars(builder.Parameters);

            Messages.Verbose("      Preprocess IL graph...");
            RunPreprocessor();

            Messages.Verbose("      Compiling IL graph to java bytecode...");
            CompileNode(ilBody, ExpectType.None);

            //Checking for deleted last ret
            if (ilBody.Body.Count > 0)
            {
                ILNode lastNode = ilBody.Body.Last();
                if ((lastNode is ILExpression) && (((ILExpression)lastNode).Code != ILCode.Ret) &&
                    (((ILExpression)lastNode).Code != ILCode.Throw))
                {
                    CompileRet(null, ExpectType.None);
                }
                else if (thisMethod.ReturnParameter.Type.PrimitiveType == PrimitiveType.Void)
                {
                    CompileRet(null, ExpectType.None);
                }
            }
            else
            {
                CompileRet(null, ExpectType.None);
            }

            oldCodeGenerator = codeGenerator;
            byte[] prolog = GenerateMethodProlog();
            codeGenerator = oldCodeGenerator;

            Messages.Verbose("      Linking java bytecode...");
            codeGenerator.StartOffset = prolog.Length;
            byte[] codeBytes = codeGenerator.Link(constsPool);
            GenerateJavaExceptionTable();

            resultCode           = new Java.Attributes.Code();
            resultCode.CodeBytes = prolog.Concat(codeBytes).ToArray();

            WriteJavaExceptionTable(prolog.Length);

            Messages.Verbose("      Simulating stack to calculate MaxStack and MaxLocals...");
            StackSimulator.SimulateStack(constsPool, resultCode);
            resultCode.MaxLocals = (ushort)nextVarIndex;

            if (Program.Debug)
            {
                GenerateDebugInfo(prolog.Length);
            }
        }
Ejemplo n.º 15
0
        private void GenerateDelegateRunner(InterType type)
        {
            Java.Class runner = new Java.Class();
            runner.AccessFlag = ClassAccessFlag.Final;
            runner.ThisClass  = currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName;
            runner.SuperClass = TypeNameToJava(ClassNames.CIL2JavaDelegateRunner.ClassName);

            Java.Attributes.InnerClasses.InnerClass inner = new Java.Attributes.InnerClasses.InnerClass()
            {
                AccessFlags    = Java.Attributes.InnerClasses.InnerClassAccessFlags.Final | Java.Attributes.InnerClasses.InnerClassAccessFlags.Private,
                InnerClassInfo = runner.ThisClass,
                InnerName      = ClassNames.DelegateRunnerClassName,
                OuterClassInfo = currentJavaClass.ThisClass
            };

            Java.Attributes.InnerClasses innerAttr = new Java.Attributes.InnerClasses();
            innerAttr.Classes.Add(inner);
            runner.Attributes.Add(innerAttr);
            currentJavaInnerClasses.Classes.Add(inner);

            InterMethod invokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault();

            Field selfField = new Field();

            selfField.AccessFlags = FieldAccessFlags.Private | FieldAccessFlags.Final;
            selfField.Name        = ClassNames.DelegateRunnerSelfFieldName;
            selfField.Descriptor  = GetFieldDescriptor(type);
            runner.Fields.Add(selfField);
            FieldRef selfFieldRef = new FieldRef(runner.ThisClass, selfField.Name, selfField.Descriptor);

            JavaBytecodeWriter ctorCodeWriter = new JavaBytecodeWriter();
            JavaBytecodeWriter runCodeWriter  = new JavaBytecodeWriter();

            ctorCodeWriter
            //super()
            .Add(OpCodes.aload_0)
            .Add(OpCodes.invokespecial, ClassNames.CIL2JavaDelegateRunner.CtorMethodRef)

            //this.self = self;
            .Add(OpCodes.aload_0)
            .Add(OpCodes.aload_1)
            .Add(OpCodes.putfield, selfFieldRef);

            if (invokeMethod.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void)
            {
                runCodeWriter.Add(OpCodes.aload_0);
            }

            runCodeWriter
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, selfFieldRef);

            for (int i = 0; i < invokeMethod.Parameters.Count; i++)
            {
                InterType         paramType = invokeMethod.Parameters[i].Type;
                JavaPrimitiveType jp        = JavaHelpers.InterTypeToJavaPrimitive(paramType);

                Field paramField = new Field();
                paramField.AccessFlags = FieldAccessFlags.Final | FieldAccessFlags.Private;
                paramField.Name        = ClassNames.DelegateRunnerParamFieldNamePrefix + i.ToString();;
                paramField.Descriptor  = GetFieldDescriptor(paramType);
                runner.Fields.Add(paramField);
                FieldRef paramFieldRef = new FieldRef(runner.ThisClass, paramField.Name, paramField.Descriptor);

                ctorCodeWriter
                .Add(OpCodes.aload_0)
                .AddLoad(jp, i + 2)
                .Add(OpCodes.putfield, paramFieldRef);

                runCodeWriter
                .Add(OpCodes.aload_0)
                .Add(OpCodes.getfield, paramFieldRef);
            }

            if (invokeMethod.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void)
            {
                Field resultField = new Field();
                resultField.AccessFlags = FieldAccessFlags.Private;
                resultField.Name        = ClassNames.DelegateRunnerResultFieldName;
                resultField.Descriptor  = GetFieldDescriptor(invokeMethod.ReturnParameter.Type);
                runner.Fields.Add(resultField);
                runCodeWriter.Add(OpCodes.putfield, new FieldRef(runner.ThisClass, resultField.Name, resultField.Descriptor));
            }

            runCodeWriter
            .Add(OpCodes.invokevirtual, new MethodRef(TypeNameToJava(type.Fullname), ClassNames.DelegateInvokeMethodName,
                                                      GetMethodDescriptor(invokeMethod)))
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, ClassNames.CIL2JavaDelegateRunner.OnEndedFieldRef)
            .Add(OpCodes.dup)
            .Add(OpCodes.ifnull, "noOnEnd")
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, ClassNames.CIL2JavaDelegateRunner.AsyncResultFieldResult)
            .Add(OpCodes.invokevirtual, ClassNames.SystemAsyncCallback.InvokeMethodRef)
            .Add(OpCodes._goto, "exit")
            .Label("noOnEnd")
            .Add(OpCodes.pop)
            .Label("exit");

            ctorCodeWriter.Add(OpCodes._return);
            runCodeWriter.Add(OpCodes._return);

            string paramsDescriptor = GetMethodDescriptor(invokeMethod);

            paramsDescriptor = paramsDescriptor.Substring(1, paramsDescriptor.LastIndexOf(')') - 1);

            Method ctorMethod = new Method();

            ctorMethod.AccessFlags = MethodAccessFlags.Public;
            ctorMethod.Name        = ClassNames.JavaConstructorMethodName;
            ctorMethod.Descriptor  = "(" + GetFieldDescriptor(type) + paramsDescriptor + ")V";
            ctorMethod.Attributes.Add(ctorCodeWriter.End(runner.ConstantPool));
            runner.Methods.Add(ctorMethod);

            Method runMethod = new Method();

            runMethod.AccessFlags = MethodAccessFlags.Public;
            runMethod.Name        = ClassNames.CIL2JavaDelegateRunner.RunMethodName;
            runMethod.Descriptor  = "()V";
            runMethod.Attributes.Add(runCodeWriter.End(runner.ConstantPool));
            runner.Methods.Add(runMethod);

            WriteClass(runner);
        }
Ejemplo n.º 16
0
        private void CompileDelegateInvoke(InterType type)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final;
            result.Name        = ClassNames.DelegateInvokeMethodName;
            result.Descriptor  = GetMethodDescriptor(type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName)
                                                     .FirstOrDefault());

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            Java.Constants.Class methodPointerType = new Java.Constants.Class(
                TypeNameToJava(((INamesController)this).GetMethodPointerInterface(
                                   type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault())));

            InterMethod invokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault();

            codeWriter
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, ClassNames.DelegateMethodFieldFast);

            if (Program.MethodPointersType == MethodPointerImplementation.Standart)
            {
                MethodRef unboxRef = Program.AsX64 ? ClassNames.JavaLongUnbox : ClassNames.JavaIntegerUnbox;

                codeWriter
                .Add(OpCodes.checkcast, new Java.Constants.Class(unboxRef.Class))
                .Add(OpCodes.invokevirtual, unboxRef);

                if (Program.AsX64)
                {
                    codeWriter.Add(OpCodes.l2i);
                }

                codeWriter.Add(OpCodes.invokestatic, ClassNames.GlobalMethodPointersGet);
            }

            codeWriter
            .Add(OpCodes.checkcast, methodPointerType)
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, ClassNames.DelegateTargetField);

            for (int i = 0; i < invokeMethod.Parameters.Count; i++)
            {
                codeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(invokeMethod.Parameters[i].Type), i + 1);
            }

            codeWriter.Add(OpCodes.invokeinterface,
                           new InterfaceMethodRef(methodPointerType.Value, ClassNames.MethodPointerInvokeName,
                                                  "(L" + TypeNameToJava(ClassNames.JavaObject) + ";" + GetMethodDescriptor(invokeMethod).Substring(1)));

            if (type.BaseType.Fullname == ClassNames.MulticastDelegateTypeName)
            {
                codeWriter
                .Add(OpCodes.aload_0)
                .Add(OpCodes.getfield, ClassNames.MulticastDelegateNextField)
                .Add(OpCodes.ifnull, "exit");

                if (invokeMethod.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void)
                {
                    codeWriter.Add(OpCodes.pop);
                }

                codeWriter
                .Add(OpCodes.aload_0)
                .Add(OpCodes.getfield, ClassNames.MulticastDelegateNextField)
                .Add(OpCodes.checkcast, new Java.Constants.Class(TypeNameToJava(type.Fullname)));

                for (int i = 0; i < invokeMethod.Parameters.Count; i++)
                {
                    codeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(invokeMethod.Parameters[i].Type), i + 1);
                }

                codeWriter.Add(OpCodes.invokevirtual, new MethodRef(TypeNameToJava(type.Fullname),
                                                                    ClassNames.DelegateInvokeMethodName, GetMethodDescriptor(invokeMethod)));
            }

            codeWriter
            .Label("exit")
            .AddReturn(JavaHelpers.InterTypeToJavaPrimitive(invokeMethod.ReturnParameter.Type));
            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }