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)); }
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))); }
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); }
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 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); } }
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); } }
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); }
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); }
public JavaBytecodeWriter AddArrayLoad(JavaArrayType arrType) { return(AddArrayLoad(arrType, null)); }
public JavaBytecodeWriter AddNewArray(JavaArrayType arrType) { return(AddNewArray(arrType, null)); }
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); } }