Ejemplo n.º 1
0
        private void CompileFieldStore(InterField operand, object tag)
        {
            if ((operand.IsStatic) && (operand.IsThreadLocal))
            {
                CompileFieldLoad(operand, tag, false);
                codeGenerator.Add(OpCodes.swap, null, tag);
                codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangThreadLocal.SetMethodRef, tag);
                return;
            }

            if (((operand.IsPrivate) && (operand.DeclaringType != thisMethod.DeclaringType)) ||
                ((operand.IsProtected) && (operand.DeclaringType != thisMethod.DeclaringType) &&
                (!thisMethod.DeclaringType.IsSuper(operand.DeclaringType))))
            {
                string accessMethodName = operand.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Setter, operand));

                MethodRef accessMethod = new MethodRef(
                    namesController.TypeNameToJava(operand.DeclaringType),
                    accessMethodName,
                    "(" + namesController.GetFieldDescriptor(operand.DeclaringType)
                        + namesController.GetFieldDescriptor(operand.FieldType) + ")V");
                codeGenerator.Add(Java.OpCodes.invokestatic, accessMethod);
            }
            else
            {
                codeGenerator.AddInstruction(new JavaInstruction(
                    operand.IsStatic ? Java.OpCodes.putstatic : Java.OpCodes.putfield,
                    new Java.Constants.FieldRef(
                        namesController.TypeNameToJava(operand.DeclaringType),
                        namesController.FieldNameToJava(operand.Name),
                        namesController.GetFieldDescriptor(operand.FieldType)),
                    tag));
            }
        }
Ejemplo n.º 2
0
        private void CompileStfld(ILExpression e, ExpectType expectType)
        {
            InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments);
            bool needDup = ((e.ExpectedType != null) && (expectType != ExpectType.None));

            bool boxed = operand.IsStatic && operand.IsThreadLocal;

            int argIndex = 0;
            if (e.Code == ILCode.Stfld)
                CompileExpression(e.Arguments[argIndex++], ExpectType.Reference);

            CompileExpression(e.Arguments[argIndex++], boxed ? ExpectType.Boxed : GetExpectType(operand));

            if (needDup)
            {
                JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(operand.FieldType);
                if (e.Code == ILCode.Stfld)
                {
                    if (jp.IsDoubleSlot())
                        codeGenerator.Add(Java.OpCodes.dup2_x1, null, e);
                    else
                        codeGenerator.Add(Java.OpCodes.dup_x1, null, e);
                }
                else
                {
                    if (jp.IsDoubleSlot())
                        codeGenerator.Add(Java.OpCodes.dup2, null, e);
                    else
                        codeGenerator.Add(Java.OpCodes.dup, null, e);
                }
            }

            CompileFieldStore(operand, e);
        }
Ejemplo n.º 3
0
        private void CompileFieldLoad(InterField operand, object tag, bool getFromThreadLocal = true)
        {
            string fldDesc = namesController.GetFieldDescriptor(operand.FieldType);
            if ((operand.IsStatic) && (operand.IsThreadLocal))
                fldDesc = "L" + namesController.TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";";

            if (((operand.IsPrivate) && (operand.DeclaringType != thisMethod.DeclaringType)) ||
                ((operand.IsProtected) && (operand.DeclaringType != thisMethod.DeclaringType) &&
                (!thisMethod.DeclaringType.IsSuper(operand.DeclaringType))))
            {
                string accessMethodName = operand.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, operand));

                MethodRef accessMethod = new MethodRef(
                    namesController.TypeNameToJava(operand.DeclaringType),
                    accessMethodName,
                    "(" + (operand.IsStatic ? "" : namesController.GetFieldDescriptor(operand.DeclaringType)) + ")"
                        + fldDesc);
                codeGenerator.Add(Java.OpCodes.invokestatic, accessMethod);
            }
            else
            {
                codeGenerator.AddInstruction(new JavaInstruction(
                    operand.IsStatic ? Java.OpCodes.getstatic : Java.OpCodes.getfield,
                    new Java.Constants.FieldRef(
                        namesController.TypeNameToJava(operand.DeclaringType),
                        namesController.FieldNameToJava(operand.Name),
                        fldDesc),
                    tag));
            }

            if ((operand.IsStatic) && (operand.IsThreadLocal) && (getFromThreadLocal))
                CompileFieldLoadThreadLocal(operand, tag);
        }
Ejemplo n.º 4
0
        private void CompilePostIncrement(ILExpression e, ExpectType expect)
        {
            int incVal = (int)e.Operand;

            e = e.Arguments[0];
            //TODO: PostIncrement for long and other types

            if (e.Code == ILCode.Ldloca)
            {
                int varIndex = GetVarIndex((ILVariable)e.Operand);

                codeGenerator
                .AddLoad(JavaPrimitiveType.Int, varIndex, e)
                .Add(OpCodes.dup, null, e)
                .AddIntConst(incVal, e)
                .Add(OpCodes.iadd, null, e)
                .AddStore(JavaPrimitiveType.Int, varIndex, e);
            }
            else if (e.Code == ILCode.Ldsflda)
            {
                InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments);

                CompileFieldLoad(operand, e);
                codeGenerator
                .Add(OpCodes.dup, null, e)
                .AddIntConst(incVal, e)
                .Add(OpCodes.iadd, null, e);
                CompileFieldStore(operand, e);
            }
            else if (e.Code == ILCode.Ldflda)
            {
                InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments);

                int tmpVar = GetNextFreeVar(JavaPrimitiveType.Int);

                CompileExpression(e.Arguments[0], ExpectType.Reference);    //this

                codeGenerator.Add(OpCodes.dup, null, e);
                CompileFieldLoad(operand, e);
                codeGenerator
                .Add(OpCodes.dup, null, e)
                .AddStore(JavaPrimitiveType.Int, tmpVar, e)
                .AddIntConst(incVal, e)
                .Add(OpCodes.iadd, null, e);
                CompileFieldStore(operand, e);
                codeGenerator
                .AddLoad(JavaPrimitiveType.Int, tmpVar, e);

                FreeVar(tmpVar, JavaPrimitiveType.Int);
            }
            else
            {
                throw new Exception();  //TODO: another supported postincrements.
            }
            // See ICSharpCode.Decompiler\ILAst\PeepholeTransform.cs:IntroducePostIncrement
        }
Ejemplo n.º 5
0
        private void CompileFieldLoadThreadLocal(InterField operand, object tag)
        {
            InterType fldType = operand.FieldType;

            codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangThreadLocal.GetMethodRef, tag);

            if ((fldType.IsPrimitive) || (fldType.IsValueType) || (fldType.IsEnum))
                CompileUnbox_Any(
                    new ILExpression(ILCode.Unbox_Any, fldType,
                        new ILExpression(ILCode.Nop, null)),
                    GetExpectType(fldType));
            else
                codeGenerator.Add(OpCodes.checkcast, new Java.Constants.Class(namesController.TypeNameToJava(
                    fldType)), tag);
        }
Ejemplo n.º 6
0
        private void CompileLdflda(ILExpression e, ExpectType expectType)
        {
            InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments);

            if ((operand.FieldType.IsValueType) || ((operand.FieldType.IsPrimitive) && (expectType == ExpectType.Reference)))
            {
                if (e.Code == ILCode.Ldflda)
                {
                    CompileExpression(e.Arguments[0], ExpectType.Reference);
                }

                CompileFieldLoad(operand, e);

                if (operand.FieldType.IsPrimitive)
                {
                    TranslateType(operand.FieldType, ExpectType.Boxed, e);
                }

                return;
            }

            string byRefTypeName = byRefController.GetFieldByRefTypeName(operand.FieldType);

            Java.Constants.Class constByRefType      = new Java.Constants.Class(namesController.TypeNameToJava(byRefTypeName));
            Java.Constants.Class constFieldDeclClass =
                new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType));
            Java.Constants.String constFieldName = new Java.Constants.String(
                namesController.FieldNameToJava(operand.Name));
            MethodRef constFieldByRefCtorRef = byRefController.GetFieldByRefCtorMethodRef(operand.FieldType);

            codeGenerator.Add(OpCodes._new, constByRefType, e);
            codeGenerator.Add(OpCodes.dup, null, e);

            if (e.Code == ILCode.Ldflda)
            {
                CompileExpression(e.Arguments[0], ExpectType.Reference);
            }
            else
            {
                codeGenerator.Add(OpCodes.aconst_null, null, e);
            }

            codeGenerator.Add(OpCodes.ldc, constFieldDeclClass, e);
            codeGenerator.Add(OpCodes.ldc, constFieldName, e);
            codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredFieldRef, e);
            codeGenerator.Add(OpCodes.invokespecial, constFieldByRefCtorRef);
        }
Ejemplo n.º 7
0
        private void CompileLdfld(ILExpression e, ExpectType expectType)
        {
            InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments);

            if (e.Code == ILCode.Ldfld)
                CompileExpression(e.Arguments[0], ExpectType.Reference);

            CompileFieldLoad(operand, e);

            if (operand.FieldType.IsValueType)
            {
                MethodRef getCopyRef = new MethodRef(namesController.TypeNameToJava(operand.FieldType),
                    ClassNames.ValueTypeGetCopy, "()" + namesController.GetFieldDescriptor(operand.FieldType));
                codeGenerator.Add(Java.OpCodes.invokevirtual, getCopyRef, e);
            }

            TranslateType(operand.FieldType, expectType, e);
        }
Ejemplo n.º 8
0
        InterField IResolver.Resolve(FieldReference fldRef, List <InterGenericArgument> genericArgs)
        {
            InterType  declType = ((IResolver)this).Resolve(fldRef.DeclaringType, genericArgs);
            InterField result   = declType.Fields.Where(F => F.Name == fldRef.Name).FirstOrDefault();

            if (result == null)
            {
                InterField mapped = null;

                result = new InterField(fldRef, genericArgs, this, F => mapped = F);
                if (mapped != null)
                {
                    return(mapped);
                }

                Messages.Verbose("Adding field {0} to compile...", result.ToString());
                declType.Fields.Add(result);
            }

            return(result);
        }
Ejemplo n.º 9
0
 public FieldAccessor(FieldAccessorType type, InterField field)
 {
     this.Type  = type;
     this.Field = field;
 }
Ejemplo n.º 10
0
 private ExpectType GetExpectType(InterField fld)
 {
     return(GetExpectType(fld.FieldType));
 }
Ejemplo n.º 11
0
        private void CompileLdtoken(ILExpression e, ExpectType expect)
        {
            if (e.Operand is TypeReference)
            {
                InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments);

                codeGenerator
                .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeTypeHandle.ClassName)), e)
                .Add(OpCodes.dup, null, e)
                .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand)), e)
                .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeTypeHandle.CtorMethodRef, e);
            }
            else if (e.Operand is FieldReference)
            {
                InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments);

                codeGenerator
                .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeFieldHandle.ClassName)), e)
                .Add(OpCodes.dup, null, e)
                .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType)), e)
                .Add(OpCodes.ldc, new Java.Constants.String(operand.Name), e)
                .Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredFieldRef, e)
                .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeFieldHandle.CtorMethodRef, e);
            }
            else if (e.Operand is MethodReference)
            {
                InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);

                codeGenerator
                .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeMethodHandle.ClassName)), e)
                .Add(OpCodes.dup, null, e)
                .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType)), e);

                if (!operand.IsConstructor)
                {
                    codeGenerator.Add(OpCodes.ldc, new Java.Constants.String(operand.NewName), e);
                }

                codeGenerator
                .AddIntConst(operand.Parameters.Count, e)
                .Add(OpCodes.anewarray, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.JavaLangClass.ClassName)), e);

                for (int i = 0; i < operand.Parameters.Count; i++)
                {
                    codeGenerator
                    .Add(OpCodes.dup)
                    .AddIntConst(i, e)
                    .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.Parameters[i].Type)))
                    .Add(OpCodes.aastore, null, e);
                }

                if (operand.IsConstructor)
                {
                    codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredConstructorRef, e);
                }
                else
                {
                    codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredMethodRef, e);
                }

                codeGenerator.Add(OpCodes.invokespecial, ClassNames.SystemRuntimeMethodHandle.CtorMethodRef, e);
            }
        }
Ejemplo n.º 12
0
        private Java.Field CompileField(InterField field)
        {
            Messages.Verbose("    Compiling field {0}...", field.ToString());
            Java.Field result = new Java.Field();

            if (field.IsPublic)
            {
                result.AccessFlags |= Java.FieldAccessFlags.Public;
            }
            else if (field.IsProtected)
            {
                result.AccessFlags |= Java.FieldAccessFlags.Protected;
            }
            else
            {
                result.AccessFlags |= Java.FieldAccessFlags.Private;
            }

            if (field.IsStatic)
            {
                result.AccessFlags |= Java.FieldAccessFlags.Static;
            }

            //if it will be readonly, we will get error in CopyTo method of ValueType
            if (((field.IsReadonly) || (field.IsLiteral)) && (!field.DeclaringType.IsValueType))
            {
                result.AccessFlags |= Java.FieldAccessFlags.Final;
            }
            if (field.IsVolatile)
            {
                result.AccessFlags |= Java.FieldAccessFlags.Volatile;
            }

            result.Name       = FieldNameToJava(field.Name);
            result.Descriptor = GetFieldDescriptor(field.FieldType);

            if ((field.IsStatic) && (field.IsThreadLocal))
            {
                result.Descriptor = "L" + TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";";
            }

            if (field.Constatnt != null)
            {
                Java.Constant constVal = null;

                if (field.Constatnt is byte)
                {
                    constVal = new Java.Constants.Integer((byte)field.Constatnt);
                }
                else if (field.Constatnt is sbyte)
                {
                    constVal = new Java.Constants.Integer((sbyte)field.Constatnt);
                }
                else if (field.Constatnt is short)
                {
                    constVal = new Java.Constants.Integer((short)field.Constatnt);
                }
                else if (field.Constatnt is ushort)
                {
                    constVal = new Java.Constants.Integer((ushort)field.Constatnt);
                }
                else if (field.Constatnt is int)
                {
                    constVal = new Java.Constants.Integer((int)field.Constatnt);
                }
                else if (field.Constatnt is uint)
                {
                    constVal = new Java.Constants.Integer(unchecked ((int)((uint)field.Constatnt)));
                }
                else if (field.Constatnt is char)
                {
                    constVal = new Java.Constants.Integer((char)field.Constatnt);
                }
                else if (field.Constatnt is bool)
                {
                    constVal = new Java.Constants.Integer((bool)field.Constatnt ? 1 : 0);
                }
                else if (field.Constatnt is long)
                {
                    constVal = new Java.Constants.Long((long)field.Constatnt);
                }
                else if (field.Constatnt is ulong)
                {
                    constVal = new Java.Constants.Long(unchecked ((long)((ulong)field.Constatnt)));
                }
                else if (field.Constatnt is float)
                {
                    constVal = new Java.Constants.Float((float)field.Constatnt);
                }
                else if (field.Constatnt is double)
                {
                    constVal = new Java.Constants.Double((double)field.Constatnt);
                }
                else if (field.Constatnt is string)
                {
                    constVal = new Java.Constants.String((string)field.Constatnt);
                }

                if (constVal != null)
                {
                    result.Attributes.Add(new Java.Attributes.ConstantValue(constVal));
                }
            }

            return(result);
        }
Ejemplo n.º 13
0
        private void ProcessMethodDecencies(InterMethod method, ILNode node, List <InterGenericArgument> genericArgs)
        {
            if (node is ILBlock)
            {
                ILBlock block = node as ILBlock;

                foreach (ILNode n in block.Body)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }
            }
            else if (node is ILBasicBlock)
            {
                ILBasicBlock block = node as ILBasicBlock;

                foreach (ILNode n in block.Body)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }
            }
            else if (node is ILTryCatchBlock)
            {
                ILTryCatchBlock block = node as ILTryCatchBlock;

                foreach (ILNode n in block.TryBlock.Body)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }
                if (block.FaultBlock != null)
                {
                    foreach (ILNode n in block.FaultBlock.Body)
                    {
                        ProcessMethodDecencies(method, n, genericArgs);
                    }
                }
                if (block.FinallyBlock != null)
                {
                    foreach (ILNode n in block.FinallyBlock.Body)
                    {
                        ProcessMethodDecencies(method, n, genericArgs);
                    }
                }
                foreach (var catchBlock in block.CatchBlocks)
                {
                    ((IResolver)this).Resolve(catchBlock.ExceptionType, genericArgs);
                    ProcessMethodDecencies(method, catchBlock, genericArgs);
                }
            }
            else if (node is ILExpression)
            {
                ILExpression e = node as ILExpression;

                foreach (var n in e.Arguments)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }

                if ((e.Code == ILCode.Mkrefany) || (e.Code == ILCode.Refanyval))
                {
                    ((IResolver)this).Resolve(ClassNames.SystemTypedReference.ClassName);
                }

                if (e.Code == ILCode.Refanytype)
                {
                    ((IResolver)this).Resolve(ClassNames.SystemTypedReference.ClassName);
                    ((IResolver)this).Resolve(ClassNames.SystemRuntimeTypeHandle.ClassName);
                }

                if (e.Code == ILCode.Arglist)
                {
                    ((IResolver)this).Resolve(ClassNames.SystemRuntimeArgumentHandle.ClassName);
                }

                if (e.Code.IsExternalRealization())
                {
                    ((IResolver)this).Resolve(ClassNames.CIL2JavaVESInstructions.ClassName);
                }

                if (e.Code == ILCode.Ldc_Decimal)
                {
                    ((IResolver)this).Resolve(ClassNames.SystemDecimal.ClassNames);
                }

                if (e.Code == ILCode.Ldtoken)
                {
                    if (e.Operand is TypeReference)
                    {
                        ((IResolver)this).Resolve(ClassNames.SystemRuntimeTypeHandle.ClassName);
                    }
                    else if (e.Operand is FieldReference)
                    {
                        ((IResolver)this).Resolve(ClassNames.SystemRuntimeFieldHandle.ClassName);
                    }
                    else if (e.Operand is MethodReference)
                    {
                        ((IResolver)this).Resolve(ClassNames.SystemRuntimeMethodHandle.ClassName);
                    }
                }

                if (e.Operand is ILVariable)
                {
                    ((IResolver)this).Resolve(((ILVariable)e.Operand).Type, genericArgs);
                }
                if (e.Operand is TypeReference)
                {
                    ((IResolver)this).Resolve((TypeReference)e.Operand, genericArgs);
                }
                if (e.Operand is MethodReference)
                {
                    ((IResolver)this).Resolve((MethodReference)e.Operand, genericArgs);
                }
                if (e.Operand is FieldReference)
                {
                    InterField fld          = ((IResolver)this).Resolve((FieldReference)e.Operand, genericArgs);
                    bool       needAccessor = false;

                    if ((fld.IsPrivate) && (fld.DeclaringType != method.DeclaringType))
                    {
                        needAccessor = true;
                    }
                    else if ((fld.IsProtected) && (fld.DeclaringType != method.DeclaringType) &&
                             (!method.DeclaringType.IsSuper(fld.DeclaringType)))
                    {
                        needAccessor = true;
                    }

                    if (needAccessor)
                    {
                        switch (e.Code)
                        {
                        case ILCode.Ldflda:
                        case ILCode.Ldsflda:
                            if (fld.FieldType.IsValueType)
                            {
                                fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, fld));
                            }
                            break;

                        case ILCode.Ldfld:
                        case ILCode.Ldsfld:
                            fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, fld));
                            break;

                        case ILCode.Stfld:
                        case ILCode.Stsfld:
                            fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Setter, fld));
                            break;
                        }
                    }
                }

                InterType expected = null;
                InterType inferred = null;

                if (e.ExpectedType != null)
                {
                    expected = ((IResolver)this).Resolve(e.ExpectedType, genericArgs);
                }
                if (e.InferredType != null)
                {
                    inferred = ((IResolver)this).Resolve(e.InferredType, genericArgs);
                }

                if ((expected != null) && (expected.IsInterface) && (inferred != null) && (inferred.IsArray))
                {
                    ((IResolver)this).Resolve(ClassNames.ArraysInterfaceAdapterTypeName,
                                              new List <InterGenericArgument>()
                    {
                        new InterGenericArgument(GenericArgumentOwnerType.Type, 0, inferred.ElementType)
                    });
                }
            }
            else if (node is ILWhileLoop)
            {
                ILWhileLoop loop = node as ILWhileLoop;
                ProcessMethodDecencies(method, loop.Condition, genericArgs);
                ProcessMethodDecencies(method, loop.BodyBlock, genericArgs);
            }
            else if (node is ILCondition)
            {
                ILCondition cond = node as ILCondition;
                ProcessMethodDecencies(method, cond.Condition, genericArgs);
                ProcessMethodDecencies(method, cond.TrueBlock, genericArgs);
                ProcessMethodDecencies(method, cond.FalseBlock, genericArgs);
            }
            else if (node is ILSwitch)
            {
                ILSwitch sw = node as ILSwitch;
                ProcessMethodDecencies(method, sw.Condition, genericArgs);
                foreach (var c in sw.CaseBlocks)
                {
                    ProcessMethodDecencies(method, c, genericArgs);
                }
            }
            else if (node is ILFixedStatement)
            {
                ILFixedStatement fs = node as ILFixedStatement;
                foreach (var n in fs.Initializers)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }
                ProcessMethodDecencies(method, fs.BodyBlock, genericArgs);
            }
        }