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); }
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); }