private void CompileFieldStore(InterField operand, object tag) { if ((operand.IsStatic) && (operand.IsThreadLocal)) { CompileFieldLoad(operand, tag, false); codeGenerator.Add(OpCodes.swap, null, tag); codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangThreadLocal.SetMethodRef, tag); return; } if (((operand.IsPrivate) && (operand.DeclaringType != thisMethod.DeclaringType)) || ((operand.IsProtected) && (operand.DeclaringType != thisMethod.DeclaringType) && (!thisMethod.DeclaringType.IsSuper(operand.DeclaringType)))) { string accessMethodName = operand.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Setter, operand)); MethodRef accessMethod = new MethodRef( namesController.TypeNameToJava(operand.DeclaringType), accessMethodName, "(" + namesController.GetFieldDescriptor(operand.DeclaringType) + namesController.GetFieldDescriptor(operand.FieldType) + ")V"); codeGenerator.Add(Java.OpCodes.invokestatic, accessMethod); } else { codeGenerator.AddInstruction(new JavaInstruction( operand.IsStatic ? Java.OpCodes.putstatic : Java.OpCodes.putfield, new Java.Constants.FieldRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.FieldNameToJava(operand.Name), namesController.GetFieldDescriptor(operand.FieldType)), tag)); } }
private void CompileStfld(ILExpression e, ExpectType expectType) { InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments); bool needDup = ((e.ExpectedType != null) && (expectType != ExpectType.None)); bool boxed = operand.IsStatic && operand.IsThreadLocal; int argIndex = 0; if (e.Code == ILCode.Stfld) CompileExpression(e.Arguments[argIndex++], ExpectType.Reference); CompileExpression(e.Arguments[argIndex++], boxed ? ExpectType.Boxed : GetExpectType(operand)); if (needDup) { JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(operand.FieldType); if (e.Code == ILCode.Stfld) { if (jp.IsDoubleSlot()) codeGenerator.Add(Java.OpCodes.dup2_x1, null, e); else codeGenerator.Add(Java.OpCodes.dup_x1, null, e); } else { if (jp.IsDoubleSlot()) codeGenerator.Add(Java.OpCodes.dup2, null, e); else codeGenerator.Add(Java.OpCodes.dup, null, e); } } CompileFieldStore(operand, e); }
private void CompileFieldLoad(InterField operand, object tag, bool getFromThreadLocal = true) { string fldDesc = namesController.GetFieldDescriptor(operand.FieldType); if ((operand.IsStatic) && (operand.IsThreadLocal)) fldDesc = "L" + namesController.TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";"; if (((operand.IsPrivate) && (operand.DeclaringType != thisMethod.DeclaringType)) || ((operand.IsProtected) && (operand.DeclaringType != thisMethod.DeclaringType) && (!thisMethod.DeclaringType.IsSuper(operand.DeclaringType)))) { string accessMethodName = operand.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, operand)); MethodRef accessMethod = new MethodRef( namesController.TypeNameToJava(operand.DeclaringType), accessMethodName, "(" + (operand.IsStatic ? "" : namesController.GetFieldDescriptor(operand.DeclaringType)) + ")" + fldDesc); codeGenerator.Add(Java.OpCodes.invokestatic, accessMethod); } else { codeGenerator.AddInstruction(new JavaInstruction( operand.IsStatic ? Java.OpCodes.getstatic : Java.OpCodes.getfield, new Java.Constants.FieldRef( namesController.TypeNameToJava(operand.DeclaringType), namesController.FieldNameToJava(operand.Name), fldDesc), tag)); } if ((operand.IsStatic) && (operand.IsThreadLocal) && (getFromThreadLocal)) CompileFieldLoadThreadLocal(operand, tag); }
private void CompilePostIncrement(ILExpression e, ExpectType expect) { int incVal = (int)e.Operand; e = e.Arguments[0]; //TODO: PostIncrement for long and other types if (e.Code == ILCode.Ldloca) { int varIndex = GetVarIndex((ILVariable)e.Operand); codeGenerator .AddLoad(JavaPrimitiveType.Int, varIndex, e) .Add(OpCodes.dup, null, e) .AddIntConst(incVal, e) .Add(OpCodes.iadd, null, e) .AddStore(JavaPrimitiveType.Int, varIndex, e); } else if (e.Code == ILCode.Ldsflda) { InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments); CompileFieldLoad(operand, e); codeGenerator .Add(OpCodes.dup, null, e) .AddIntConst(incVal, e) .Add(OpCodes.iadd, null, e); CompileFieldStore(operand, e); } else if (e.Code == ILCode.Ldflda) { InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments); int tmpVar = GetNextFreeVar(JavaPrimitiveType.Int); CompileExpression(e.Arguments[0], ExpectType.Reference); //this codeGenerator.Add(OpCodes.dup, null, e); CompileFieldLoad(operand, e); codeGenerator .Add(OpCodes.dup, null, e) .AddStore(JavaPrimitiveType.Int, tmpVar, e) .AddIntConst(incVal, e) .Add(OpCodes.iadd, null, e); CompileFieldStore(operand, e); codeGenerator .AddLoad(JavaPrimitiveType.Int, tmpVar, e); FreeVar(tmpVar, JavaPrimitiveType.Int); } else { throw new Exception(); //TODO: another supported postincrements. } // See ICSharpCode.Decompiler\ILAst\PeepholeTransform.cs:IntroducePostIncrement }
private void CompileFieldLoadThreadLocal(InterField operand, object tag) { InterType fldType = operand.FieldType; codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangThreadLocal.GetMethodRef, tag); if ((fldType.IsPrimitive) || (fldType.IsValueType) || (fldType.IsEnum)) CompileUnbox_Any( new ILExpression(ILCode.Unbox_Any, fldType, new ILExpression(ILCode.Nop, null)), GetExpectType(fldType)); else codeGenerator.Add(OpCodes.checkcast, new Java.Constants.Class(namesController.TypeNameToJava( fldType)), tag); }
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); }
private void CompileLdfld(ILExpression e, ExpectType expectType) { InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments); if (e.Code == ILCode.Ldfld) CompileExpression(e.Arguments[0], ExpectType.Reference); CompileFieldLoad(operand, e); if (operand.FieldType.IsValueType) { MethodRef getCopyRef = new MethodRef(namesController.TypeNameToJava(operand.FieldType), ClassNames.ValueTypeGetCopy, "()" + namesController.GetFieldDescriptor(operand.FieldType)); codeGenerator.Add(Java.OpCodes.invokevirtual, getCopyRef, e); } TranslateType(operand.FieldType, expectType, e); }
InterField IResolver.Resolve(FieldReference fldRef, List <InterGenericArgument> genericArgs) { InterType declType = ((IResolver)this).Resolve(fldRef.DeclaringType, genericArgs); InterField result = declType.Fields.Where(F => F.Name == fldRef.Name).FirstOrDefault(); if (result == null) { InterField mapped = null; result = new InterField(fldRef, genericArgs, this, F => mapped = F); if (mapped != null) { return(mapped); } Messages.Verbose("Adding field {0} to compile...", result.ToString()); declType.Fields.Add(result); } return(result); }
public FieldAccessor(FieldAccessorType type, InterField field) { this.Type = type; this.Field = field; }
private ExpectType GetExpectType(InterField fld) { return(GetExpectType(fld.FieldType)); }
private void CompileLdtoken(ILExpression e, ExpectType expect) { if (e.Operand is TypeReference) { InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments); codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeTypeHandle.ClassName)), e) .Add(OpCodes.dup, null, e) .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand)), e) .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeTypeHandle.CtorMethodRef, e); } else if (e.Operand is FieldReference) { InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments); codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeFieldHandle.ClassName)), e) .Add(OpCodes.dup, null, e) .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType)), e) .Add(OpCodes.ldc, new Java.Constants.String(operand.Name), e) .Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredFieldRef, e) .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeFieldHandle.CtorMethodRef, e); } else if (e.Operand is MethodReference) { InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments); codeGenerator .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.SystemRuntimeMethodHandle.ClassName)), e) .Add(OpCodes.dup, null, e) .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType)), e); if (!operand.IsConstructor) { codeGenerator.Add(OpCodes.ldc, new Java.Constants.String(operand.NewName), e); } codeGenerator .AddIntConst(operand.Parameters.Count, e) .Add(OpCodes.anewarray, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.JavaLangClass.ClassName)), e); for (int i = 0; i < operand.Parameters.Count; i++) { codeGenerator .Add(OpCodes.dup) .AddIntConst(i, e) .Add(OpCodes.ldc, new Java.Constants.Class(namesController.TypeNameToJava(operand.Parameters[i].Type))) .Add(OpCodes.aastore, null, e); } if (operand.IsConstructor) { codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredConstructorRef, e); } else { codeGenerator.Add(OpCodes.invokevirtual, ClassNames.JavaLangClass.getDeclaredMethodRef, e); } codeGenerator.Add(OpCodes.invokespecial, ClassNames.SystemRuntimeMethodHandle.CtorMethodRef, e); } }
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); }
private void ProcessMethodDecencies(InterMethod method, ILNode node, List <InterGenericArgument> genericArgs) { if (node is ILBlock) { ILBlock block = node as ILBlock; foreach (ILNode n in block.Body) { ProcessMethodDecencies(method, n, genericArgs); } } else if (node is ILBasicBlock) { ILBasicBlock block = node as ILBasicBlock; foreach (ILNode n in block.Body) { ProcessMethodDecencies(method, n, genericArgs); } } else if (node is ILTryCatchBlock) { ILTryCatchBlock block = node as ILTryCatchBlock; foreach (ILNode n in block.TryBlock.Body) { ProcessMethodDecencies(method, n, genericArgs); } if (block.FaultBlock != null) { foreach (ILNode n in block.FaultBlock.Body) { ProcessMethodDecencies(method, n, genericArgs); } } if (block.FinallyBlock != null) { foreach (ILNode n in block.FinallyBlock.Body) { ProcessMethodDecencies(method, n, genericArgs); } } foreach (var catchBlock in block.CatchBlocks) { ((IResolver)this).Resolve(catchBlock.ExceptionType, genericArgs); ProcessMethodDecencies(method, catchBlock, genericArgs); } } else if (node is ILExpression) { ILExpression e = node as ILExpression; foreach (var n in e.Arguments) { ProcessMethodDecencies(method, n, genericArgs); } if ((e.Code == ILCode.Mkrefany) || (e.Code == ILCode.Refanyval)) { ((IResolver)this).Resolve(ClassNames.SystemTypedReference.ClassName); } if (e.Code == ILCode.Refanytype) { ((IResolver)this).Resolve(ClassNames.SystemTypedReference.ClassName); ((IResolver)this).Resolve(ClassNames.SystemRuntimeTypeHandle.ClassName); } if (e.Code == ILCode.Arglist) { ((IResolver)this).Resolve(ClassNames.SystemRuntimeArgumentHandle.ClassName); } if (e.Code.IsExternalRealization()) { ((IResolver)this).Resolve(ClassNames.CIL2JavaVESInstructions.ClassName); } if (e.Code == ILCode.Ldc_Decimal) { ((IResolver)this).Resolve(ClassNames.SystemDecimal.ClassNames); } if (e.Code == ILCode.Ldtoken) { if (e.Operand is TypeReference) { ((IResolver)this).Resolve(ClassNames.SystemRuntimeTypeHandle.ClassName); } else if (e.Operand is FieldReference) { ((IResolver)this).Resolve(ClassNames.SystemRuntimeFieldHandle.ClassName); } else if (e.Operand is MethodReference) { ((IResolver)this).Resolve(ClassNames.SystemRuntimeMethodHandle.ClassName); } } if (e.Operand is ILVariable) { ((IResolver)this).Resolve(((ILVariable)e.Operand).Type, genericArgs); } if (e.Operand is TypeReference) { ((IResolver)this).Resolve((TypeReference)e.Operand, genericArgs); } if (e.Operand is MethodReference) { ((IResolver)this).Resolve((MethodReference)e.Operand, genericArgs); } if (e.Operand is FieldReference) { InterField fld = ((IResolver)this).Resolve((FieldReference)e.Operand, genericArgs); bool needAccessor = false; if ((fld.IsPrivate) && (fld.DeclaringType != method.DeclaringType)) { needAccessor = true; } else if ((fld.IsProtected) && (fld.DeclaringType != method.DeclaringType) && (!method.DeclaringType.IsSuper(fld.DeclaringType))) { needAccessor = true; } if (needAccessor) { switch (e.Code) { case ILCode.Ldflda: case ILCode.Ldsflda: if (fld.FieldType.IsValueType) { fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, fld)); } break; case ILCode.Ldfld: case ILCode.Ldsfld: fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, fld)); break; case ILCode.Stfld: case ILCode.Stsfld: fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Setter, fld)); break; } } } InterType expected = null; InterType inferred = null; if (e.ExpectedType != null) { expected = ((IResolver)this).Resolve(e.ExpectedType, genericArgs); } if (e.InferredType != null) { inferred = ((IResolver)this).Resolve(e.InferredType, genericArgs); } if ((expected != null) && (expected.IsInterface) && (inferred != null) && (inferred.IsArray)) { ((IResolver)this).Resolve(ClassNames.ArraysInterfaceAdapterTypeName, new List <InterGenericArgument>() { new InterGenericArgument(GenericArgumentOwnerType.Type, 0, inferred.ElementType) }); } } else if (node is ILWhileLoop) { ILWhileLoop loop = node as ILWhileLoop; ProcessMethodDecencies(method, loop.Condition, genericArgs); ProcessMethodDecencies(method, loop.BodyBlock, genericArgs); } else if (node is ILCondition) { ILCondition cond = node as ILCondition; ProcessMethodDecencies(method, cond.Condition, genericArgs); ProcessMethodDecencies(method, cond.TrueBlock, genericArgs); ProcessMethodDecencies(method, cond.FalseBlock, genericArgs); } else if (node is ILSwitch) { ILSwitch sw = node as ILSwitch; ProcessMethodDecencies(method, sw.Condition, genericArgs); foreach (var c in sw.CaseBlocks) { ProcessMethodDecencies(method, c, genericArgs); } } else if (node is ILFixedStatement) { ILFixedStatement fs = node as ILFixedStatement; foreach (var n in fs.Initializers) { ProcessMethodDecencies(method, n, genericArgs); } ProcessMethodDecencies(method, fs.BodyBlock, genericArgs); } }