示例#1
0
        public JavaBytecodeWriter AddDefaultValue(JavaPrimitiveType jp, object tag)
        {
            Java.OpCodes opcode = Java.OpCodes.aconst_null;

            switch (jp)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Int:
            case JavaPrimitiveType.Short:
                opcode = Java.OpCodes.iconst_0;
                break;

            case JavaPrimitiveType.Long:
                opcode = Java.OpCodes.lconst_0;
                break;

            case JavaPrimitiveType.Float:
                opcode = Java.OpCodes.fconst_0;
                break;

            case JavaPrimitiveType.Double:
                opcode = Java.OpCodes.dconst_0;
                break;
            }

            AddInstruction(new JavaInstruction(opcode, null, tag));

            return(this);
        }
示例#2
0
        private void AddLocalVarStore(JavaPrimitiveType varType, int varIndex, object tag)
        {
            Java.OpCodes shortOpcode = Java.OpCodes.astore_0;
            Java.OpCodes longOpcode  = Java.OpCodes.astore;

            switch (varType)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Short:
            case JavaPrimitiveType.Int:
                shortOpcode = Java.OpCodes.istore_0;
                longOpcode  = Java.OpCodes.istore;
                break;

            case JavaPrimitiveType.Long:
                shortOpcode = Java.OpCodes.lstore_0;
                longOpcode  = Java.OpCodes.lstore;
                break;

            case JavaPrimitiveType.Float:
                shortOpcode = Java.OpCodes.fstore_0;
                longOpcode  = Java.OpCodes.fstore;
                break;

            case JavaPrimitiveType.Double:
                shortOpcode = Java.OpCodes.dstore_0;
                longOpcode  = Java.OpCodes.dstore;
                break;
            }
            AddLocalVarInstruction(shortOpcode, longOpcode, varIndex, tag);
        }
示例#3
0
        public static JavaArrayType JavaPrimitiveToArrayType(JavaPrimitiveType jp)
        {
            switch (jp)
            {
            case JavaPrimitiveType.Bool: return(JavaArrayType.Boolean);

            case JavaPrimitiveType.Byte: return(JavaArrayType.Byte);

            case JavaPrimitiveType.Char: return(JavaArrayType.Char);

            case JavaPrimitiveType.Double: return(JavaArrayType.Double);

            case JavaPrimitiveType.Float: return(JavaArrayType.Float);

            case JavaPrimitiveType.Int: return(JavaArrayType.Int);

            case JavaPrimitiveType.Long: return(JavaArrayType.Long);

            case JavaPrimitiveType.Ref: return(JavaArrayType.Ref);

            case JavaPrimitiveType.Short: return(JavaArrayType.Short);

            default: return(JavaArrayType.Ref);
            }
        }
示例#4
0
        private void CompileStfld(ILExpression e, ExpectType expectType)
        {
            InterField operand = resolver.Resolve((FieldReference)e.Operand, thisMethod.FullGenericArguments);
            bool needDup = ((e.ExpectedType != null) && (expectType != ExpectType.None));

            bool boxed = operand.IsStatic && operand.IsThreadLocal;

            int argIndex = 0;
            if (e.Code == ILCode.Stfld)
                CompileExpression(e.Arguments[argIndex++], ExpectType.Reference);

            CompileExpression(e.Arguments[argIndex++], boxed ? ExpectType.Boxed : GetExpectType(operand));

            if (needDup)
            {
                JavaPrimitiveType jp = JavaHelpers.InterTypeToJavaPrimitive(operand.FieldType);
                if (e.Code == ILCode.Stfld)
                {
                    if (jp.IsDoubleSlot())
                        codeGenerator.Add(Java.OpCodes.dup2_x1, null, e);
                    else
                        codeGenerator.Add(Java.OpCodes.dup_x1, null, e);
                }
                else
                {
                    if (jp.IsDoubleSlot())
                        codeGenerator.Add(Java.OpCodes.dup2, null, e);
                    else
                        codeGenerator.Add(Java.OpCodes.dup, null, e);
                }
            }

            CompileFieldStore(operand, e);
        }
示例#5
0
        private void FillVars(List <ILVariable> vars)
        {
            if (thisMethod.HasThis)
            {
                var2Index.Add(vars.Where(V => V.Name == "this").FirstOrDefault() ?? new ILVariable()
                {
                    Name = "this"
                },
                              nextVarIndex++);
            }
            for (int i = 0; i < thisMethod.Parameters.Count; i++)
            {
                InterParameter param = thisMethod.Parameters[i];
                ILVariable     var   = vars.Where(V => ((V.IsParameter) && (V.OriginalParameter.Index == param.Index))).FirstOrDefault();
                var2Index.Add(var, nextVarIndex++);

                if (param.Type.IsPrimitive)
                {
                    JavaPrimitiveType varType = JavaHelpers.PrimitiveTypeToJavaPrimitive(param.Type.PrimitiveType);

                    if ((varType == JavaPrimitiveType.Long) || (varType == JavaPrimitiveType.Double))
                    {
                        nextVarIndex++;
                    }
                }
            }

            if (thisMethod.IsVarArg)
            {
                var2Index.Add(new ILVariable()
                {
                    Name = ClassNames.VarArgParamName
                }, nextVarIndex++);
            }
        }
示例#6
0
        private void CompileNeg(ILExpression e, ExpectType expect)
        {
            CompileExpression(e.Arguments[0], ExpectType.Primitive);

            InterType         opType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments);
            JavaPrimitiveType jp     = JavaHelpers.InterTypeToJavaPrimitive(opType);

            OpCodes opcode = OpCodes.ineg;

            switch (jp)
            {
            case JavaPrimitiveType.Long: opcode = OpCodes.lneg; break;

            case JavaPrimitiveType.Float: opcode = OpCodes.fneg; break;

            case JavaPrimitiveType.Double: opcode = OpCodes.dneg; break;

            case JavaPrimitiveType.Ref:
                throw new Exception();      //TODO: normal error
            }

            codeGenerator.Add(opcode, null, e);

            TranslateType(opType, expect, e);
        }
示例#7
0
        private void CompileConvR8(ILExpression e, ExpectType expect)
        {
            InterType         gettedType = resolver.Resolve(e.Arguments[0].InferredType, thisMethod.FullGenericArguments);
            JavaPrimitiveType gettedJava = JavaHelpers.InterTypeToJavaPrimitive(gettedType);

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

            switch (gettedJava)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Short:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Int:
                codeGenerator.Add(Java.OpCodes.i2d, e);
                break;

            case JavaPrimitiveType.Long:
                codeGenerator.Add(Java.OpCodes.l2d, e);
                break;

            case JavaPrimitiveType.Float:
                codeGenerator.Add(Java.OpCodes.f2d, e);
                break;

            case JavaPrimitiveType.Double:
                break;

            default:
                Messages.Message(MessageCode.CantConvertType, gettedType.Fullname, "double");
                return;
            }

            TranslateType(InterType.PrimitiveTypes[(int)PrimitiveType.Double], expect, e);
        }
示例#8
0
        public JavaBytecodeWriter AddReturn(JavaPrimitiveType jp, object tag)
        {
            Java.OpCodes opcode = Java.OpCodes.areturn;
            switch (jp)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Int:
            case JavaPrimitiveType.Short:
                opcode = Java.OpCodes.ireturn;
                break;

            case JavaPrimitiveType.Long: opcode = Java.OpCodes.lreturn; break;

            case JavaPrimitiveType.Float: opcode = Java.OpCodes.freturn; break;

            case JavaPrimitiveType.Double: opcode = Java.OpCodes.dreturn; break;

            case JavaPrimitiveType.Void: opcode = Java.OpCodes._return; break;
            }

            AddInstruction(new JavaInstruction(opcode, null, tag));

            return(this);
        }
示例#9
0
        private int GetVarIndex(ILVariable var)
        {
            if (var2Index.ContainsKey(var))
            {
                return(var2Index[var]);
            }

            int result = nextVarIndex++;

            var2Index.Add(var, result);

            InterType varType = resolver.Resolve(var.Type, thisMethod.FullGenericArguments);

            if (varType.IsPrimitive)
            {
                JavaPrimitiveType javaPrimitiv = JavaHelpers.PrimitiveTypeToJavaPrimitive(varType.PrimitiveType);
                if ((javaPrimitiv == JavaPrimitiveType.Long) || (javaPrimitiv == JavaPrimitiveType.Double))
                {
                    nextVarIndex++;
                }
            }
            else if (varType.IsValueType)
            {
                valueTypesVars.Add(new ValueTypeVar(varType, result));
            }


            return(result);
        }
示例#10
0
        private void CompileConvTo8(ILExpression e, ExpectType expect)
        {
            InterType         gettedType = resolver.Resolve(e.Arguments[0].InferredType, thisMethod.FullGenericArguments);
            JavaPrimitiveType gettedJava = JavaHelpers.InterTypeToJavaPrimitive(gettedType);

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

            bool isToUnsigned   = e.Code.IsConvToUnsigned();
            bool isFromUnsigned = e.Code.IsConvFromUnsigned();
            bool isOvf          = e.Code.IsOvf();

            if (isOvf)
            {
                long   mask     = unchecked ((long)0xffffffffffffffffL);
                double minValue = (double)long.MinValue;
                double maxValue = (double)long.MaxValue;

                if (isToUnsigned)
                {
                    minValue = (double)ulong.MinValue;
                    maxValue = (double)ulong.MaxValue;
                }

                if ((isToUnsigned && !isFromUnsigned) || (!isToUnsigned && isFromUnsigned))
                {
                    mask = 0x7fffffffffffffffL;
                }
                CompileCheckOvf(e, gettedJava, mask, minValue, maxValue);
            }

            switch (gettedJava)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Short:
            case JavaPrimitiveType.Int:
                codeGenerator.Add(OpCodes.i2l, null, e);
                break;

            case JavaPrimitiveType.Long:
                break;

            case JavaPrimitiveType.Float:
                codeGenerator.Add(OpCodes.f2l, null, e);
                break;

            case JavaPrimitiveType.Double:
                codeGenerator.Add(OpCodes.d2l, null, e);
                break;

            default: throw new Exception();     //TODO: Normal error
            }

            TranslateType(InterType.PrimitiveTypes[(int)(isToUnsigned ? PrimitiveType.UInt64 : PrimitiveType.Int64)], expect, e);
        }
示例#11
0
        private void CompileStelem(ILExpression e, ExpectType expect)
        {
            TypeReference typeRef = e.Operand as TypeReference ?? e.InferredType;

            InterType operand = null;

            if (typeRef != null)
            {
                operand = resolver.Resolve(typeRef, thisMethod.FullGenericArguments);
            }
            else
            {
                switch (e.Code)
                {
                case ILCode.Stelem_I: operand = InterType.PrimitiveTypes[(int)(Program.AsX64 ? PrimitiveType.Int64 : PrimitiveType.Int32)]; break;

                case ILCode.Stelem_I1: operand = InterType.PrimitiveTypes[(int)PrimitiveType.SByte]; break;

                case ILCode.Stelem_I2: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int16]; break;

                case ILCode.Stelem_I4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int32]; break;

                case ILCode.Stelem_I8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Int64]; break;

                case ILCode.Stelem_R4: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Single]; break;

                case ILCode.Stelem_R8: operand = InterType.PrimitiveTypes[(int)PrimitiveType.Double]; break;
                }
            }

            JavaPrimitiveType valueJPType = operand != null?JavaHelpers.InterTypeToJavaPrimitive(operand) : JavaPrimitiveType.Ref;

            JavaArrayType arrType         = JavaHelpers.JavaPrimitiveToArrayType(valueJPType);
            ExpectType    valueExpectType = operand != null?GetExpectType(operand) : ExpectType.Reference;

            bool needDup = ((e.ExpectedType != null) && (expect != ExpectType.None));

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

            if (needDup)
            {
                if (valueJPType.IsDoubleSlot())
                {
                    codeGenerator.Add(Java.OpCodes.dup2_x2, null, e);
                }
                else
                {
                    codeGenerator.Add(Java.OpCodes.dup_x2, null, e);
                }
            }

            codeGenerator.AddArrayStore(arrType, e);
        }
 private ExpectType GetExpectType(JavaPrimitiveType type)
 {
     if (type == JavaPrimitiveType.Ref)
     {
         return(ExpectType.Reference);
     }
     else
     {
         return(ExpectType.Primitive);
     }
 }
示例#13
0
 private string GetByRefGetValueDescriptor(JavaPrimitiveType type)
 {
     if (type == JavaPrimitiveType.Ref)
     {
         return("()L" + TypeNameToJava(ClassNames.JavaObject) + ";");
     }
     else
     {
         return("()" + JavaPrimitive2FieldChar[(int)type] + "");
     }
 }
        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);
                }
            }
        }
示例#15
0
        private void CompileRemUn(ILExpression e, ExpectType expect)
        {
            if (!Program.Unsigned)
            {
                CompileMath(e, expect, OpCodes.irem, OpCodes.lrem, OpCodes.frem, OpCodes.drem);
                return;
            }

            InterType         opType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments);
            JavaPrimitiveType jp     = JavaHelpers.InterTypeToJavaPrimitive(opType);

            if ((jp == JavaPrimitiveType.Bool) || (jp == JavaPrimitiveType.Byte) || (jp == JavaPrimitiveType.Char) ||
                (jp == JavaPrimitiveType.Short))
            {
                //this types are already growed up to int
                CompileExpression(e.Arguments[0], ExpectType.Primitive);
                CompileExpression(e.Arguments[1], ExpectType.Primitive);
                codeGenerator.Add(OpCodes.irem);
            }
            else if (jp == JavaPrimitiveType.Int)
            {
                //grow up int to long
                CompileExpression(e.Arguments[0], ExpectType.Primitive);
                codeGenerator
                .Add(OpCodes.i2l, null, e)
                .AddLongConst(0xffffffff, e)
                .Add(OpCodes.land, e);

                CompileExpression(e.Arguments[0], ExpectType.Primitive);
                codeGenerator
                .Add(OpCodes.i2l, null, e)
                .AddLongConst(0xffffffff, e)
                .Add(OpCodes.land, e);

                codeGenerator
                .Add(OpCodes.lrem, e)
                .Add(OpCodes.l2i);
            }
            else if (jp == JavaPrimitiveType.Long)
            {
                //call special method from corlib
                CompileExpression(e.Arguments[0], ExpectType.Primitive);
                CompileExpression(e.Arguments[1], ExpectType.Primitive);
                resolver.Resolve(ClassNames.CIL2JavaVESInstructions.ClassName);
                codeGenerator.Add(OpCodes.invokestatic, ClassNames.CIL2JavaVESInstructions.UInt64RemainderRef);
            }
            else
            {
                throw new Exception();  //TODO: Normal error
            }
            TranslateType(opType, expect, e);
        }
示例#16
0
        public JavaBytecodeWriter AddLocalVarInstruction(LocalVarInstruction instr, JavaPrimitiveType varType, int varIndex, object tag)
        {
            if (instr == LocalVarInstruction.Load)
            {
                AddLocalVarLoad(varType, varIndex, tag);
            }
            else
            {
                AddLocalVarStore(varType, varIndex, tag);
            }

            return(this);
        }
示例#17
0
        private void PreprocessorPrepareUninitializedLocalVars()
        {
            foreach (ILVariable v in uninitializedLocals)
            {
                int               varIndex = GetVarIndex(v);
                InterType         varType  = resolver.Resolve(v.Type, thisMethod.FullGenericArguments);
                JavaPrimitiveType jp       = JavaHelpers.InterTypeToJavaPrimitive(varType);

                codeGenerator
                .AddDefaultValue(jp)
                .AddStore(jp, varIndex);
            }
        }
示例#18
0
        public JavaBytecodeWriter AddPop(JavaPrimitiveType javaPrimitiveType, object tag)
        {
            if ((javaPrimitiveType == JavaPrimitiveType.Long) || (javaPrimitiveType == JavaPrimitiveType.Double))
            {
                AddInstruction(new JavaInstruction(Java.OpCodes.pop2, null, tag));
            }
            else
            {
                AddInstruction(new JavaInstruction(Java.OpCodes.pop, null, tag));
            }

            return(this);
        }
示例#19
0
        public static bool IsIntSlot(this JavaPrimitiveType jp)
        {
            switch (jp)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Int:
            case JavaPrimitiveType.Short:
                return(true);

            default: return(false);
            }
        }
示例#20
0
        private void CompileBrBool(ILExpression e, ExpectType expect, bool brOnTrue)
        {
            JavaPrimitiveType gettedType = JavaHelpers.InterTypeToJavaPrimitive(resolver.Resolve(
                                                                                    e.InferredType, thisMethod.FullGenericArguments));

            OpCodes brInstr = brOnTrue ? OpCodes.ifne : OpCodes.ifeq;

            if (gettedType == JavaPrimitiveType.Ref)
            {
                brInstr = brOnTrue ? OpCodes.ifnonnull : OpCodes.ifnull;
            }

            codeGenerator.Add(brInstr, ((ILLabel)e.Operand).Name, e);
        }
示例#21
0
        private int GetNextFreeVar(JavaPrimitiveType type)
        {
            int result = -1;

            if (freeVars.Count > 0)
            {
                if ((type == JavaPrimitiveType.Long) || (type == JavaPrimitiveType.Double))
                {
                    for (int i = 0; i < freeVars.Count; i++)
                    {
                        if (freeVars.Contains(freeVars[i] + 1))
                        {
                            result = freeVars[i];
                            break;
                        }
                    }

                    if (result > 0)
                    {
                        freeVars.Remove(result);
                        freeVars.Remove(result + 1);
                        tempVars.Add(new TempVar()
                        {
                            type = type, index = result, startInstr = codeGenerator.NextInstructionIndex, endInstr = -1
                        });
                        return(result);
                    }
                }
                else
                {
                    result = freeVars.Last();
                    freeVars.Remove(result);
                    tempVars.Add(new TempVar()
                    {
                        type = type, index = result, startInstr = codeGenerator.NextInstructionIndex, endInstr = -1
                    });
                    return(result);
                }
            }
            result = nextVarIndex++;
            if ((type == JavaPrimitiveType.Long) || (type == JavaPrimitiveType.Double))
            {
                nextVarIndex++;
            }
            tempVars.Add(new TempVar()
            {
                type = type, index = result, startInstr = codeGenerator.NextInstructionIndex, endInstr = -1
            });
            return(result);
        }
示例#22
0
        Java.Constants.MethodRef IByRefController.GetByRefSetValueMethodRef(JavaPrimitiveType type)
        {
            JavaByRefType byRefType = new JavaByRefType(ByRefPlace.Unknown, type);
            string        descr     = "L" + TypeNameToJava(ClassNames.JavaObject) + ";";

            if (type != JavaPrimitiveType.Ref)
            {
                descr = JavaPrimitive2FieldChar[(int)type].ToString();
            }

            return(new Java.Constants.MethodRef(
                       TypeNameToJava(byRefType.ToString()),
                       ClassNames.ByRef.SetValueMethodName,
                       "(" + descr + ")V"));
        }
示例#23
0
        private void TranslateToBool(TypeReference inferredType, ref Java.OpCodes cmpOp, object tag)
        {
            JavaPrimitiveType gettedType = JavaHelpers.InterTypeToJavaPrimitive(resolver.Resolve(
                                                                                    inferredType, thisMethod.FullGenericArguments));

            switch (gettedType)
            {
            case JavaPrimitiveType.Double: codeGenerator.Add(Java.OpCodes.d2i, null, tag); break;

            case JavaPrimitiveType.Float: codeGenerator.Add(Java.OpCodes.f2i, null, tag); break;

            case JavaPrimitiveType.Long: codeGenerator.Add(Java.OpCodes.l2i, null, tag); break;

            case JavaPrimitiveType.Ref: cmpOp = (cmpOp == Java.OpCodes.ifne ? Java.OpCodes.ifnonnull : Java.OpCodes.ifnull); break;
            }
        }
示例#24
0
        private void FreeVar(int varType, JavaPrimitiveType type)
        {
            freeVars.Add(varType);
            if ((type == JavaPrimitiveType.Double) || (type == JavaPrimitiveType.Long))
            {
                freeVars.Add(varType + 1);
            }

            var tmpVar      = tempVars.Where(TV => TV.index == varType && TV.type == type).FirstOrDefault();
            int tmpVarIndex = tempVars.IndexOf(tmpVar);

            if (tmpVarIndex >= 0)
            {
                tmpVar.endInstr       = codeGenerator.NextInstructionIndex;
                tempVars[tmpVarIndex] = tmpVar;
            }
        }
示例#25
0
        private void GenerateBaseByRefType(JavaPrimitiveType type)
        {
            if ((baseTypesGenerated & (1 << (int)type)) != 0)
            {
                return;
            }

            Java.Class javaClass = new Java.Class();
            javaClass.AccessFlag = Java.ClassAccessFlag.Abstract | Java.ClassAccessFlag.Public | Java.ClassAccessFlag.Super;
            javaClass.ThisClass  = TypeNameToJava(new JavaByRefType(ByRefPlace.Unknown, type).ToString());
            javaClass.SuperClass = TypeNameToJava(ClassNames.JavaObject);

            Java.Method ctor = new Java.Method();
            ctor.AccessFlags = Java.MethodAccessFlags.Public;
            ctor.Name        = ClassNames.JavaConstructorMethodName;
            ctor.Descriptor  = "()V";

            JavaBytecodeWriter ctorCodeGenerator = new JavaBytecodeWriter();

            ctorCodeGenerator
            .AddLocalVarInstruction(LocalVarInstruction.Load, JavaPrimitiveType.Ref, 0, null)
            .AddInstruction(new JavaInstruction(Java.OpCodes.invokespecial, ClassNames.JavaObjectCtorMethodRef))
            .AddReturn(JavaPrimitiveType.Void, null);
            Java.Attributes.Code ctorCode = new Java.Attributes.Code();
            ctorCode.CodeBytes = ctorCodeGenerator.Link(javaClass.ConstantPool);
            ctorCode.MaxLocals = 1;
            ctorCode.MaxStack  = 1;
            ctor.Attributes.Add(ctorCode);
            javaClass.Methods.Add(ctor);

            Java.Method getValue = new Java.Method();
            getValue.AccessFlags = Java.MethodAccessFlags.Abstract | Java.MethodAccessFlags.Public;
            getValue.Name        = ClassNames.ByRef.GetValueMethodName;
            getValue.Descriptor  = GetByRefGetValueDescriptor(type);
            javaClass.Methods.Add(getValue);

            Java.Method setValue = new Java.Method();
            setValue.AccessFlags = Java.MethodAccessFlags.Abstract | Java.MethodAccessFlags.Public;
            setValue.Name        = ClassNames.ByRef.SetValueMethodName;
            setValue.Descriptor  = GetByRefSetValueDescriptor(type);
            javaClass.Methods.Add(setValue);

            WriteClass(javaClass);

            baseTypesGenerated |= (1 << (int)type);
        }
示例#26
0
        private void GenerateFieldAccessors(InterType type)
        {
            for (int i = 0; i < type.FieldAccessors.Count; i++)
            {
                FieldAccessor fld          = type.FieldAccessors[i];
                string        fldTypeDescr = GetFieldDescriptor(fld.Field.FieldType);
                if ((fld.Field.IsStatic) && (fld.Field.IsThreadLocal))
                {
                    fldTypeDescr = "L" + TypeNameToJava(ClassNames.JavaLangThreadLocal.ClassName) + ";";
                }

                JavaPrimitiveType javaFldType = JavaHelpers.InterTypeToJavaPrimitive(fld.Field.FieldType);
                FieldRef          fldRef      = new FieldRef(TypeNameToJava(type.Fullname), FieldNameToJava(fld.Field.Name), fldTypeDescr);

                Method result = new Method();
                result.AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Static;
                result.Name        = ClassNames.FieldAccessorPrefix + i.ToString();

                JavaBytecodeWriter codeWriter = new JavaBytecodeWriter();
                if (!fld.Field.IsStatic)
                {
                    codeWriter.Add(OpCodes.aload_0);
                }

                if (fld.Type == FieldAccessorType.Getter)
                {
                    result.Descriptor = "(" + (fld.Field.IsStatic ? "" : GetFieldDescriptor(type)) + ")" + fldTypeDescr;
                    codeWriter
                    .Add(fld.Field.IsStatic ? OpCodes.getstatic : OpCodes.getfield, fldRef)
                    .AddReturn(javaFldType);
                }
                else
                {
                    result.Descriptor = "(" + (fld.Field.IsStatic ? "" : GetFieldDescriptor(type)) + fldTypeDescr + ")V";
                    codeWriter
                    .AddLoad(javaFldType, 1)
                    .Add(fld.Field.IsStatic ? OpCodes.putstatic : OpCodes.putfield, fldRef)
                    .Add(OpCodes._return);
                }

                result.Attributes.Add(codeWriter.End(currentJavaClass.ConstantPool));
                currentJavaClass.Methods.Add(result);
            }
        }
示例#27
0
        private void CompileNullCoalescing(ILExpression e, ExpectType expect)
        {
            InterType         inferredType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments);
            JavaPrimitiveType jp           = JavaHelpers.InterTypeToJavaPrimitive(inferredType);

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

            CompileExpression(e.Arguments[0], expect);
            codeGenerator.Add(jp.IsDoubleSlot() ? OpCodes.dup2 : OpCodes.dup, null, e);

            if (jp == JavaPrimitiveType.Ref)
            {
                codeGenerator.Add(Java.OpCodes.ifnonnull, exitLabel, e);
            }
            else if (jp.IsIntSlot())
            {
                codeGenerator.Add(Java.OpCodes.ifne, exitLabel, e);
            }
            else
            {
                if (jp == JavaPrimitiveType.Float)
                {
                    codeGenerator.Add(OpCodes.fconst_0, null, e).Add(OpCodes.fcmpg, null, e);
                }
                else if (jp == JavaPrimitiveType.Double)
                {
                    codeGenerator.Add(OpCodes.dconst_0, null, e).Add(OpCodes.dcmpg, null, e);
                }
                else if (jp == JavaPrimitiveType.Long)
                {
                    codeGenerator.Add(OpCodes.lconst_0, null, e).Add(OpCodes.lcmp, null, e);
                }

                codeGenerator.Add(OpCodes.ifeq, exitLabel, e);
            }

            codeGenerator.Add(jp.IsDoubleSlot() ? OpCodes.pop2 : OpCodes.pop);
            CompileExpression(e.Arguments[1], expect);
            codeGenerator.Label(exitLabel);
        }
示例#28
0
        private void CompileNot(ILExpression e, ExpectType expect)
        {
            CompileExpression(e.Arguments[0], ExpectType.Primitive);

            InterType         opType = resolver.Resolve(e.InferredType, thisMethod.FullGenericArguments);
            JavaPrimitiveType jp     = JavaHelpers.InterTypeToJavaPrimitive(opType);

            if (jp == JavaPrimitiveType.Long)
            {
                codeGenerator
                .AddLongConst(-1L, e)
                .Add(OpCodes.lxor, null, e);
            }
            else
            {
                codeGenerator
                .Add(OpCodes.iconst_m1, null, e)
                .Add(OpCodes.ixor, null, e);
            }

            TranslateType(opType, expect, e);
        }
示例#29
0
        private void CompileStind(ILExpression e, ExpectType expectType)
        {
            JavaPrimitiveType type = JavaPrimitiveType.Ref;

            if (e.Operand != null)
            {
                InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments);

                if ((operand.IsPrimitive) && ((operand.PrimitiveType == PrimitiveType.Byte) ||
                                              (operand.PrimitiveType == PrimitiveType.SByte)))
                {
                    operand = resolver.Resolve(e.Arguments[0].InferredType, thisMethod.FullGenericArguments).ElementType;
                }

                type = JavaHelpers.InterTypeToJavaPrimitive(operand);
            }

            bool needDup = ((e.ExpectedType != null) && (expectType != ExpectType.None));

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

            Java.Constants.MethodRef setMethodRef = byRefController.GetByRefSetValueMethodRef(type);

            if (needDup)
            {
                if (type.IsDoubleSlot())
                {
                    codeGenerator.Add(OpCodes.dup2_x1, null, e);
                }
                else
                {
                    codeGenerator.Add(OpCodes.dup_x1, null, e);
                }
            }

            codeGenerator.Add(OpCodes.invokevirtual, setMethodRef, e);
        }
示例#30
0
        private void CompileInitobj(ILExpression e, ExpectType expect)
        {
            InterType operand = resolver.Resolve((TypeReference)e.Operand, thisMethod.FullGenericArguments);

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

            if (!operand.IsValueType)
            {
                JavaPrimitiveType jp          = JavaHelpers.InterTypeToJavaPrimitive(operand);
                MethodRef         setValueRef = byRefController.GetByRefSetValueMethodRef(jp);

                switch (jp)
                {
                case JavaPrimitiveType.Bool:
                case JavaPrimitiveType.Byte:
                case JavaPrimitiveType.Char:
                case JavaPrimitiveType.Int:
                case JavaPrimitiveType.Short:
                    codeGenerator.AddIntConst(0, e);
                    break;

                case JavaPrimitiveType.Long: codeGenerator.AddLongConst(0L, e); break;

                case JavaPrimitiveType.Float: codeGenerator.AddFloatConst(0.0f, e); break;

                case JavaPrimitiveType.Double: codeGenerator.AddDoubleConst(0.0, e); break;

                case JavaPrimitiveType.Ref: codeGenerator.Add(OpCodes.aconst_null, e); break;
                }

                codeGenerator.Add(OpCodes.invokevirtual, setValueRef, e);
            }
            else
            {
                codeGenerator.Add(OpCodes.invokevirtual, new MethodRef(namesController.TypeNameToJava(operand),
                                                                       ClassNames.ValueTypeZeroFill, "()V"));
            }
        }