예제 #1
0
        private void GenerateValueTypeGetCopy(InterType type)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            result.Name        = ClassNames.ValueTypeGetCopy;
            result.Descriptor  = "()" + GetFieldDescriptor(type);

            Java.Constants.Class typeRef        = new Java.Constants.Class(TypeNameToJava(type.Fullname));
            MethodRef            defaultCtorRef = new MethodRef(typeRef.Value, ClassNames.JavaConstructorMethodName, "()V");
            MethodRef            copyToRef      = new MethodRef(typeRef.Value, ClassNames.ValueTypeCopyTo, "(" + GetFieldDescriptor(type) + ")V");

            result.Attributes.Add(new JavaBytecodeWriter()
                                  //tmp = new type();
                                  .Add(OpCodes._new, typeRef)
                                  .Add(OpCodes.dup)
                                  .Add(OpCodes.invokespecial, defaultCtorRef)
                                  .Add(OpCodes.astore_1)

                                  //this.CopyTo(tmp)
                                  .Add(OpCodes.aload_0)
                                  .Add(OpCodes.aload_1)
                                  .Add(OpCodes.invokevirtual, copyToRef)

                                  //return tmp
                                  .Add(OpCodes.aload_1)
                                  .AddReturn(JavaPrimitiveType.Ref)

                                  .End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(result);
        }
예제 #2
0
        private void CompileIsinst(ILExpression e, ExpectType expect)
        {
            InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments);

            CompileExpression(e.Arguments[0], ExpectType.Reference);

            //  dup
            //  instanceof operand
            //  ifne :end
            //  pop
            //  aconst_null
            //:end
            //  checkcast operand

            string endLabel = rnd.Next().ToString() + "end";

            Java.Constants.Class operandRef = new Java.Constants.Class(namesController.TypeNameToJava(GetBoxType(operand)));

            codeGenerator
            .Add(Java.OpCodes.dup, null, e)
            .Add(Java.OpCodes.instanceof, operandRef, e)
            .Add(Java.OpCodes.ifne, endLabel, e)
            .Add(Java.OpCodes.pop, null, e)
            .Add(Java.OpCodes.aconst_null, null, e)
            .Label(endLabel)
            .Add(Java.OpCodes.checkcast, operandRef, e);
        }
예제 #3
0
 public JavaBytecodeWriter AddMultianewarray(Java.Constants.Class arrayType, byte dimensions, object tag)
 {
     return(Add(Java.OpCodes.multianewarray, new MultianewarrayOperand()
     {
         ClassOperand = arrayType,
         DimensionsOperand = dimensions
     }, tag));
 }
예제 #4
0
        private void CompileLdloca(ILExpression e, ExpectType expectType)
        {
            ILVariable operand     = (ILVariable)e.Operand;
            int        varIndex    = GetVarIndex(operand);
            InterType  operandType = resolver.Resolve(operand.Type, thisMethod.FullGenericArguments);

            if (operandType.IsValueType)
            {
                codeGenerator.AddLoad(JavaPrimitiveType.Ref, varIndex);
                return;
            }

            if ((operandType.IsPrimitive) && (expectType == ExpectType.Reference))
            {
                codeGenerator.AddLoad(JavaHelpers.InterTypeToJavaPrimitive(operandType), varIndex, e);
                TranslateType(operandType, ExpectType.Boxed, e);
                return;
            }

            string localByRefName = byRefController.GetLocalByRefTypeName(operandType);

            Java.Constants.Class localByRefNameClass =
                new Java.Constants.Class(namesController.TypeNameToJava(localByRefName));
            Java.Constants.MethodRef localByRefInitMethodRef =
                byRefController.GetLocalByRefCtorMethodRef(operandType);
            Java.Constants.MethodRef getValueMethodRef =
                byRefController.GetByRefGetValueMethodRef(JavaHelpers.InterTypeToJavaPrimitive(operandType));

            int localRefTempVar = GetNextFreeVar(JavaPrimitiveType.Ref);

            codeGenerator
            .Add(OpCodes._new, localByRefNameClass, e)
            .Add(OpCodes.dup, null, e)
            .AddLocalVarInstruction(LocalVarInstruction.Load, JavaHelpers.InterTypeToJavaPrimitive(operandType), varIndex, e)
            .Add(OpCodes.invokespecial, localByRefInitMethodRef, e)
            .Add(OpCodes.dup, null, e)
            .AddLocalVarInstruction(LocalVarInstruction.Store, JavaPrimitiveType.Ref, localRefTempVar, e);

            RegisterLocalByRef(() =>
            {
                codeGenerator
                .AddLocalVarInstruction(LocalVarInstruction.Load, JavaPrimitiveType.Ref, localRefTempVar, e)
                .Add(OpCodes.invokevirtual, getValueMethodRef, e);

                if ((!operandType.IsPrimitive) && (!operandType.IsEnum))
                {
                    codeGenerator.Add(OpCodes.checkcast,
                                      new Java.Constants.Class(namesController.TypeNameToJava(operandType)), e);
                }

                codeGenerator.AddLocalVarInstruction(LocalVarInstruction.Store, JavaHelpers.InterTypeToJavaPrimitive(operandType), varIndex, e);

                FreeVar(localRefTempVar, JavaPrimitiveType.Ref);
            });

            //TODO: TranslateType if neeeded
        }
예제 #5
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);
        }
예제 #6
0
        private void TranslateType(InterType type, ExpectType expected, object tag)
        {
            if ((Program.Unsigned) && (type.IsPrimitive) && (type.PrimitiveType.IsUnsigned()))
            {
                if ((type.PrimitiveType == PrimitiveType.Byte) || (type.PrimitiveType == PrimitiveType.UInt16))
                {
                    if (type.PrimitiveType == PrimitiveType.Byte)
                    {
                        codeGenerator.AddIntConst(0xff, tag);
                    }
                    else
                    {
                        codeGenerator.AddIntConst(0xffff, tag);
                    }
                    codeGenerator.Add(Java.OpCodes.iand, null, tag);
                }
            }

            if (expected == ExpectType.Any)
            {
                return;
            }

            if (expected == ExpectType.None)
            {
                codeGenerator.AddPop(JavaHelpers.InterTypeToJavaPrimitive(type), tag);
            }

            if ((type.IsByRef) && (expected != ExpectType.ByRef) && (!type.ElementType.IsValueType))
            {
                JavaPrimitiveType    javaType      = JavaHelpers.InterTypeToJavaPrimitive(type.ElementType);
                MethodRef            getMethodRef  = byRefController.GetByRefGetValueMethodRef(javaType);
                Java.Constants.Class loadedTypeRef = new Java.Constants.Class(namesController.TypeNameToJava(type.ElementType));

                codeGenerator.Add(OpCodes.invokevirtual, getMethodRef, tag);

                if (javaType == JavaPrimitiveType.Ref)
                {
                    codeGenerator.Add(OpCodes.checkcast, loadedTypeRef, tag);
                }

                type = type.ElementType;
            }

            if (((expected == ExpectType.Boxed) || (expected == ExpectType.Reference)) &&
                ((type.IsPrimitive) || (type.IsEnum) || (type.IsValueType)))
            {
                if ((!type.IsNullable) || (expected != ExpectType.Reference))
                {
                    BoxType(type, tag);
                }
            }
        }
예제 #7
0
        private void CompileUnbox_Any(ILExpression e, ExpectType expect)
        {
            InterType operand      = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments);
            InterType nullableType = null;

            if (operand.IsNullable)
            {
                nullableType = operand;
                operand      = operand.GenericArguments[0].Type;

                codeGenerator
                .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(nullableType)), e)
                .Add(OpCodes.dup, null, e);
            }

            CompileExpression(e.Arguments[0], ExpectType.Boxed);

            string boxType = GetBoxType(operand);

            Java.Constants.Class operandRef = new Java.Constants.Class(namesController.TypeNameToJava(boxType));

            Java.Constants.MethodRef valueRef;

            if (operand.IsValueType)
            {
                valueRef = new Java.Constants.MethodRef(operandRef.Value, ClassNames.ValueTypeGetCopy, "()" +
                                                        namesController.GetFieldDescriptor(operand));
            }
            else if (operand.IsEnum)
            {
                valueRef = new MethodRef(operandRef.Value, ClassNames.EnumGetUnboxedMethodName,
                                         "()" + namesController.GetFieldDescriptor(operand.ElementType));
            }
            else
            {
                valueRef = new Java.Constants.MethodRef(operandRef.Value,
                                                        Utils.GetJavaTypeName(operand.PrimitiveType) + "Value",
                                                        "()" + namesController.GetFieldDescriptor(operand));
            }

            codeGenerator
            .Add(Java.OpCodes.checkcast, operandRef, e)
            .Add(Java.OpCodes.invokevirtual, valueRef, e);

            if (nullableType != null)
            {
                codeGenerator.Add(OpCodes.invokespecial, new MethodRef(
                                      namesController.TypeNameToJava(nullableType),
                                      ClassNames.JavaConstructorMethodName,
                                      "(" + namesController.GetFieldDescriptor(operand) + ")V"));
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        private void GenerateStaticCtor(InterType type)
        {
            Method ctor = new Method();

            ctor.AccessFlags = MethodAccessFlags.Static;
            ctor.Name        = "<clinit>";
            ctor.Descriptor  = "()V";

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            var threadLocalFields = type.Fields.Where(F => F.IsThreadLocal && F.IsStatic);

            foreach (InterField fld in threadLocalFields)
            {
                FieldRef fldRef = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name),
                                               "L" + TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";");

                codeWriter
                .Add(OpCodes._new, new Java.Constants.Class(TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName)))
                .Add(OpCodes.dup)
                .Add(OpCodes.invokespecial, ClassNames.JavaLangThreadLocal.CtorMethodRef)
                .Add(OpCodes.putstatic, fldRef);
            }

            var staticValueTypeFields = type.Fields.Where(F => ((F.IsStatic) && (F.FieldType.IsValueType)));

            foreach (InterField fld in staticValueTypeFields)
            {
                Java.Constants.Class fldTypeRef     = new Java.Constants.Class(TypeNameToJava(fld.FieldType.Fullname));
                MethodRef            fldTypeInitRef = new MethodRef(fldTypeRef.Value, ClassNames.JavaConstructorMethodName, "()V");
                FieldRef             fldRef         = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name),
                                                                   GetFieldDescriptor(fld.FieldType));

                codeWriter
                .Add(OpCodes._new, fldTypeRef)
                .Add(OpCodes.dup)
                .Add(OpCodes.invokespecial, fldTypeInitRef)
                .Add(OpCodes.putstatic, fldRef);
            }

            codeWriter.AddReturn(JavaPrimitiveType.Void);

            ctor.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(ctor);
        }
예제 #10
0
        private void CompileLdind(ILExpression e, ExpectType expect)
        {
            InterType operand = resolver.Resolve((TypeReference)e.Arguments[0].InferredType, thisMethod.FullGenericArguments);

            CompileExpression(e.Arguments[0], ExpectType.ByRef);

            MethodRef getMethodRef = byRefController.GetByRefGetValueMethodRef(JavaHelpers.InterTypeToJavaPrimitive(
                                                                                   operand.ElementType));
            InterType loadType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments);

            Java.Constants.Class loadedTypeRef = new Java.Constants.Class(namesController.TypeNameToJava(loadType));

            codeGenerator.Add(OpCodes.invokevirtual, getMethodRef, e);

            if ((!operand.ElementType.IsPrimitive) && (!operand.ElementType.IsEnum))
            {
                codeGenerator.Add(OpCodes.checkcast, loadedTypeRef, e);
            }
        }
예제 #11
0
        private void CompileDefaultValue(ILExpression e, ExpectType expect)
        {
            InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments);

            if (operand.IsValueType)
            {
                Java.Constants.Class operandRef     = new Java.Constants.Class(namesController.TypeNameToJava(operand));
                MethodRef            operandCtorRef = new MethodRef(operandRef.Value, ClassNames.JavaConstructorMethodName, "()V");

                codeGenerator
                .Add(Java.OpCodes._new, operandRef, e)
                .Add(Java.OpCodes.dup, null, e)
                .Add(Java.OpCodes.invokespecial, operandCtorRef, e);
            }
            else
            {
                codeGenerator.AddDefaultValue(JavaHelpers.InterTypeToJavaPrimitive(operand), e);
            }
            TranslateType(operand, expect, e);
        }
예제 #12
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);
            }
        }
예제 #13
0
        private void CompileLdelema(ILExpression e, ExpectType expectType)
        {
            TypeReference typeRef = e.Operand as TypeReference;
            InterType     operand = resolver.Resolve(typeRef, thisMethod.FullGenericArguments);
            JavaArrayType arrType = JavaHelpers.InterTypeToJavaArrayType(operand);

            if (operand.IsValueType)
            {
                CompileExpression(e.Arguments[0], ExpectType.Reference);    //array
                CompileExpression(e.Arguments[1], ExpectType.Primitive);    //index

                codeGenerator.Add(OpCodes.aaload, null, e);
                return;
            }

            if ((operand.IsPrimitive) && (expectType == ExpectType.Reference))
            {
                CompileExpression(e.Arguments[0], ExpectType.Reference);    //array
                CompileExpression(e.Arguments[1], ExpectType.Primitive);    //index

                codeGenerator.AddArrayLoad(arrType);
                TranslateType(operand, ExpectType.Boxed, e);
                return;
            }

            string arrayByRefName = byRefController.GetArrayByRefTypeName(operand);

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

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

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

            codeGenerator.Add(OpCodes.invokespecial, arrayByRefInitMethodRef, e);
        }
예제 #14
0
        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);
        }
예제 #15
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);
            }
        }
예제 #16
0
        private void GenerateValueTypeDefaultCtor(InterType type)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            result.Name        = ClassNames.JavaConstructorMethodName;
            result.Descriptor  = "()V";

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            codeWriter
            .Add(OpCodes.aload_0)
            .Add(OpCodes.invokespecial, ClassNames.ValueTypeCtor);

            foreach (InterField fld in type.Fields)
            {
                if ((fld.FieldType.IsValueType) && (!fld.IsStatic))
                {
                    Java.Constants.Class fldTypeClassRef = new Java.Constants.Class(TypeNameToJava(fld.FieldType.Fullname));
                    MethodRef            fldTypeCtorRef  = new MethodRef(fldTypeClassRef.Value, "<init>", "()V");
                    FieldRef             fldRef          = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Name),
                                                                        GetFieldDescriptor(fld.FieldType));

                    codeWriter
                    .Add(OpCodes.aload_0)
                    .Add(OpCodes._new, fldTypeClassRef)
                    .Add(OpCodes.dup)
                    .Add(OpCodes.invokespecial, fldTypeCtorRef)
                    .Add(OpCodes.putfield, fldRef);
                }
            }

            codeWriter.AddReturn(JavaPrimitiveType.Void);

            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(result);
        }
예제 #17
0
        private void GenerateValueTypeEquals(InterType type)
        {
            if (type.Methods.Where(M => ((M.Name == "Equals") && (M.Parameters.Count == 1) &&
                                         (M.Parameters[0].Type.Fullname == ClassNames.JavaObject))).Count() > 0)
            {
                return;
            }

            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public;
            result.Name        = "equals";
            result.Descriptor  = "(L" + TypeNameToJava(ClassNames.JavaObject) + ";)Z";

            Java.Constants.Class thisTypeRef = new Java.Constants.Class(TypeNameToJava(type.Fullname));

            JavaBytecodeWriter codeGenerator = new JavaBytecodeWriter();

            codeGenerator
            .Add(OpCodes.aload_1)
            .Add(OpCodes.instanceof, thisTypeRef)
            .Add(OpCodes.ifeq, "false")
            .Add(OpCodes.aload_1)
            .Add(OpCodes.checkcast, thisTypeRef)
            .Add(OpCodes.astore_1);

            foreach (InterField fld in type.Fields)
            {
                FieldRef fldRef = new FieldRef(thisTypeRef.Value, FieldNameToJava(fld.Name), GetFieldDescriptor(fld.FieldType));

                codeGenerator
                .Add(OpCodes.aload_0)
                .Add(OpCodes.getfield, fldRef)
                .Add(OpCodes.aload_1)
                .Add(OpCodes.getfield, fldRef);

                if ((fld.FieldType.IsPrimitive) || (fld.FieldType.IsEnum))
                {
                    switch (JavaHelpers.InterTypeToJavaPrimitive(fld.FieldType))
                    {
                    case JavaPrimitiveType.Bool:
                    case JavaPrimitiveType.Byte:
                    case JavaPrimitiveType.Char:
                    case JavaPrimitiveType.Int:
                    case JavaPrimitiveType.Short:
                        codeGenerator.Add(OpCodes.if_icmpne, "false");
                        break;

                    case JavaPrimitiveType.Long:
                        codeGenerator.Add(OpCodes.lcmp).Add(OpCodes.ifne, "false");
                        break;

                    case JavaPrimitiveType.Float:
                        codeGenerator.Add(OpCodes.fcmpg).Add(OpCodes.ifne, "false");
                        break;

                    case JavaPrimitiveType.Double:
                        codeGenerator.Add(OpCodes.dcmpg).Add(OpCodes.ifne, "false");
                        break;
                    }
                }
                else if (fld.FieldType.IsValueType)
                {
                    MethodRef equalMethod = new MethodRef(TypeNameToJava(fld.FieldType.Fullname), result.Name, result.Descriptor);
                    codeGenerator.Add(OpCodes.invokevirtual, equalMethod).Add(OpCodes.ifeq, "false");
                }
                else
                {
                    codeGenerator.Add(OpCodes.if_acmpne, "false");
                }
            }

            codeGenerator
            .Add(OpCodes.iconst_1)
            .Add(OpCodes._goto, "exit")
            .Label("false")
            .Add(OpCodes.iconst_0)
            .Label("exit")
            .Add(OpCodes.ireturn);

            result.Attributes.Add(codeGenerator.End(currentJavaClass.ConstantPool));
            currentJavaClass.Methods.Add(result);
        }
예제 #18
0
        private void CompileTryBlock(ILTryCatchBlock block)
        {
            string labelsSufix = rnd.Next().ToString();

            string tryStartLabel     = "tryStart" + labelsSufix;
            string tryEndLabel       = "tryEnd" + labelsSufix;
            string handlerStartLabel = "handler" + labelsSufix;
            string exitLabel         = "exit" + labelsSufix;
            string rethrowLabel      = "rethrow" + labelsSufix;

            codeGenerator.Label(tryStartLabel);
            CompileBlock(block.TryBlock);

            if (block.TryBlock.Body.Count == 0)
            {
                codeGenerator.Add(Java.OpCodes.nop, null, block);
            }

            codeGenerator.Label(tryEndLabel);


            if ((block.FinallyBlock != null) || (block.FaultBlock != null))
            {
                int handlerExceptionVar = GetNextFreeVar(JavaPrimitiveType.Ref);

                endfinallyLabels.Push(exitLabel);
                if (block.FinallyBlock != null)
                {
                    CompileBlock(block.FinallyBlock);
                }
                endfinallyLabels.Pop();

                codeGenerator
                .Add(Java.OpCodes._goto, exitLabel, block)
                .Label(handlerStartLabel)
                .AddStore(JavaPrimitiveType.Ref, handlerExceptionVar, block);

                endfinallyLabels.Push(rethrowLabel);
                CompileBlock(block.FinallyBlock ?? block.FaultBlock);
                endfinallyLabels.Pop();

                codeGenerator
                .Label(rethrowLabel)
                .AddLoad(JavaPrimitiveType.Ref, handlerExceptionVar, block)
                .Add(Java.OpCodes.athrow, null, block)
                .Label(exitLabel);

                FreeVar(handlerExceptionVar, JavaPrimitiveType.Ref);

                exceptions.Add(new ExceptionDescription()
                {
                    TryStart     = tryStartLabel,
                    TryEnd       = tryEndLabel,
                    HandlerStart = handlerStartLabel,
                    HandlerType  = null
                });
            }
            else if (block.CatchBlocks.Count > 0)
            {
                codeGenerator.Add(Java.OpCodes._goto, exitLabel, block);

                int index = 0;
                foreach (ILTryCatchBlock.CatchBlock cblock in block.CatchBlocks)
                {
                    string catchHandlerStartLabel = handlerStartLabel + (index++).ToString();
                    int    varIndex = GetVarIndex(cblock.ExceptionVariable ?? new ILVariable {
                        Name = "tmp_Exception", Type = cblock.ExceptionType, IsGenerated = true
                    });
                    InterType catchType = resolver.Resolve(cblock.ExceptionType, thisMethod.FullGenericArguments);

                    Java.Constants.Class catchTypeRef = new Java.Constants.Class(namesController.TypeNameToJava(catchType));

                    foreach (string javaException in catchType.JavaExceptions)
                    {
                        Java.Constants.MethodRef catchTypeInitRef = new Java.Constants.MethodRef(
                            catchTypeRef.Value, ClassNames.JavaConstructorMethodName, "(L" + namesController.TypeNameToJava(
                                javaException) + ";)V");

                        string javaExceptionLabel = catchHandlerStartLabel + javaException;

                        codeGenerator
                        .Label(javaExceptionLabel)
                        .AddStore(JavaPrimitiveType.Ref, varIndex, block)
                        .Add(Java.OpCodes._new, catchTypeRef, block)
                        .Add(Java.OpCodes.dup, null, block)
                        .AddLoad(JavaPrimitiveType.Ref, varIndex, block)
                        .Add(Java.OpCodes.invokespecial, catchTypeInitRef, block)
                        .Add(Java.OpCodes._goto, catchHandlerStartLabel, block);

                        exceptions.Add(new ExceptionDescription()
                        {
                            TryStart     = tryStartLabel,
                            TryEnd       = tryEndLabel,
                            HandlerStart = javaExceptionLabel,
                            HandlerType  = javaException
                        });
                    }

                    codeGenerator
                    .Label(catchHandlerStartLabel)
                    .AddStore(JavaPrimitiveType.Ref, varIndex);

                    exceptionVar.Push(varIndex);
                    CompileBlock(cblock);
                    exceptionVar.Pop();

                    codeGenerator.Add(Java.OpCodes._goto, exitLabel);

                    exceptions.Add(new ExceptionDescription()
                    {
                        TryStart     = tryStartLabel,
                        TryEnd       = tryEndLabel,
                        HandlerStart = catchHandlerStartLabel,
                        HandlerType  = catchType.Fullname
                    });
                }

                codeGenerator.Label(exitLabel);
            }
        }
예제 #19
0
        private byte[] GenerateMethodProlog()
        {
            codeGenerator = new JavaBytecodeWriter();

            if (thisMethod.IsConstructor)
            {
                if (firstCall != null)
                {
                    CompileExpression(firstCall, ExpectType.Any);
                }
                else if (!thisMethod.IsStatic)
                {
                    string typeName = namesController.TypeNameToJava(thisMethod.DeclaringType.BaseType);
                    if ((thisMethod.DeclaringType.IsValueType) && (thisMethod.Parameters.Count > 0))
                    {
                        //call to this() to initialize all fields
                        typeName = namesController.TypeNameToJava(thisMethod.DeclaringType);
                    }

                    MethodRef superCall = new MethodRef(typeName, ClassNames.JavaConstructorMethodName, "()V");
                    codeGenerator
                    .Add(OpCodes.aload_0)
                    .Add(OpCodes.invokespecial, superCall);
                }

                if (thisMethod.IsStatic)
                {
                    var threadLocalFields = thisMethod.DeclaringType.Fields.Where(F => F.IsStatic && F.IsThreadLocal);

                    foreach (InterField fld in threadLocalFields)
                    {
                        FieldRef fldRef = new FieldRef(
                            namesController.TypeNameToJava(fld.DeclaringType.Fullname),
                            namesController.FieldNameToJava(fld.Name),
                            "L" + namesController.TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";");

                        codeGenerator
                        .Add(OpCodes._new, new Java.Constants.Class(namesController.TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName)))
                        .Add(OpCodes.dup)
                        .Add(OpCodes.invokespecial, ClassNames.JavaLangThreadLocal.CtorMethodRef)
                        .Add(OpCodes.putstatic, fldRef);
                    }
                }

                var valueTypeFields = thisMethod.DeclaringType.Fields
                                      .Where(F => ((F.FieldType.IsValueType) && (F.IsStatic == thisMethod.IsStatic)));
                OpCodes putfield = thisMethod.IsStatic ? OpCodes.putstatic : OpCodes.putfield;

                foreach (InterField fld in valueTypeFields)
                {
                    Java.Constants.Class fldTypeRef = new Java.Constants.Class(
                        namesController.TypeNameToJava(fld.FieldType));
                    MethodRef ctorRef = new MethodRef(fldTypeRef.Value, ClassNames.JavaConstructorMethodName, "()V");
                    FieldRef  fldRef  = new FieldRef(namesController.TypeNameToJava(fld.DeclaringType),
                                                     namesController.FieldNameToJava(fld.Name), namesController.GetFieldDescriptor(fld.FieldType));

                    if (!thisMethod.IsStatic)
                    {
                        codeGenerator.Add(OpCodes.aload_0);
                    }

                    codeGenerator
                    .Add(OpCodes._new, fldTypeRef)
                    .Add(OpCodes.dup)
                    .Add(OpCodes.invokespecial, ctorRef)
                    .Add(putfield, fldRef);
                }
            }

            foreach (ValueTypeVar v in valueTypesVars)
            {
                Java.Constants.Class     typeRef = new Java.Constants.Class(namesController.TypeNameToJava(v.varType));
                Java.Constants.MethodRef ctorRef = new Java.Constants.MethodRef(typeRef.Value,
                                                                                ClassNames.JavaConstructorMethodName, "()V");

                codeGenerator
                .Add(Java.OpCodes._new, typeRef)
                .Add(Java.OpCodes.dup)
                .Add(Java.OpCodes.invokespecial, ctorRef)
                .AddStore(JavaPrimitiveType.Ref, v.varIndex);
            }

            return(codeGenerator.End(constsPool).CodeBytes);
        }
예제 #20
0
 public JavaBytecodeWriter AddMultianewarray(Java.Constants.Class arrayType, byte dimensions)
 {
     return(AddMultianewarray(arrayType, dimensions, null));
 }
예제 #21
0
        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);
            }
        }
예제 #22
0
        private void CompileNewarr(ILExpression e, ExpectType expect)
        {
            InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments);
            InterType element = operand;

            if (element.IsArray)
            {
                element = element.ElementType;
            }

            Java.Constants.Class operandRef       = new Java.Constants.Class(namesController.TypeNameToJava(element));
            MethodRef            valueTypeInitRef = new MethodRef(operandRef.Value, ClassNames.JavaConstructorMethodName, "()V");

            JavaArrayType arrayType = JavaHelpers.InterTypeToJavaArrayType(operand);

            if (e.Code == ILCode.Newarr)
            {
                CompileExpression(e.Arguments[0], ExpectType.Primitive);
            }
            else
            {
                if (operand.Dimesnsions[0].LowerBound != 0)
                {
                    Messages.Message(MessageCode.NotZeroLowerBound, operand.Fullname);
                }
                codeGenerator.AddIntConst(operand.Dimesnsions[0].UpperBound.Value, e);
            }

            if (arrayType == JavaArrayType.Ref)
            {
                codeGenerator.Add(Java.OpCodes.anewarray, operandRef, e);
            }
            else
            {
                codeGenerator.AddNewArray(arrayType, e);
            }

            if (e.Code == ILCode.InitArray)
            {
                for (int i = 0; i < e.Arguments.Count; i++)
                {
                    if ((e.Arguments[i].Code == ILCode.DefaultValue) && (!element.IsValueType))
                    {
                        continue;
                    }

                    codeGenerator.Add(Java.OpCodes.dup, null, e);
                    codeGenerator.AddIntConst(i, e);
                    CompileExpression(e.Arguments[i], GetExpectType(element));
                    codeGenerator.AddArrayStore(arrayType, e);
                }
            }
            else if (element.IsValueType)
            {
                int arrayTmpStore  = GetNextFreeVar(JavaPrimitiveType.Ref);
                int arrayLengthTmp = GetNextFreeVar(JavaPrimitiveType.Int);

                string labelPrefix = rnd.Next().ToString();
                string loopLabel   = labelPrefix + "loop";
                string endLabel    = labelPrefix + "end";

                codeGenerator
                .AddStore(JavaPrimitiveType.Ref, arrayTmpStore, e)
                .AddLoad(JavaPrimitiveType.Ref, arrayTmpStore, e)
                .Add(Java.OpCodes.arraylength, null, e)
                .AddStore(JavaPrimitiveType.Int, arrayLengthTmp, e)

                // while (arrayLengthTmp > 0) arrayTmpStore[--arrayLengthTmp] = new valType();
                .Label(loopLabel)
                .AddLoad(JavaPrimitiveType.Int, arrayLengthTmp, e)
                .Add(Java.OpCodes.ifle, endLabel, e)
                .AddIInc((ushort)arrayLengthTmp, -1, e)
                .AddLoad(JavaPrimitiveType.Ref, arrayTmpStore, e)
                .AddLoad(JavaPrimitiveType.Int, arrayLengthTmp, e)
                .Add(Java.OpCodes._new, operandRef, e)
                .Add(Java.OpCodes.dup, null, e)
                .Add(Java.OpCodes.invokespecial, valueTypeInitRef, e)
                .Add(Java.OpCodes.aastore, null, e)
                .Add(Java.OpCodes._goto, loopLabel, e)
                .Label(endLabel)


                .AddLoad(JavaPrimitiveType.Ref, arrayTmpStore, e);

                FreeVar(arrayTmpStore, JavaPrimitiveType.Ref);
                FreeVar(arrayLengthTmp, JavaPrimitiveType.Int);
            }
        }
예제 #23
0
        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);
        }
예제 #24
0
        private void CompileDelegateInvoke(InterType type)
        {
            Method result = new Method();

            result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Final;
            result.Name        = ClassNames.DelegateInvokeMethodName;
            result.Descriptor  = GetMethodDescriptor(type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName)
                                                     .FirstOrDefault());

            JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();

            Java.Constants.Class methodPointerType = new Java.Constants.Class(
                TypeNameToJava(((INamesController)this).GetMethodPointerInterface(
                                   type.Methods.Where(M => M.Name == ClassNames.DelegateInvokeMethodName).FirstOrDefault())));

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

            codeWriter
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, ClassNames.DelegateMethodFieldFast);

            if (Program.MethodPointersType == MethodPointerImplementation.Standart)
            {
                MethodRef unboxRef = Program.AsX64 ? ClassNames.JavaLongUnbox : ClassNames.JavaIntegerUnbox;

                codeWriter
                .Add(OpCodes.checkcast, new Java.Constants.Class(unboxRef.Class))
                .Add(OpCodes.invokevirtual, unboxRef);

                if (Program.AsX64)
                {
                    codeWriter.Add(OpCodes.l2i);
                }

                codeWriter.Add(OpCodes.invokestatic, ClassNames.GlobalMethodPointersGet);
            }

            codeWriter
            .Add(OpCodes.checkcast, methodPointerType)
            .Add(OpCodes.aload_0)
            .Add(OpCodes.getfield, ClassNames.DelegateTargetField);

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

            codeWriter.Add(OpCodes.invokeinterface,
                           new InterfaceMethodRef(methodPointerType.Value, ClassNames.MethodPointerInvokeName,
                                                  "(L" + TypeNameToJava(ClassNames.JavaObject) + ";" + GetMethodDescriptor(invokeMethod).Substring(1)));

            if (type.BaseType.Fullname == ClassNames.MulticastDelegateTypeName)
            {
                codeWriter
                .Add(OpCodes.aload_0)
                .Add(OpCodes.getfield, ClassNames.MulticastDelegateNextField)
                .Add(OpCodes.ifnull, "exit");

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

                codeWriter
                .Add(OpCodes.aload_0)
                .Add(OpCodes.getfield, ClassNames.MulticastDelegateNextField)
                .Add(OpCodes.checkcast, new Java.Constants.Class(TypeNameToJava(type.Fullname)));

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

                codeWriter.Add(OpCodes.invokevirtual, new MethodRef(TypeNameToJava(type.Fullname),
                                                                    ClassNames.DelegateInvokeMethodName, GetMethodDescriptor(invokeMethod)));
            }

            codeWriter
            .Label("exit")
            .AddReturn(JavaHelpers.InterTypeToJavaPrimitive(invokeMethod.ReturnParameter.Type));
            result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));

            currentJavaClass.Methods.Add(result);
        }