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); }
public ConstantPool Read(BinaryReader Reader) { ushort Count = Reader.ReadUInt16BE(); ResultPool = new ConstantPool(); FiledConsts = new bool[Count]; FiledConsts[0] = true; RawData = new byte[Count][]; for (int i = 1; i < Count; i++) { Constant Result = null; ConstantTag Tag = (ConstantTag)Reader.ReadByte(); switch (Tag) { case ConstantTag.Utf8: Result = new Constants.Utf8(); break; case ConstantTag.Integer: Result = new Constants.Integer(); break; case ConstantTag.Float: Result = new Constants.Float(); break; case ConstantTag.Long: Result = new Constants.Long(); break; case ConstantTag.Double: Result = new Constants.Double(); break; case ConstantTag.Class: Result = new Constants.Class(); break; case ConstantTag.String: Result = new Constants.String(); break; case ConstantTag.FieldRef: Result = new Constants.FieldRef(); break; case ConstantTag.MethodRef: Result = new Constants.MethodRef(); break; case ConstantTag.InterfaceMethodRef: Result = new Constants.InterfaceMethodRef(); break; case ConstantTag.NameAndType: Result = new Constants.NameAndType(); break; case ConstantTag.MethodHandle: Result = new Constants.MethodHandle(); break; case ConstantTag.MethodType: Result = new Constants.MethodType(); break; case ConstantTag.InvokeDynamic: Result = new Constants.InvokeDynamic(); break; } if (Result == null) { ResultPool.ForceAddConstant(new Constants.Skip(), (ushort)i); Messages.Message(MessageCode.JavaUnknownConstantTag, ((byte)Tag).ToString()); continue; } RawData[i] = Result.ReadData(Reader); ResultPool.ForceAddConstant(Result, (ushort)i); if (Result.Is8Byte()) { FiledConsts[++i] = true; } } for (int i = 1; i < Count; i++) { GetFilledConstant((ushort)i); } return(ResultPool); }
private void CompileUnbox(ILExpression e, ExpectType expect) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); if ((operand.IsPrimitive) || (operand.IsEnum)) { string fieldName = ClassNames.BoxedPrimitiveValueFieldName; if (operand.IsEnum) { fieldName = ClassNames.EnumValueFieldName; } // Generating FieldByRef to value field of boxed class // In java boxed primitived has field named "value" too. // Yes, it is bad hack, but I don't known another way to do this string boxedClass = GetBoxType(operand); string byRefTypeName = byRefController.GetFieldByRefTypeName(operand); Java.Constants.Class constByRefType = new Java.Constants.Class(namesController.TypeNameToJava(byRefTypeName)); Java.Constants.Class constFieldDeclClass = new Java.Constants.Class(namesController.TypeNameToJava(operand)); Java.Constants.String constFieldName = new Java.Constants.String( namesController.FieldNameToJava(fieldName)); MethodRef constFieldByRefCtorRef = byRefController.GetFieldByRefCtorMethodRef(operand); codeGenerator.Add(OpCodes._new, constByRefType, e); codeGenerator.Add(OpCodes.dup, null, e); CompileExpression(e.Arguments[0], ExpectType.Boxed); 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); } else if (operand.IsNullable) { // From ECMA-335, III.4.32 // [Note: Typically, unbox simply computes the address of the value type that is already present // inside of the boxed object. This approach is not possible when unboxing nullable value types. // Because Nullable<T> values are converted to boxed Ts during the box operation, an // implementation often must manufacture a new Nullable<T> on the heap and compute the address // to the newly allocated object. end note] codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(operand)), e) .Add(OpCodes.dup, null, e); CompileUnbox_Any(e, ExpectType.Any); codeGenerator.Add(OpCodes.invokespecial, new MethodRef( namesController.TypeNameToJava(operand), ClassNames.JavaConstructorMethodName, "(" + namesController.GetFieldDescriptor(operand.GenericArguments[0].Type) + ")V")); } else { // By standart, we must compute a ref to value type from it boxed representation // But in CIL2Java boxed value type is ref to it CompileExpression(e.Arguments[0], ExpectType.Any); } }
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); }