示例#1
0
        public JavaBytecodeWriter AddArrayLoad(JavaArrayType arrType, object tag)
        {
            Java.OpCodes opcode = Java.OpCodes.aaload;

            switch (arrType)
            {
            case JavaArrayType.Boolean: opcode = Java.OpCodes.baload; break;

            case JavaArrayType.Byte: opcode = Java.OpCodes.baload; break;

            case JavaArrayType.Char: opcode = Java.OpCodes.caload; break;

            case JavaArrayType.Double: opcode = Java.OpCodes.daload; break;

            case JavaArrayType.Float: opcode = Java.OpCodes.faload; break;

            case JavaArrayType.Int: opcode = Java.OpCodes.iaload; break;

            case JavaArrayType.Long: opcode = Java.OpCodes.laload; break;

            case JavaArrayType.Short: opcode = Java.OpCodes.saload; break;
            }

            return(Add(opcode, null, tag));
        }
示例#2
0
 public JavaBytecodeWriter AddNewArray(JavaArrayType arrType, object tag)
 {
     if (arrType == JavaArrayType.Ref)
     {
         return(null);    //TODO: Must throw exception
     }
     return(AddInstruction(new JavaInstruction(Java.OpCodes.newarray, (byte)arrType, tag)));
 }
示例#3
0
        private void CompileAddressOf(ILExpression e, ExpectType expectType)
        {
            e = e.Arguments[0];

            if (e.Operand is TypeReference)
            {
                //ValueType
                CompileExpression(e, expectType);
                return;
            }
            else if (!(e.Operand is MethodReference))
            {
                CompileExpression(e, ExpectType.Boxed);
                return;
            }

            InterMethod method  = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);
            InterType   operand = method.DeclaringType;

            if (!operand.IsArray)
            {
                //Getter
                if (method.ReturnParameter.Type.IsPrimitive)
                {
                    CompileExpression(e, ExpectType.Boxed);
                }
                else
                {
                    CompileExpression(e, GetExpectType(method.ReturnParameter));
                }
                return;
            }

            JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand);

            string arrayByRefName = byRefController.GetArrayByRefTypeName(operand);

            Java.Constants.Class arrayByRefNameClass =
                new Java.Constants.Class(namesController.TypeNameToJava(arrayByRefName));
            Java.Constants.MethodRef arrayByRefInitMethodRef =
                byRefController.GetArrayByRefCtorMethodRef(operand);

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

            CompileExpression(e.Arguments[0], ExpectType.Reference);    //array
            CompileExpression(e.Arguments[1], ExpectType.Primitive);    //first index

            for (int i = 0; i < operand.ArrayRank - 1; i++)
            {
                codeGenerator.Add(Java.OpCodes.aaload, null, e);
                CompileExpression(e.Arguments[i + 2], ExpectType.Primitive);
            }

            codeGenerator.Add(OpCodes.invokespecial, arrayByRefInitMethodRef, e);
        }
示例#4
0
        private void CompileStelem(ILExpression e, ExpectType expect)
        {
            TypeReference typeRef = e.Operand as TypeReference ?? e.InferredType;

            InterType operand = null;

            if (typeRef != null)
            {
                operand = resolver.Resolve(typeRef, thisMethod.FullGenericArguments);
            }
            else
            {
                switch (e.Code)
                {
                case ILCode.Stelem_I: operand = InterType.PrimitiveTypes[(int)(Program.AsX64 ? PrimitiveType.Int64 : PrimitiveType.Int32)]; break;

                case ILCode.Stelem_I1: operand = InterType.PrimitiveTypes[(int)PrimitiveType.SByte]; break;

                case ILCode.Stelem_I2: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int16]; break;

                case ILCode.Stelem_I4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int32]; break;

                case ILCode.Stelem_I8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int64]; break;

                case ILCode.Stelem_R4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Single]; break;

                case ILCode.Stelem_R8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Double]; break;
                }
            }

            JavaPrimitiveType valueJPType = operand != null?JavaHelpers.InterTypeToJavaPrimitive(operand) : JavaPrimitiveType.Ref;

            JavaArrayType arrType         = JavaHelpers.JavaPrimitiveToArrayType(valueJPType);
            ExpectType    valueExpectType = operand != null?GetExpectType(operand) : ExpectType.Reference;

            bool needDup = ((e.ExpectedType != null) && (expect != ExpectType.None));

            CompileExpression(e.Arguments[0], ExpectType.Reference); //array
            CompileExpression(e.Arguments[1], ExpectType.Primitive); //index
            CompileExpression(e.Arguments[2], valueExpectType);      //value

            if (needDup)
            {
                if (valueJPType.IsDoubleSlot())
                {
                    codeGenerator.Add(Java.OpCodes.dup2_x2, null, e);
                }
                else
                {
                    codeGenerator.Add(Java.OpCodes.dup_x2, null, e);
                }
            }

            codeGenerator.AddArrayStore(arrType, e);
        }
示例#5
0
        private void CompileLdelem(ILExpression e, ExpectType expect)
        {
            TypeReference typeRef = e.Operand as TypeReference ?? e.InferredType;
            InterType     operand = null;

            if (typeRef != null)
            {
                operand = resolver.Resolve(typeRef, thisMethod.FullGenericArguments);
            }
            else
            {
                switch (e.Code)
                {
                case ILCode.Ldelem_I: operand = InterType.PrimitiveTypes[(int)(Program.AsX64 ? PrimitiveType.Int64 : PrimitiveType.Int32)]; break;

                case ILCode.Ldelem_I1: operand = InterType.PrimitiveTypes[(int)PrimitiveType.SByte]; break;

                case ILCode.Ldelem_I2: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int16]; break;

                case ILCode.Ldelem_I4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int32]; break;

                case ILCode.Ldelem_I8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int64]; break;

                case ILCode.Ldelem_R4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Single]; break;

                case ILCode.Ldelem_R8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Double]; break;

                case ILCode.Ldelem_U1: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Byte]; break;

                case ILCode.Ldelem_U2: operand = InterType.PrimitiveTypes[(int)PrimitiveType.UInt16]; break;

                case ILCode.Ldelem_U4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.UInt32]; break;
                }
            }
            JavaArrayType arrType = operand != null?JavaHelpers.InterTypeToJavaArrayType(operand) : JavaArrayType.Ref;

            CompileExpression(e.Arguments[0], ExpectType.Reference);    //array
            CompileExpression(e.Arguments[1], ExpectType.Primitive);    //index

            codeGenerator.AddArrayLoad(arrType, e);

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

            if (operand != null)
            {
                TranslateType(operand, expect, e);
            }
        }
示例#6
0
        private void CompileArrayGet(ILExpression e, ExpectType expect)
        {
            InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);

            JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand.DeclaringType.ElementType);

            codeGenerator.AddArrayLoad(arrType, e);

            if (operand.DeclaringType.ElementType.IsValueType)
            {
                MethodRef getCopyRef = new MethodRef(namesController.TypeNameToJava(operand.DeclaringType.ElementType),
                                                     ClassNames.ValueTypeGetCopy, "()" + namesController.GetFieldDescriptor(operand.DeclaringType.ElementType));
                codeGenerator.Add(Java.OpCodes.invokevirtual, getCopyRef, e);
            }
        }
示例#7
0
        private void CompileLdelema(ILExpression e, ExpectType expectType)
        {
            TypeReference typeRef = e.Operand as TypeReference;
            InterType     operand = resolver.Resolve(typeRef, thisMethod.FullGenericArguments);
            JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand);

            if (operand.IsValueType)
            {
                CompileExpression(e.Arguments[0], ExpectType.Reference);    //array
                CompileExpression(e.Arguments[1], ExpectType.Primitive);    //index

                codeGenerator.Add(OpCodes.aaload, null, e);
                return;
            }

            if ((operand.IsPrimitive) && (expectType == ExpectType.Reference))
            {
                CompileExpression(e.Arguments[0], ExpectType.Reference);    //array
                CompileExpression(e.Arguments[1], ExpectType.Primitive);    //index

                codeGenerator.AddArrayLoad(arrType);
                TranslateType(operand, ExpectType.Boxed, e);
                return;
            }

            string arrayByRefName = byRefController.GetArrayByRefTypeName(operand);

            Java.Constants.Class arrayByRefNameClass =
                new Java.Constants.Class(namesController.TypeNameToJava(arrayByRefName));
            Java.Constants.MethodRef arrayByRefInitMethodRef =
                byRefController.GetArrayByRefCtorMethodRef(operand);

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

            CompileExpression(e.Arguments[0], ExpectType.Reference);    //array
            CompileExpression(e.Arguments[1], ExpectType.Primitive);    //index

            codeGenerator.Add(OpCodes.invokespecial, arrayByRefInitMethodRef, e);
        }
示例#8
0
        private void CompileArraySet(ILExpression e, ExpectType expect)
        {
            InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);

            CompileExpression(e.Arguments.Last(), GetExpectType(operand.DeclaringType.ElementType));

            JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand.DeclaringType);

            bool needDup = ((e.ExpectedType != null) && (expect != ExpectType.None));

            if (needDup)
            {
                if (JavaHelpers.InterTypeToJavaPrimitive(operand.DeclaringType).IsDoubleSlot())
                {
                    codeGenerator.Add(Java.OpCodes.dup2_x2, null, e);
                }
                else
                {
                    codeGenerator.Add(Java.OpCodes.dup_x2, null, e);
                }
            }

            codeGenerator.AddArrayStore(arrType, e);
        }
示例#9
0
 public JavaBytecodeWriter AddArrayLoad(JavaArrayType arrType)
 {
     return(AddArrayLoad(arrType, null));
 }
示例#10
0
 public JavaBytecodeWriter AddNewArray(JavaArrayType arrType)
 {
     return(AddNewArray(arrType, null));
 }
示例#11
0
        private void CompileNewarr(ILExpression e, ExpectType expect)
        {
            InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments);
            InterType element = operand;

            if (element.IsArray)
            {
                element = element.ElementType;
            }

            Java.Constants.Class operandRef       = new Java.Constants.Class(namesController.TypeNameToJava(element));
            MethodRef            valueTypeInitRef = new MethodRef(operandRef.Value, ClassNames.JavaConstructorMethodName, "()V");

            JavaArrayType arrayType = JavaHelpers.InterTypeToJavaArrayType(operand);

            if (e.Code == ILCode.Newarr)
            {
                CompileExpression(e.Arguments[0], ExpectType.Primitive);
            }
            else
            {
                if (operand.Dimesnsions[0].LowerBound != 0)
                {
                    Messages.Message(MessageCode.NotZeroLowerBound, operand.Fullname);
                }
                codeGenerator.AddIntConst(operand.Dimesnsions[0].UpperBound.Value, e);
            }

            if (arrayType == JavaArrayType.Ref)
            {
                codeGenerator.Add(Java.OpCodes.anewarray, operandRef, e);
            }
            else
            {
                codeGenerator.AddNewArray(arrayType, e);
            }

            if (e.Code == ILCode.InitArray)
            {
                for (int i = 0; i < e.Arguments.Count; i++)
                {
                    if ((e.Arguments[i].Code == ILCode.DefaultValue) && (!element.IsValueType))
                    {
                        continue;
                    }

                    codeGenerator.Add(Java.OpCodes.dup, null, e);
                    codeGenerator.AddIntConst(i, e);
                    CompileExpression(e.Arguments[i], GetExpectType(element));
                    codeGenerator.AddArrayStore(arrayType, e);
                }
            }
            else if (element.IsValueType)
            {
                int arrayTmpStore  = GetNextFreeVar(JavaPrimitiveType.Ref);
                int arrayLengthTmp = GetNextFreeVar(JavaPrimitiveType.Int);

                string labelPrefix = rnd.Next().ToString();
                string loopLabel   = labelPrefix + "loop";
                string endLabel    = labelPrefix + "end";

                codeGenerator
                .AddStore(JavaPrimitiveType.Ref, arrayTmpStore, e)
                .AddLoad(JavaPrimitiveType.Ref, arrayTmpStore, e)
                .Add(Java.OpCodes.arraylength, null, e)
                .AddStore(JavaPrimitiveType.Int, arrayLengthTmp, e)

                // while (arrayLengthTmp > 0) arrayTmpStore[--arrayLengthTmp] = new valType();
                .Label(loopLabel)
                .AddLoad(JavaPrimitiveType.Int, arrayLengthTmp, e)
                .Add(Java.OpCodes.ifle, endLabel, e)
                .AddIInc((ushort)arrayLengthTmp, -1, e)
                .AddLoad(JavaPrimitiveType.Ref, arrayTmpStore, e)
                .AddLoad(JavaPrimitiveType.Int, arrayLengthTmp, e)
                .Add(Java.OpCodes._new, operandRef, e)
                .Add(Java.OpCodes.dup, null, e)
                .Add(Java.OpCodes.invokespecial, valueTypeInitRef, e)
                .Add(Java.OpCodes.aastore, null, e)
                .Add(Java.OpCodes._goto, loopLabel, e)
                .Label(endLabel)


                .AddLoad(JavaPrimitiveType.Ref, arrayTmpStore, e);

                FreeVar(arrayTmpStore, JavaPrimitiveType.Ref);
                FreeVar(arrayLengthTmp, JavaPrimitiveType.Int);
            }
        }