Example #1
0
        private void CompileOverridedMethods(InterType type, InterType iface)
        {
            var renamedMethods = iface.Methods.Where(I => I.NewName != I.Name);

            foreach (InterMethod renamedMethod in renamedMethods)
            {
                InterMethod overrideMethod = type.Methods.Where(M => M.Overrides.Contains(renamedMethod)).FirstOrDefault();
                if (overrideMethod == null)
                {
                    overrideMethod = type.Methods.Where(M => M.IsSame(renamedMethod)).FirstOrDefault();
                }

                if (overrideMethod == null)
                {
                    // In CIL interfaces didn't duplicate methods from base interfaces
                    if (!type.IsInterface)
                    {
                        Messages.Message(MessageCode.CantFindInterfaceImplMethod, renamedMethod.ToString(), type.Fullname);
                    }

                    continue;
                }

                GenerateInterfaceMethodAccessor(renamedMethod, overrideMethod);
            }
        }
Example #2
0
        private string GetMethodDescriptor(InterMethod method)
        {
            if ((Program.MethodPointersType == MethodPointerImplementation.Fast) && (method.IsConstructor) &&
                (method.DeclaringType.IsDelegate))
            {
                return("(L" + TypeNameToJava(ClassNames.JavaObject) + ";L" +
                       TypeNameToJava(((INamesController)this).GetMethodPointerInterface(
                                          method.DeclaringType.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault())) +
                       ";)V");
            }

            StringBuilder result = new StringBuilder("(");

            foreach (InterParameter param in method.Parameters)
            {
                result.Append(GetFieldDescriptor(param.Type));
            }

            if (method.IsVarArg)
            {
                result.Append("[L" + TypeNameToJava(ClassNames.JavaObject) + ";");
            }

            result
            .Append(')')
            .Append(GetFieldDescriptor(method.ReturnParameter.Type));
            return(result.ToString());
        }
Example #3
0
        InterMethod IResolver.Resolve(MethodReference methodRef, List <InterGenericArgument> genericArgs)
        {
            InterMethod founded = null;
            InterMethod tmp     = new InterMethod(methodRef, genericArgs, this, M => founded = M);

            if (founded == null)
            {
                Messages.Verbose("Adding method {0} to compile...", tmp.ToString());
                tmp.DeclaringType.Methods.Add(tmp);
                founded = tmp;

                var unionedGenericArgs = tmp.FullGenericArguments;

                if (tmp.HasBody)
                {
                    MethodDefinition methodDef = tmp.Body.Method;

                    ILAstBuilder builder = new ILAstBuilder();
                    ILBlock      ilBody  = new ILBlock();

                    DecompilerContext context = new DecompilerContext(methodDef.Module)
                    {
                        CurrentType = methodDef.DeclaringType, CurrentMethod = methodDef
                    };
                    Utils.SetDecompillerSettings(context.Settings);

                    ilBody.Body = builder.Build(methodDef, true, context);
                    new ILAstOptimizer().Optimize(context, ilBody);
                    ProcessMethodDecencies(tmp, ilBody, tmp.FullGenericArguments);
                }
            }

            return(founded);
        }
Example #4
0
        public bool Equals(InterMethod m)
        {
            if (declType != m.declType)
            {
                return(false);
            }
            if (name != m.name)
            {
                return(false);
            }
            if (returnParam.Type != m.returnParam.Type)
            {
                return(false);
            }
            if (parameters.Count != m.parameters.Count)
            {
                return(false);
            }
            for (int i = 0; i < parameters.Count; i++)
            {
                if (parameters[i].Type != m.parameters[i].Type)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #5
0
 public CodeCompiler(IResolver resolver, INamesController namesController, IByRefController byRefController,
                     InterMethod method, Java.ConstantPool constsPool)
 {
     this.resolver        = resolver;
     this.namesController = namesController;
     this.byRefController = byRefController;
     this.thisMethod      = method;
     this.constsPool      = constsPool;
 }
Example #6
0
        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);
        }
Example #7
0
        public override bool Equals(object obj)
        {
            InterMethod o = obj as InterMethod;

            if (o == null)
            {
                return(false);
            }
            return(Equals(o));
        }
        string INamesController.GetMethodPointerInterface(InterMethod method)
        {
            string result = ClassNames.MethodPointerPrefix + escapeTypeName(method.ReturnParameter.Type.Fullname) + "_"
                            + string.Join("_", method.Parameters.Select(P => escapeTypeName(P.Type.Fullname)).ToArray());

            if (!methodPointerInterfaces.ContainsKey(result))
            {
                methodPointerInterfaces.Add(result, method);
            }

            return(result);
        }
Example #9
0
        private void RenameMethod(InterMethod method, string newName)
        {
            method.NewName = newName;

            foreach (InterType derivedType in typesToCompile.Where(T => T.BaseType == method.DeclaringType))
            {
                InterMethod derivedMethod = derivedType.Methods.Where(M => M.IsSame(method)).FirstOrDefault();

                if (derivedMethod != null)
                {
                    RenameMethod(derivedMethod, newName);
                }
            }
        }
Example #10
0
        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);
            }
        }
Example #11
0
        private void CompileNewmultiarray(ILExpression e, ExpectType expect)
        {
            InterMethod ctor    = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);
            InterType   arrType = ctor.DeclaringType;

            for (int i = 0; i < arrType.ArrayRank; i++)
            {
                CompileExpression(e.Arguments[i], ExpectType.Primitive);
            }

            //TODO: lower and apper bounds

            codeGenerator.AddMultianewarray(new Java.Constants.Class(namesController.GetFieldDescriptor(arrType)),
                                            (byte)arrType.ArrayRank);
        }
Example #12
0
        private void CompileDelegateBeginInvoke(InterType type)
        {
            InterMethod beginInvokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateBeginInvokeMethodName).FirstOrDefault();

            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final;
            result.Name        = ClassNames.DelegateBeginInvokeMethodName;
            result.Descriptor  = GetMethodDescriptor(beginInvokeMethod);

            string runnerName = currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName;

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            codeWriter
            .Add(OpCodes._new, new Java.Constants.Class(TypeNameToJava(ClassNames.SystemRuntimeRemotingMessagingAsyncResult.ClassName)))
            .Add(OpCodes.dup)
            .Add(OpCodes._new, new Java.Constants.Class(runnerName))
            .Add(OpCodes.dup)
            .Add(OpCodes.aload_0);

            int    paramsCount       = beginInvokeMethod.Parameters.Count;
            string paramsDescriptors = "";

            for (int i = 0; i < paramsCount - 2; i++)
            {
                InterType paramType = beginInvokeMethod.Parameters[i].Type;

                codeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(paramType), i + 1);
                paramsDescriptors += GetFieldDescriptor(paramType);
            }

            codeWriter
            .Add(OpCodes.invokespecial, new MethodRef(runnerName, ClassNames.JavaConstructorMethodName,
                                                      "(" + GetFieldDescriptor(type) + paramsDescriptors + ")V"))
            .Add(OpCodes.aload_0)
            .AddLoad(JavaPrimitiveType.Ref, paramsCount - 1)
            .AddLoad(JavaPrimitiveType.Ref, paramsCount)
            .Add(OpCodes.invokespecial, ClassNames.SystemRuntimeRemotingMessagingAsyncResult.CtorMethodRef)
            .Add(OpCodes.areturn);
            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }
Example #13
0
        //Find this() or super() calls in ctor to move it to begin of method
        private void PreprocessorFindAndMoveSuperOrThisCalls()
        {
            if (!thisMethod.IsConstructor)
            {
                return;
            }

            ILExpression call = null;

            foreach (ILNode node in ilBody.Body)
            {
                ILExpression e = node as ILExpression;
                if (e == null)
                {
                    continue;
                }
                if (e.Code != ILCode.Call)
                {
                    continue;
                }

                InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);
                if (!operand.IsConstructor)
                {
                    continue;
                }
                if (operand.DeclaringType != thisMethod.DeclaringType)
                {
                    if (operand.DeclaringType != thisMethod.DeclaringType.BaseType)
                    {
                        continue;
                    }
                }

                call = e;
                break;
            }

            if (call != null)
            {
                ilBody.Body.Remove(call);
                firstCall = call;
            }
        }
Example #14
0
        private void CompileNewobj(ILExpression e, ExpectType expect)
        {
            InterMethod ctor = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);

            if (ctor.DeclaringType.IsArray)
            {
                CompileNewmultiarray(e, expect);
            }
            else
            {
                Java.Constants.Class declTypeClassRef = new Java.Constants.Class(
                    namesController.TypeNameToJava(ctor.DeclaringType));

                codeGenerator
                .Add(Java.OpCodes._new, declTypeClassRef, e)
                .Add(Java.OpCodes.dup, null, e);

                CompileCall(e, expect);
            }
        }
        private void CompileIntrinsicCreatePointerToArray(ILExpression e)
        {
            InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);
            InterType   refType = operand.GenericArguments[0].Type;

            string arrayByRefName = byRefController.GetArrayByRefTypeName(refType);

            Java.Constants.Class arrayByRefNameClass =
                new Java.Constants.Class(namesController.TypeNameToJava(arrayByRefName));
            Java.Constants.MethodRef arrayByRefInitMethodRef =
                byRefController.GetArrayByRefCtorMethodRef(refType);

            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);
        }
Example #16
0
        private void CompileArrayCall(ILExpression e, ExpectType expect)
        {
            InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);

            CompileExpression(e.Arguments[0], ExpectType.Reference);    //array
            CompileExpression(e.Arguments[1], ExpectType.Primitive);    //first index

            for (int i = 0; i < operand.DeclaringType.ArrayRank - 1; i++)
            {
                codeGenerator.Add(Java.OpCodes.aaload, null, e);
                CompileExpression(e.Arguments[i + 2], ExpectType.Primitive);
            }

            if (operand.Name == "Set")
            {
                CompileArraySet(e, expect);
            }
            else if (operand.Name == "Get")
            {
                CompileArrayGet(e, expect);
            }
        }
Example #17
0
        private void CompileLdftn(ILExpression e, ExpectType expect)
        {
            InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);

            string methodPointerClass = GenerateMethodPointerClass(operand);

            if (Program.MethodPointersType == MethodPointerImplementation.Fast)
            {
                Java.Constants.Class mpClassRef = new Java.Constants.Class(namesController.TypeNameToJava(methodPointerClass));
                MethodRef            mpInitRef  = new MethodRef(mpClassRef.Value, ClassNames.JavaConstructorMethodName, "()V");

                codeGenerator
                .Add(OpCodes._new, mpClassRef, e)
                .Add(OpCodes.dup, null, e)
                .Add(OpCodes.invokespecial, mpInitRef, e);
            }
            else
            {
                codeGenerator
                .Add(OpCodes.ldc, new Java.Constants.String(methodPointerClass.Replace('/', '$')))
                .Add(OpCodes.invokestatic, ClassNames.GlobalMethodPointersAdd);
            }
        }
Example #18
0
        private void GenerateInterfaceMethodAccessor(InterMethod ifaceMethod, InterMethod typeMethod)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            if (ifaceMethod.IsVarArg)
            {
                result.AccessFlags |= MethodAccessFlags.VarArgs;
            }
            result.Name       = MethodNameToJava(ifaceMethod.NewName);
            result.Descriptor = GetMethodDescriptor(ifaceMethod);

            JavaBytecodeWriter code = new JavaBytecodeWriter();

            code.Add(OpCodes.aload_0);

            for (int i = 0; i < ifaceMethod.Parameters.Count; i++)
            {
                code.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(ifaceMethod.Parameters[i].Type), i + 1);
            }

            MethodRef typeMethodRef = new MethodRef(TypeNameToJava(typeMethod.DeclaringType.Fullname),
                                                    MethodNameToJava(typeMethod.NewName), GetMethodDescriptor(typeMethod));

            if (typeMethod.IsPrivate)
            {
                code.Add(OpCodes.invokespecial, typeMethodRef);
            }
            else
            {
                code.Add(OpCodes.invokevirtual, typeMethodRef);
            }
            code.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(ifaceMethod.ReturnParameter.Type));
            result.Attributes.Add(code.End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }
Example #19
0
        private void CompileDelegateEndInvoke(InterType type)
        {
            InterMethod endInvokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateEndInvokeMethodName).FirstOrDefault();

            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final;
            result.Name        = ClassNames.DelegateEndInvokeMethodName;
            result.Descriptor  = GetMethodDescriptor(endInvokeMethod);

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            codeWriter
            .Add(OpCodes.aload_1)
            .Add(OpCodes.checkcast, new Java.Constants.Class(TypeNameToJava(ClassNames.SystemRuntimeRemotingMessagingAsyncResult.ClassName)))
            .Add(OpCodes.invokevirtual, ClassNames.SystemRuntimeRemotingMessagingAsyncResult.EndInvokeMethodRef);

            if (endInvokeMethod.ReturnParameter.Type.PrimitiveType == PrimitiveType.Void)
            {
                codeWriter.Add(OpCodes.pop);
            }
            else
            {
                codeWriter
                .Add(OpCodes.checkcast, new Java.Constants.Class(currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName))
                .Add(OpCodes.getfield, new Java.Constants.FieldRef(
                         currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName,
                         ClassNames.DelegateRunnerResultFieldName,
                         GetFieldDescriptor(endInvokeMethod.ReturnParameter.Type)));
            }
            codeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(endInvokeMethod.ReturnParameter.Type));

            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }
Example #20
0
        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);
        }
Example #21
0
        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 string GenerateMethodPointerClass(InterMethod operand)
        {
            string mpInterfaceName = namesController.GetMethodPointerInterface(operand);

            string anonClassName = namesController.GetAnonimousClassName();

            Java.Class anonClass = new Java.Class();
            anonClass.AccessFlag = Java.ClassAccessFlag.Super | ClassAccessFlag.Public;
            anonClass.ThisClass  = namesController.TypeNameToJava(anonClassName);
            anonClass.SuperClass = namesController.TypeNameToJava(ClassNames.JavaObject);
            anonClass.Interfaces.Add(namesController.TypeNameToJava(mpInterfaceName));

            Method invokeMethod = new Method();

            invokeMethod.AccessFlags = MethodAccessFlags.Public;
            invokeMethod.Name        = ClassNames.MethodPointerInvokeName;
            invokeMethod.Descriptor  = "(L" + namesController.TypeNameToJava(ClassNames.JavaObject)
                                       + ";" + namesController.GetMethodDescriptor(operand).Substring(1);

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            if (!operand.IsStatic)
            {
                codeWriter
                .Add(OpCodes.aload_1)
                .Add(OpCodes.checkcast, new Java.Constants.Class(namesController.TypeNameToJava(operand.DeclaringType)));
            }

            for (int i = 0; i < operand.Parameters.Count; i++)
            {
                codeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(operand.Parameters[i].Type), i + 2);
            }

            MethodRef invokingMethodRef = new MethodRef(namesController.TypeNameToJava(operand.DeclaringType),
                                                        namesController.MethodNameToJava(operand.NewName), namesController.GetMethodDescriptor(operand));;

            if (!operand.IsPublic)
            {
                Method access = namesController.GetAnonumousAccessMethod();
                access.AccessFlags = MethodAccessFlags.Public;

                if (operand.IsStatic)
                {
                    access.AccessFlags |= MethodAccessFlags.Static;
                }

                access.Descriptor = namesController.GetMethodDescriptor(operand);

                JavaBytecodeWriter accessCodeWriter = new JavaBytecodeWriter();

                if (!operand.IsStatic)
                {
                    accessCodeWriter.Add(OpCodes.aload_0);
                }

                int firstParameter = operand.IsStatic ? 0 : 1;

                for (int i = 0; i < operand.Parameters.Count; i++)
                {
                    accessCodeWriter.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(operand.Parameters[i].Type), i + firstParameter);
                }

                if (operand.IsStatic)
                {
                    accessCodeWriter.Add(OpCodes.invokestatic, invokingMethodRef);
                }
                else if (operand.IsPrivate)
                {
                    accessCodeWriter.Add(OpCodes.invokespecial, invokingMethodRef);
                }
                else
                {
                    accessCodeWriter.Add(OpCodes.invokevirtual, invokingMethodRef);
                }

                access.Attributes.Add(accessCodeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(
                                                                     operand.ReturnParameter.Type)).End(this.constsPool));

                invokingMethodRef = new MethodRef(namesController.TypeNameToJava(operand.DeclaringType),
                                                  access.Name, namesController.GetMethodDescriptor(operand));
            }

            if (operand.IsStatic)
            {
                codeWriter.Add(OpCodes.invokestatic, invokingMethodRef);
            }
            else if (operand.DeclaringType.IsInterface)
            {
                codeWriter.Add(OpCodes.invokeinterface, invokingMethodRef);
            }
            else
            {
                codeWriter.Add(OpCodes.invokevirtual, invokingMethodRef);
            }

            invokeMethod.Attributes.Add(codeWriter.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(operand.ReturnParameter.Type))
                                        .End(anonClass.ConstantPool));
            anonClass.Methods.Add(invokeMethod);

            Method ctor = new Method();

            ctor.AccessFlags = MethodAccessFlags.Public;
            ctor.Name        = ClassNames.JavaConstructorMethodName;
            ctor.Descriptor  = "()V";
            ctor.Attributes.Add(new JavaBytecodeWriter()
                                .Add(OpCodes.aload_0)
                                .Add(OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef)
                                .Add(OpCodes._return).End(anonClass.ConstantPool));
            anonClass.Methods.Add(ctor);

            namesController.WriteAnonumousClass(anonClass);

            return(anonClassName);
        }
Example #23
0
 public MethodSignature(InterMethod method)
 {
     this.Name       = method.Name;
     this.Parameters = method.Parameters.Select(IP => IP.Type.Fullname).ToArray();
 }
Example #24
0
        private void GenerateDelegateRunner(InterType type)
        {
            Java.Class runner = new Java.Class();
            runner.AccessFlag = ClassAccessFlag.Final;
            runner.ThisClass  = currentJavaClass.ThisClass + "$" + ClassNames.DelegateRunnerClassName;
            runner.SuperClass = TypeNameToJava(ClassNames.CIL2JavaDelegateRunner.ClassName);

            Java.Attributes.InnerClasses.InnerClass inner = new Java.Attributes.InnerClasses.InnerClass()
            {
                AccessFlags    = Java.Attributes.InnerClasses.InnerClassAccessFlags.Final | Java.Attributes.InnerClasses.InnerClassAccessFlags.Private,
                InnerClassInfo = runner.ThisClass,
                InnerName      = ClassNames.DelegateRunnerClassName,
                OuterClassInfo = currentJavaClass.ThisClass
            };

            Java.Attributes.InnerClasses innerAttr = new Java.Attributes.InnerClasses();
            innerAttr.Classes.Add(inner);
            runner.Attributes.Add(innerAttr);
            currentJavaInnerClasses.Classes.Add(inner);

            InterMethod invokeMethod = type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault();

            Field selfField = new Field();

            selfField.AccessFlags = FieldAccessFlags.Private | FieldAccessFlags.Final;
            selfField.Name        = ClassNames.DelegateRunnerSelfFieldName;
            selfField.Descriptor  = GetFieldDescriptor(type);
            runner.Fields.Add(selfField);
            FieldRef selfFieldRef = new FieldRef(runner.ThisClass, selfField.Name, selfField.Descriptor);

            JavaBytecodeWriter ctorCodeWriter = new JavaBytecodeWriter();
            JavaBytecodeWriter runCodeWriter  = new JavaBytecodeWriter();

            ctorCodeWriter
            //super()
            .Add(OpCodes.aload_0)
            .Add(OpCodes.invokespecial, ClassNames.CIL2JavaDelegateRunner.CtorMethodRef)

            //this.self = self;
            .Add(OpCodes.aload_0)
            .Add(OpCodes.aload_1)
            .Add(OpCodes.putfield, selfFieldRef);

            if (invokeMethod.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void)
            {
                runCodeWriter.Add(OpCodes.aload_0);
            }

            runCodeWriter
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, selfFieldRef);

            for (int i = 0; i < invokeMethod.Parameters.Count; i++)
            {
                InterType         paramType = invokeMethod.Parameters[i].Type;
                JavaPrimitiveType jp        = JavaHelpers.InterTypeToJavaPrimitive(paramType);

                Field paramField = new Field();
                paramField.AccessFlags = FieldAccessFlags.Final | FieldAccessFlags.Private;
                paramField.Name        = ClassNames.DelegateRunnerParamFieldNamePrefix + i.ToString();;
                paramField.Descriptor  = GetFieldDescriptor(paramType);
                runner.Fields.Add(paramField);
                FieldRef paramFieldRef = new FieldRef(runner.ThisClass, paramField.Name, paramField.Descriptor);

                ctorCodeWriter
                .Add(OpCodes.aload_0)
                .AddLoad(jp, i + 2)
                .Add(OpCodes.putfield, paramFieldRef);

                runCodeWriter
                .Add(OpCodes.aload_0)
                .Add(OpCodes.getfield, paramFieldRef);
            }

            if (invokeMethod.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void)
            {
                Field resultField = new Field();
                resultField.AccessFlags = FieldAccessFlags.Private;
                resultField.Name        = ClassNames.DelegateRunnerResultFieldName;
                resultField.Descriptor  = GetFieldDescriptor(invokeMethod.ReturnParameter.Type);
                runner.Fields.Add(resultField);
                runCodeWriter.Add(OpCodes.putfield, new FieldRef(runner.ThisClass, resultField.Name, resultField.Descriptor));
            }

            runCodeWriter
            .Add(OpCodes.invokevirtual, new MethodRef(TypeNameToJava(type.Fullname), ClassNames.DelegateInvokeMethodName,
                                                      GetMethodDescriptor(invokeMethod)))
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, ClassNames.CIL2JavaDelegateRunner.OnEndedFieldRef)
            .Add(OpCodes.dup)
            .Add(OpCodes.ifnull, "noOnEnd")
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, ClassNames.CIL2JavaDelegateRunner.AsyncResultFieldResult)
            .Add(OpCodes.invokevirtual, ClassNames.SystemAsyncCallback.InvokeMethodRef)
            .Add(OpCodes._goto, "exit")
            .Label("noOnEnd")
            .Add(OpCodes.pop)
            .Label("exit");

            ctorCodeWriter.Add(OpCodes._return);
            runCodeWriter.Add(OpCodes._return);

            string paramsDescriptor = GetMethodDescriptor(invokeMethod);

            paramsDescriptor = paramsDescriptor.Substring(1, paramsDescriptor.LastIndexOf(')') - 1);

            Method ctorMethod = new Method();

            ctorMethod.AccessFlags = MethodAccessFlags.Public;
            ctorMethod.Name        = ClassNames.JavaConstructorMethodName;
            ctorMethod.Descriptor  = "(" + GetFieldDescriptor(type) + paramsDescriptor + ")V";
            ctorMethod.Attributes.Add(ctorCodeWriter.End(runner.ConstantPool));
            runner.Methods.Add(ctorMethod);

            Method runMethod = new Method();

            runMethod.AccessFlags = MethodAccessFlags.Public;
            runMethod.Name        = ClassNames.CIL2JavaDelegateRunner.RunMethodName;
            runMethod.Descriptor  = "()V";
            runMethod.Attributes.Add(runCodeWriter.End(runner.ConstantPool));
            runner.Methods.Add(runMethod);

            WriteClass(runner);
        }
Example #25
0
        public InterMethod(MethodReference methodRef, List <InterGenericArgument> genericArgs, IResolver resolver, Action <InterMethod> onFounded)
        {
            originalName = methodRef.Name;

            genericArgs = genericArgs ?? InterGenericArgument.EmptyGenericArgsList;

            MethodDefinition methodDef = methodRef.Resolve();

            CustomAttribute methodMapCustomAttr = null;

            if (methodDef != null)
            {
                methodMapCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.MethodMapAttribute).FirstOrDefault();
                if ((methodMapCustomAttr == null) && (Program.BoxType == BoxingType.Java))
                {
                    methodMapCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.JavaBoxMethodMapAttribute).FirstOrDefault();
                }
            }

            declType = resolver.Resolve(methodRef.DeclaringType, genericArgs);
            #region Mapping
            if (methodMapCustomAttr != null)
            {
                TypeReference  realDeclType    = methodMapCustomAttr.ConstructorArguments[0].Value as TypeReference;
                TypeDefinition realDeclTypeDef = realDeclType.Resolve();

                string           mappedName = (string)methodMapCustomAttr.ConstructorArguments[1].Value;
                MethodDefinition md         = null;
                int paramsOffset            = 0;
                if ((methodMapCustomAttr.ConstructorArguments.Count > 2) && ((bool)methodMapCustomAttr.ConstructorArguments[2].Value))
                {
                    paramsOffset = 1;
                }

                foreach (var method in realDeclTypeDef.Methods)
                {
                    if (method.Name != mappedName)
                    {
                        continue;
                    }
                    if (method.HasGenericParameters != methodDef.HasGenericParameters)
                    {
                        continue;
                    }
                    if (method.HasGenericParameters && method.GenericParameters.Count != methodDef.GenericParameters.Count)
                    {
                        continue;
                    }

                    if (!Utils.AreSame(method.ReturnType, methodDef.ReturnType))
                    {
                        continue;
                    }

                    if (paramsOffset == 0)
                    {
                        if ((!method.HasParameters) && (methodDef.HasParameters))
                        {
                            md = method;
                            break;
                        }
                    }
                    else
                    {
                        if (!method.HasParameters)
                        {
                            continue;
                        }

                        if ((!methodRef.HasParameters) && (method.Parameters.Count == 1))
                        {
                            md = method;
                            break;
                        }
                    }

                    if (!Utils.AreSame(method.Parameters, methodDef.Parameters, paramsOffset))
                    {
                        continue;
                    }

                    md = method;
                    break;
                }

                if (md == null)
                {
                    throw new Exception();  //TODO: mapping error
                }
                MethodReference newMethodRef = md;
                if (methodRef is GenericInstanceMethod)
                {
                    GenericInstanceMethod oldGIM = (GenericInstanceMethod)methodRef;
                    GenericInstanceMethod newGIM = new GenericInstanceMethod(newMethodRef);

                    oldGIM.GenericArguments.ForEach(T => newGIM.GenericArguments.Add(T));
                    newMethodRef = newGIM;
                }

                onFounded(resolver.Resolve(newMethodRef, genericArgs));
                return;
            }
            else
            #endregion
            { name = methodRef.Name; }

            genericArgs.AddRange(declType.GenericArguments);
            if ((methodDef ?? methodRef).HasGenericParameters)
            {
                GenericInstanceMethod gim = methodRef as GenericInstanceMethod;

                for (int i = 0; i < (methodDef ?? methodRef).GenericParameters.Count; i++)
                {
                    GenericParameter gp = (methodDef ?? methodRef).GenericParameters[i];

                    TypeReference genericArg = null;
                    if (gim != null)
                    {
                        genericArg = gim.GenericArguments[i];
                    }

                    if (genericArg is GenericParameter)
                    {
                        gp         = (GenericParameter)genericArg;
                        genericArg = null;
                    }

                    InterType resolvedGenericArg = null;
                    if (genericArg == null)
                    {
                        var resolvedInterGenericArg = genericArgs.Where(G => G.Owner == Utils.CecilGenericOwnerToC2JGenericOwner(gp.Type) &&
                                                                        G.Position == gp.Position);
                        if (resolvedInterGenericArg.Count() > 0)
                        {
                            resolvedGenericArg = resolvedInterGenericArg.First().Type;
                        }
                    }

                    if (resolvedGenericArg != null)
                    {
                        this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolvedGenericArg));
                    }
                    else if (genericArg != null)
                    {
                        this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolver.Resolve(genericArg, genericArgs)));
                    }
                    else
                    {
                        Messages.Message(MessageCode.CantResolveGenericParameter, gp.ToString(), methodRef.ToString());
                        this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolver.Resolve(ClassNames.ObjectTypeName)));
                    }
                }

                string genericsSufix = "<" + string.Join(",", this.genericArgs.Select(G => G.Type.Fullname)) + ">";
                this.name = this.name + "_GIM_" + resolver.GetGenericsArgsIndex(genericsSufix).ToString();
            }

            if (methodDef != null)
            {
                CustomAttribute fromJavaCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.FromJavaAttribute).FirstOrDefault();
                if (fromJavaCustomAttr != null)
                {
                    FromJava = true;
                    if (fromJavaCustomAttr.ConstructorArguments.Count > 0)
                    {
                        name = fromJavaCustomAttr.ConstructorArguments[0].Value.ToString();
                    }
                }
            }

            if (methodRef.HasThis)
            {
                thisParam = new InterParameter(0, declType, "this");
            }

            this.returnParam = new InterParameter(-1, resolver.Resolve(methodRef.ReturnType, this.FullGenericArguments), "return",
                                                  methodRef.MethodReturnType.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.BoxedAttribute).Count() > 0,
                                                  methodRef.MethodReturnType.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.JavaBoxedAttribute).Count() > 0);

            foreach (ParameterDefinition paramDef in methodRef.Parameters)
            {
                if (paramDef.ParameterType.IsSentinel)
                {
                    break;
                }

                parameters.Add(new InterParameter(paramDef, this.FullGenericArguments, resolver));
            }

            if (methodDef != null)
            {
                if (methodDef.HasBody)
                {
                    body = methodDef.Body;
                }

                IsPublic       = methodDef.IsPublic || methodDef.IsAssembly;
                IsProtected    = methodDef.IsFamily || methodDef.IsFamilyAndAssembly || methodDef.IsFamilyOrAssembly;
                IsPrivate      = methodDef.IsPrivate;
                IsAbstract     = methodDef.IsAbstract;
                IsFinal        = methodDef.IsFinal;
                IsVirtual      = methodDef.IsVirtual;
                IsNewSlot      = methodDef.IsNewSlot;
                IsStatic       = methodDef.IsStatic;
                IsSynchronized = methodDef.IsSynchronized;
                IsConstructor  = methodDef.IsConstructor;
                IsVarArg       = methodDef.CallingConvention == MethodCallingConvention.VarArg;
                HasThis        = methodDef.HasThis;
                HasBody        = methodDef.HasBody;

                foreach (MethodReference overridedMethod in methodDef.Overrides)
                {
                    overrides.Add(resolver.Resolve(overridedMethod, this.FullGenericArguments));
                }
            }
            else
            {
                IsPublic = true;
                IsFinal  = true;
                HasThis  = methodRef.HasThis;
                IsStatic = !methodRef.HasThis;
            }

            if ((!IsConstructor) && (!declType.IsDelegate))
            {
                //TODO: change params in ctors
                var changedParams = parameters.Where(P => ((P.Type.IsEnum) ||
                                                           ((P.Type.IsPrimitive) && (Utils.IsUnsigned(P.Type.PrimitiveType)))));
                if (changedParams.Count() > 0)
                {
                    name += "$" + string.Join("_", changedParams.Select(P => P.Index + P.Type.Fullname));
                }
            }

            InterMethod thisFromDecl = declType.Methods.Where(M => M.Equals(this)).FirstOrDefault();
            if (thisFromDecl != null)
            {
                onFounded(thisFromDecl);
            }
        }
Example #26
0
        private Method CompileMethod(InterMethod method)
        {
            Messages.Verbose("    Compiling method {0}...", method.ToString());
            Method result = new Method();

            if (method.IsPublic)
            {
                result.AccessFlags |= MethodAccessFlags.Public;
            }
            else if (method.IsProtected)
            {
                result.AccessFlags |= MethodAccessFlags.Protected;
            }
            else
            {
                result.AccessFlags |= MethodAccessFlags.Private;
            }

            if (method.IsAbstract)
            {
                result.AccessFlags |= MethodAccessFlags.Abstract;
            }
            if ((method.IsFinal) || ((!method.IsVirtual) && (!method.IsConstructor)) && (!method.IsStatic))
            {
                result.AccessFlags |= MethodAccessFlags.Final;
            }
            if (method.IsStatic)
            {
                result.AccessFlags |= MethodAccessFlags.Static;
            }
            if (method.IsSynchronized)
            {
                result.AccessFlags |= MethodAccessFlags.Synchronized;
            }
            if ((method.IsPrivate) && (method.IsVirtual))
            {
                Messages.Message(MessageCode.MethodPrivateAndVirtual, method.ToString());
            }
            if (method.IsVarArg)
            {
                result.AccessFlags |= MethodAccessFlags.VarArgs;
            }

            result.Name       = MethodNameToJava(method.NewName);
            result.Descriptor = GetMethodDescriptor(method);

            if (method.HasBody)
            {
                CodeCompiler codeCompiler = new CodeCompiler(this, this, this, method, currentJavaClass.ConstantPool);
                codeCompiler.Compile();
                result.Attributes.Add(codeCompiler.Result);

                if (Program.Debug)
                {
                    string sourceFileName = codeCompiler.SourceFile;
                    if (sourceFileName != null)
                    {
                        sourceFileNameCounter.Add(sourceFileName);
                    }
                }
            }

            if ((method.IsStatic) && (method.IsConstructor))
            {
                result.AccessFlags = MethodAccessFlags.Static;
            }

            return(result);
        }
Example #27
0
        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);
            }
        }
Example #28
0
        private void CompileCondition(ILCondition node, ExpectType expectType)
        {
            ILExpression condition = node.Condition;

            while (condition != null)
            {
                if (condition.Code == ILCode.Call)
                {
                    InterMethod callMethod = resolver.Resolve((MethodReference)condition.Operand, thisMethod.FullGenericArguments);

                    if (callMethod.DeclaringType.Fullname == ClassNames.Intrinsics.ClassName)
                    {
                        if (callMethod.Name == ClassNames.Intrinsics.IsCILBoxing)
                        {
                            if (Program.BoxType == BoxingType.Cil)
                            {
                                CompileBlock(node.TrueBlock);
                            }
                            return;
                        }

                        if (callMethod.Name == ClassNames.Intrinsics.IsJavaBoxing)
                        {
                            if (Program.BoxType == BoxingType.Java)
                            {
                                CompileBlock(node.TrueBlock);
                            }
                            return;
                        }
                    }
                    break;
                }

                condition = condition.Arguments.FirstOrDefault();
            }

            string labelsSufix = rnd.Next().ToString();
            string falseLabel  = "false" + labelsSufix;
            string exitLabel   = "exit" + labelsSufix;

            if (node.FalseBlock.Body.Count == 0)
            {
                falseLabel = exitLabel;
            }
            CompileCondition(new ILExpression(ILCode.LogicNot, null, node.Condition), falseLabel);

            //CompileExpression(node.Condition, ExpectType.Primitive);

            //Java.OpCodes branchInstr = Java.OpCodes.ifeq;
            //TranslateToBool(node.Condition.InferredType, ref branchInstr, node);

            //codeGenerator.Add(branchInstr, falseLabel, node);
            CompileBlock(node.TrueBlock, expectType);

            if (node.FalseBlock.Body.Count > 0)
            {
                codeGenerator.Add(Java.OpCodes._goto, exitLabel, node)
                .Label(falseLabel);
                CompileBlock(node.FalseBlock, expectType);
            }

            codeGenerator.Label(exitLabel);
        }
Example #29
0
        private void CompileCall(ILExpression e, ExpectType expect)
        {
            InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);

            if (operand.DeclaringType.Fullname == ClassNames.SystemThreadingMonitor.ClassName)
            {
                if (operand.Name == ClassNames.SystemThreadingMonitor.Enter)
                {
                    CompileMonitorEnter(e);
                    return;
                }

                if (operand.Name == ClassNames.SystemThreadingMonitor.Exit)
                {
                    CompileMonitorExit(e);
                    return;
                }
            }

            // Intrinsics that not poping real arguments
            if (operand.DeclaringType.Fullname == ClassNames.Intrinsics.ClassName)
            {
                if (operand.Name.Contains(ClassNames.Intrinsics.CreatePointerToArray))
                {
                    CompileIntrinsicCreatePointerToArray(e); return;
                }
                if (operand.Name == ClassNames.Intrinsics.GetBoxedDataFromPointer)
                {
                    CompileIntrinsicGetBoxedDataFromPointer(e); return;
                }
                if (operand.Name == ClassNames.Intrinsics.GetClass)
                {
                    CompileIntrinsicGetClass(e); return;
                }
            }

            if ((Program.BoxType == BoxingType.Java) && (operand.DeclaringType.Fullname == ClassNames.CorlibUtils) &&
                (operand.Name == ClassNames.ReboxMethod))
            {
                //Skip CIL2Java.Utils::Rebox in java boxing mode due optimizations
                CompileExpression(e.Arguments[0], expect);
                return;
            }

            if ((operand.IsConstructor) && (operand.DeclaringType.IsValueType) && (operand.Parameters.Count < e.Arguments.Count) &&
                (!thisMethod.IsConstructor))
            {
                // rebuild nodes from `call ctor(getVar(), [params])` to
                // setVar(newObj([params])

                ILExpression getVar = e.Arguments[0];
                e.Arguments.RemoveAt(0);
                e.Code      = ILCode.Newobj;
                getVar.Code = LoadVarInvert[getVar.Code];
                getVar.Arguments.Add(e);
                CompileExpression(getVar, expect);

                return;
            }

            if (operand.DeclaringType.IsArray)
            {
                CompileArrayCall(e, expect);
                return;
            }

            int argIndex = 0;

            if ((operand.HasThis) && (operand.Parameters.Count < e.Arguments.Count))
            {
                if (e.Prefixes != null)
                {
                    ILExpressionPrefix constrained = e.Prefixes.Where(P => P.Code == ILCode.Constrained).FirstOrDefault();
                    if (constrained != null)
                    {
                        InterType thisType = resolver.Resolve((TypeReference)constrained.Operand, thisMethod.FullGenericArguments);

                        if (thisType.IsPrimitive)
                        {
                            e.Arguments[argIndex].Code = GetAddrInvert[e.Arguments[argIndex].Code];
                            e.Arguments[argIndex]      = new ILExpression(ILCode.Box, null, e.Arguments[argIndex]);
                        }
                    }
                }

                CompileExpression(e.Arguments[argIndex++], ExpectType.Reference);
            }

            foreach (InterParameter param in operand.Parameters)
            {
                CompileExpression(e.Arguments[argIndex++], GetExpectType(param));
            }

            if (operand.IsVarArg)
            {
                codeGenerator
                .AddIntConst(e.Arguments.Count - argIndex)
                .Add(OpCodes.anewarray, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.JavaObject)), e);

                int i = 0;
                while (argIndex < e.Arguments.Count)
                {
                    codeGenerator
                    .Add(OpCodes.dup, null, e)
                    .AddIntConst(i++, e);

                    CompileExpression(e.Arguments[argIndex++], ExpectType.Boxed);
                    codeGenerator.Add(OpCodes.aastore, null, e);
                }
            }

            // Intrinsics that poping real arguments
            if (operand.DeclaringType.Fullname == ClassNames.Intrinsics.ClassName)
            {
                if (operand.Name == ClassNames.Intrinsics.monitorenter)
                {
                    codeGenerator.Add(Java.OpCodes.monitorenter, null, e);
                }
                if (operand.Name == ClassNames.Intrinsics.monitorexit)
                {
                    codeGenerator.Add(Java.OpCodes.monitorexit, null, e);
                }
                if (operand.Name == ClassNames.Intrinsics.lshr)
                {
                    codeGenerator.Add(Java.OpCodes.lshr, null, e);
                }
                if (operand.Name == ClassNames.Intrinsics.lushr)
                {
                    codeGenerator.Add(Java.OpCodes.lushr, null, e);
                }

                // UnsafeTypeConvert skip because:
                // Not any compiling. Just push argument, and it will auto became object type
                return;
            }

            CallType callType = CallType.Virtual;

            if (operand.IsStatic)
            {
                callType = CallType.Static;
            }
            else if (operand.DeclaringType.IsInterface)
            {
                callType = CallType.Interface;
            }
            else if ((operand.IsConstructor) || (operand.IsPrivate) ||
                     ((operand.IsSame(thisMethod)) && (thisMethod.DeclaringType.BaseType == operand.DeclaringType)))
            {
                callType = CallType.Special;
            }

            Java.Constant javaOperand = null;

            if (callType == CallType.Interface)
            {
                javaOperand = new Java.Constants.InterfaceMethodRef(
                    namesController.TypeNameToJava(operand.DeclaringType),
                    namesController.MethodNameToJava(operand.NewName),
                    namesController.GetMethodDescriptor(operand));
            }
            else
            {
                javaOperand = new Java.Constants.MethodRef(
                    namesController.TypeNameToJava(operand.DeclaringType),
                    namesController.MethodNameToJava(operand.NewName),
                    namesController.GetMethodDescriptor(operand));
            }

            switch (callType)
            {
            case CallType.Interface:
                codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokeinterface, javaOperand, e));
                break;

            case CallType.Special:
                codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, javaOperand, e));
                break;

            case CallType.Static:
                codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokestatic, javaOperand, e));
                break;

            case CallType.Virtual:
                codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokevirtual, javaOperand, e));
                break;
            }

            OnRestoreLocalByRefs();

            if ((!operand.ReturnParameter.Type.IsPrimitive) || (operand.ReturnParameter.Type.PrimitiveType != PrimitiveType.Void) ||
                (operand.ReturnParameter.IsBoxed) || (operand.ReturnParameter.IsJavaBoxed))
            {
                TranslateType(operand.ReturnParameter.Type, expect, e);
            }
        }
Example #30
0
        private void CompileJmp(ILExpression e, ExpectType expect)
        {
            int argIndex = 0;

            if (thisMethod.HasThis)
            {
                codeGenerator.Add(Java.OpCodes.aload_0, null, e);
                argIndex++;
            }

            for (int i = 0; i < thisMethod.Parameters.Count; i++)
            {
                JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(thisMethod.Parameters[i].Type);
                codeGenerator.AddLoad(jp, argIndex++);
                if (jp.IsDoubleSlot())
                {
                    argIndex++;
                }
            }

            InterMethod operand = resolver.Resolve((MethodReference)e.Operand, thisMethod.FullGenericArguments);

            CallType callType = CallType.Virtual;

            if (operand.IsStatic)
            {
                callType = CallType.Static;
            }
            else if (operand.DeclaringType.IsInterface)
            {
                callType = CallType.Interface;
            }
            else if ((operand.IsConstructor) || (operand.IsPrivate) ||
                     ((operand.IsSame(thisMethod)) && (thisMethod.DeclaringType.BaseType == operand.DeclaringType)))
            {
                callType = CallType.Special;
            }

            Java.Constant javaOperand = null;

            if (callType == CallType.Interface)
            {
                javaOperand = new Java.Constants.InterfaceMethodRef(
                    namesController.TypeNameToJava(operand.DeclaringType),
                    namesController.MethodNameToJava(operand.NewName),
                    namesController.GetMethodDescriptor(operand));
            }
            else
            {
                javaOperand = new Java.Constants.MethodRef(
                    namesController.TypeNameToJava(operand.DeclaringType),
                    namesController.MethodNameToJava(operand.NewName),
                    namesController.GetMethodDescriptor(operand));
            }

            switch (callType)
            {
            case CallType.Interface:
                codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokeinterface, javaOperand, e));
                break;

            case CallType.Special:
                codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, javaOperand, e));
                break;

            case CallType.Static:
                codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokestatic, javaOperand, e));
                break;

            case CallType.Virtual:
                codeGenerator.AddInstruction(new JavaInstruction(Java.OpCodes.invokevirtual, javaOperand, e));
                break;
            }

            codeGenerator.AddReturn(JavaHelpers.InterTypeToJavaPrimitive(thisMethod.ReturnParameter.Type));
        }