Esempio n. 1
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);
        }
Esempio n. 2
0
        private void GenerateArrayByRefType(JavaPrimitiveType type)
        {
            GenerateBaseByRefType(type);

            string valueFieldDesc = "L" + TypeNameToJava(ClassNames.JavaObject) + ";";

            if (type != JavaPrimitiveType.Ref)
            {
                valueFieldDesc = JavaPrimitive2FieldChar[(int)type].ToString();
            }

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

            Field arrayField = new Field();

            arrayField.AccessFlags = FieldAccessFlags.Private;
            arrayField.Name        = "array";
            arrayField.Descriptor  = "[" + valueFieldDesc;
            javaClass.Fields.Add(arrayField);
            FieldRef arrayFieldRef = new FieldRef(javaClass.ThisClass, arrayField.Name, arrayField.Descriptor);

            Field indexField = new Field();

            indexField.AccessFlags = FieldAccessFlags.Private;
            indexField.Name        = "index";
            indexField.Descriptor  = "I";
            javaClass.Fields.Add(indexField);
            FieldRef indexFieldRef = new FieldRef(javaClass.ThisClass, indexField.Name, indexField.Descriptor);

            Field valueField = new Field();

            valueField.AccessFlags = FieldAccessFlags.Private;
            valueField.Name        = "value";
            valueField.Descriptor  = valueFieldDesc;
            javaClass.Fields.Add(valueField);
            FieldRef valueFieldRef = new FieldRef(javaClass.ThisClass, valueField.Name, valueField.Descriptor);

            Java.Constants.MethodRef superCtorRef =
                new Java.Constants.MethodRef(javaClass.SuperClass, ClassNames.JavaConstructorMethodName, "()V");

            Method ctorMethod = new Method();

            ctorMethod.AccessFlags = MethodAccessFlags.Public;
            ctorMethod.Name        = ClassNames.JavaConstructorMethodName;
            ctorMethod.Descriptor  = "(" + arrayField.Descriptor + "I)V";
            ctorMethod.Attributes.Add(new JavaBytecodeWriter()
                                      .Add(OpCodes.aload_0)
                                      .Add(OpCodes.invokespecial, superCtorRef)

                                      //this.array = array
                                      .Add(OpCodes.aload_0)
                                      .Add(OpCodes.aload_1)
                                      .Add(OpCodes.putfield, arrayFieldRef)

                                      //this.index = index
                                      .Add(OpCodes.aload_0)
                                      .Add(OpCodes.iload_2)
                                      .Add(OpCodes.putfield, indexFieldRef)

                                      //this.value = array[index]
                                      .Add(OpCodes.aload_0)
                                      .Add(OpCodes.aload_1)
                                      .Add(OpCodes.iload_2)
                                      .AddArrayLoad(JavaHelpers.JavaPrimitiveToArrayType(type))
                                      .Add(OpCodes.putfield, valueFieldRef)

                                      .Add(OpCodes._return)

                                      .End(javaClass.ConstantPool));
            javaClass.Methods.Add(ctorMethod);

            Java.Method getMethod = new Method();
            getMethod.AccessFlags = Java.MethodAccessFlags.Public;
            getMethod.Name        = ClassNames.ByRef.GetValueMethodName;
            getMethod.Descriptor  = "()" + valueFieldDesc;
            getMethod.Attributes.Add(new JavaBytecodeWriter()
                                     //return this.value
                                     .Add(OpCodes.aload_0)
                                     .Add(OpCodes.getfield, valueFieldRef)
                                     .AddReturn(type)
                                     .End(javaClass.ConstantPool));
            javaClass.Methods.Add(getMethod);

            Java.Method setMethod = new Method();
            setMethod.AccessFlags = MethodAccessFlags.Public;
            setMethod.Name        = ClassNames.ByRef.SetValueMethodName;
            setMethod.Descriptor  = "(" + valueFieldDesc + ")V";
            setMethod.Attributes.Add(new JavaBytecodeWriter()
                                     //this.array[this.index] = value
                                     .Add(OpCodes.aload_0)
                                     .Add(OpCodes.getfield, arrayFieldRef)
                                     .Add(OpCodes.aload_0)
                                     .Add(OpCodes.getfield, indexFieldRef)
                                     .AddLoad(type, 1)
                                     .AddArrayStore(JavaHelpers.JavaPrimitiveToArrayType(type))

                                     //this.value = value
                                     .Add(OpCodes.aload_0)
                                     .AddLoad(type, 1)
                                     .Add(OpCodes.putfield, valueFieldRef)

                                     .AddReturn(JavaPrimitiveType.Void)

                                     .End(javaClass.ConstantPool));
            javaClass.Methods.Add(setMethod);

            WriteClass(javaClass);
        }