Example #1
0
        /// <summary>
        /// Create code to box the given source value into the given type.
        /// </summary>
        public static RLRange Box(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec source, XTypeReference type, DexTargetPackage targetPackage, IRegisterAllocator frame)
        {
            if (type.IsPrimitive)
            {
                if (type.IsByte()) builder.Add(sequencePoint, RCode.Int_to_byte, source.Register, source.Register);
                else if (type.IsUInt16()) builder.Add(sequencePoint, RCode.Int_to_short, source.Register, source.Register);
                // Call appropriate valueOf method
                var boxedType = type.Module.TypeSystem.Object;
                var r = frame.AllocateTemp(boxedType.GetReference(targetPackage));
                var call = builder.Add(sequencePoint, RCode.Invoke_static, type.GetBoxValueOfMethod(), source.Registers);
                var last = builder.Add(sequencePoint, RCode.Move_result_object, r);
                return new RLRange(call, last, r);
            }
            if (type.IsGenericParameter)
            {
                var nop = builder.Add(sequencePoint, RCode.Nop);
                return new RLRange(nop, source);
            }
            XTypeDefinition typeDef ;
            if (type.TryResolve(out typeDef) && (typeDef.IsEnum))
            {
                // Call appropriate valueOf method
                /*var boxedType = type.Module.TypeSystem.Object;
                var r = frame.AllocateTemp(boxedType.GetReference(target, nsConverter));
                var call = builder.Add(sequencePoint, RCode.Invoke_static, typeDef.GetEnumUnderlyingType().GetBoxValueOfMethod(), source.Registers);
                var last = builder.Add(sequencePoint, RCode.Move_result_object, r);
                return new RLRange(call, last, r);*/
            }

            // Just cast
            var checkCast = builder.Add(sequencePoint, RCode.Check_cast, type.GetReference(targetPackage), source);
            return new RLRange(checkCast, source);
        }
Example #2
0
        /// <summary>
        /// Ensure the given value register is a temp register.
        /// If it is not, allocate a temp register an copy to it.
        /// </summary>
        public static RLRange EnsureTemp(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec value, IRegisterAllocator frame)
        {
            // Is temp?
            if (value.Register.Category == RCategory.Temp)
            {
                return(new RLRange(value));
            }
            // No, allocate temp
            var         tmp = frame.AllocateTemp(value.Type);
            Instruction ins;

            switch (value.Register.Type)
            {
            case RType.Object:
                ins = builder.Add(sequencePoint, RCode.Move_object, tmp.Register, value.Register);
                break;

            case RType.Wide:
                ins = builder.Add(sequencePoint, RCode.Move_wide, tmp.Register, value.Register);
                break;

            case RType.Value:
                ins = builder.Add(sequencePoint, RCode.Move, tmp.Register, value.Register);
                break;

            default:
                throw new ArgumentException("Unknown register type " + (int)value.Register.Type);
            }
            return(new RLRange(ins, tmp));
        }
Example #3
0
        /// <summary>
        /// Create code to unbox the given source array of boxed type elements resulting from a call into an array of primitive elements.
        /// </summary>
        public static RLRange UnboxGenericArrayResult(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec boxedArray,
                                                      XTypeReference type, DexTargetPackage targetPackage, IRegisterAllocator frame, AssemblyCompiler compiler)
        {
            var internalBoxingType = compiler.GetDot42InternalType("Boxing").Resolve();
            var primitiveArray     = frame.AllocateTemp(type.GetReference(targetPackage));
            var ilUnboxMethod      = internalBoxingType.Methods.First(x => x.Name.StartsWith("Unbox") && (x.Parameters.Count == 1) && (x.ReturnType.IsSame(type, true)));
            var unboxMethod        = ilUnboxMethod.GetReference(targetPackage);
            var call      = builder.Add(sequencePoint, RCode.Invoke_static, unboxMethod, boxedArray);
            var saveArray = builder.Add(sequencePoint, RCode.Move_result_object, primitiveArray);

            return(new RLRange(call, saveArray, primitiveArray));
        }
Example #4
0
        /// <summary>
        /// Create code to unbox the given source value into the given type.
        /// </summary>
        public static RLRange Unbox(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec source, XTypeReference type, AssemblyCompiler compiler, DexTargetPackage targetPackage, IRegisterAllocator frame)
        {
            if (type.IsPrimitive)
            {
                RCode convertAfterCode;
                var   rUnboxed         = frame.AllocateTemp(type.GetReference(targetPackage));
                var   unboxValueMethod = type.GetUnboxValueMethod(compiler, targetPackage, out convertAfterCode);
                var   first            = builder.Add(sequencePoint, RCode.Invoke_static, unboxValueMethod, source);
                var   last             = builder.Add(sequencePoint, type.MoveResult(), rUnboxed);
                if (convertAfterCode != RCode.Nop)
                {
                    last = builder.Add(sequencePoint, convertAfterCode, rUnboxed, rUnboxed);
                }

                return(new RLRange(first, last, rUnboxed));
            }

            XTypeDefinition enumTypeDef;

            if (type.IsEnum(out enumTypeDef))
            {
                var rUnboxed         = frame.AllocateTemp(type.GetReference(targetPackage));
                var unboxValueMethod = enumTypeDef.Methods.First(x => x.Name == NameConstants.Enum.UnboxMethodName).GetReference(targetPackage);
                var first            = builder.Add(sequencePoint, RCode.Invoke_static, unboxValueMethod, source);
                var last             = builder.Add(sequencePoint, type.MoveResult(), rUnboxed);
                return(new RLRange(first, last, rUnboxed));
            }

            if (!type.IsGenericParameter)
            {
                // Just cast
                var checkCast = builder.Add(sequencePoint, RCode.Check_cast, type.GetReference(targetPackage), source);
                return(new RLRange(checkCast, source));
            }

            // Do nothing
            var nop = builder.Add(sequencePoint, RCode.Nop);

            return(new RLRange(nop, source));
        }
Example #5
0
        /// <summary>
        /// Create code to box the given source array of primitive type elements into an array of boxed elements.
        /// </summary>
        public static RLRange BoxGenericArray(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec source,
                                              XTypeReference type, DexTargetPackage targetPackage, IRegisterAllocator frame, AssemblyCompiler compiler)
        {
            var objectArrayType    = new DexLib.ArrayType(new ClassReference("java.lang.Object"));
            var boxedArray         = frame.AllocateTemp(objectArrayType);
            var internalBoxingType = compiler.GetDot42InternalType("Boxing").Resolve();
            var ilBoxMethod        = internalBoxingType.Methods.First(x => x.EqualsName("Box") && (x.Parameters.Count == 1) && (x.Parameters[0].ParameterType.IsSame(type, true)));
            var boxMethod          = ilBoxMethod.GetReference(targetPackage);
            var call      = builder.Add(sequencePoint, RCode.Invoke_static, boxMethod, source);
            var saveArray = builder.Add(sequencePoint, RCode.Move_result_object, boxedArray);

            return(new RLRange(call, saveArray, boxedArray));
        }
Example #6
0
        /// <summary>
        /// Create code to box the given source value into the given type.
        /// </summary>
        public static RLRange Box(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec source, XTypeReference type, DexTargetPackage targetPackage, IRegisterAllocator frame)
        {
            if (type.IsPrimitive)
            {
                if (type.IsByte())
                {
                    builder.Add(sequencePoint, RCode.Int_to_byte, source.Register, source.Register);
                }
                else if (type.IsUInt16())
                {
                    builder.Add(sequencePoint, RCode.Int_to_short, source.Register, source.Register);
                }
                // Call appropriate valueOf method
                var boxedType = type.Module.TypeSystem.Object;
                var r         = frame.AllocateTemp(boxedType.GetReference(targetPackage));
                var call      = builder.Add(sequencePoint, RCode.Invoke_static, type.GetBoxValueOfMethod(), source.Registers);
                var last      = builder.Add(sequencePoint, RCode.Move_result_object, r);
                return(new RLRange(call, last, r));
            }
            if (type.IsGenericParameter)
            {
                var nop = builder.Add(sequencePoint, RCode.Nop);
                return(new RLRange(nop, source));
            }
            XTypeDefinition typeDef;

            if (type.TryResolve(out typeDef) && (typeDef.IsEnum))
            {
                // Call appropriate valueOf method

                /*var boxedType = type.Module.TypeSystem.Object;
                 * var r = frame.AllocateTemp(boxedType.GetReference(target, nsConverter));
                 * var call = builder.Add(sequencePoint, RCode.Invoke_static, typeDef.GetEnumUnderlyingType().GetBoxValueOfMethod(), source.Registers);
                 * var last = builder.Add(sequencePoint, RCode.Move_result_object, r);
                 * return new RLRange(call, last, r);*/
            }

            // Just cast
            var checkCast = builder.Add(sequencePoint, RCode.Check_cast, type.GetReference(targetPackage), source);

            return(new RLRange(checkCast, source));
        }
Example #7
0
 /// <summary>
 /// Ensure the given value register is a temp register.
 /// If it is not, allocate a temp register an copy to it.
 /// </summary>
 public static RLRange EnsureTemp(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec value, IRegisterAllocator frame)
 {
     // Is temp?
     if (value.Register.Category == RCategory.Temp)
         return new RLRange(value);
     // No, allocate temp
     var tmp = frame.AllocateTemp(value.Type);
     Instruction ins;
     switch (value.Register.Type)
     {
         case RType.Object:
             ins = builder.Add(sequencePoint, RCode.Move_object, tmp.Register, value.Register);
             break;
         case RType.Wide:
             ins = builder.Add(sequencePoint, RCode.Move_wide, tmp.Register, value.Register);
             break;
         case RType.Value:
             ins = builder.Add(sequencePoint, RCode.Move, tmp.Register, value.Register);
             break;
         default:
             throw new ArgumentException("Unknown register type " + (int)value.Register.Type);
     }
     return new RLRange(ins, tmp);
 }
Example #8
0
 /// <summary>
 /// Create code to unbox the given source array of boxed type elements resulting from a call into an array of primitive elements.
 /// </summary>
 public static RLRange UnboxGenericArrayResult(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec boxedArray,
                                        XTypeReference type, DexTargetPackage targetPackage, IRegisterAllocator frame, AssemblyCompiler compiler)
 {
     var internalBoxingType = compiler.GetDot42InternalType("Boxing").Resolve();
     var primitiveArray = frame.AllocateTemp(type.GetReference(targetPackage));
     var ilUnboxMethod = internalBoxingType.Methods.First(x => x.Name.StartsWith("Unbox") && (x.Parameters.Count == 1) && (x.ReturnType.IsSame(type, true)));
     var unboxMethod = ilUnboxMethod.GetReference(targetPackage);
     var call = builder.Add(sequencePoint, RCode.Invoke_static, unboxMethod, boxedArray);
     var saveArray = builder.Add(sequencePoint, RCode.Move_result_object, primitiveArray);
     return new RLRange(call, saveArray, primitiveArray);
 }
Example #9
0
 /// <summary>
 /// Create code to box the given source array of primitive type elements into an array of boxed elements.
 /// </summary>
 public static RLRange BoxGenericArray(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec source,
                                        XTypeReference type, DexTargetPackage targetPackage, IRegisterAllocator frame, AssemblyCompiler compiler)
 {
     var objectArrayType = new DexLib.ArrayType(new ClassReference("java.lang.Object"));
     var boxedArray = frame.AllocateTemp(objectArrayType);
     var internalBoxingType = compiler.GetDot42InternalType("Boxing").Resolve();
     var ilBoxMethod = internalBoxingType.Methods.First(x => x.EqualsName("Box") && (x.Parameters.Count == 1) && (x.Parameters[0].ParameterType.IsSame(type, true)));
     var boxMethod = ilBoxMethod.GetReference(targetPackage);
     var call = builder.Add(sequencePoint, RCode.Invoke_static, boxMethod, source);
     var saveArray = builder.Add(sequencePoint, RCode.Move_result_object, boxedArray);
     return new RLRange(call, saveArray, boxedArray);
 }
Example #10
0
        /// <summary>
        /// Create code to unbox the given source value into the given type.
        /// </summary>
        public static RLRange Unbox(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec source, XTypeReference type, AssemblyCompiler compiler, DexTargetPackage targetPackage, IRegisterAllocator frame)
        {
            if (type.IsPrimitive)
            {
                RCode convertAfterCode;
                var rUnboxed = frame.AllocateTemp(type.GetReference(targetPackage));
                var unboxValueMethod = type.GetUnboxValueMethod(compiler, targetPackage, out convertAfterCode);
                var first = builder.Add(sequencePoint, RCode.Invoke_static, unboxValueMethod, source);
                var last = builder.Add(sequencePoint, type.MoveResult(), rUnboxed);
                if (convertAfterCode != RCode.Nop)
                {
                    last = builder.Add(sequencePoint, convertAfterCode, rUnboxed, rUnboxed);
                }

                return new RLRange(first, last, rUnboxed);
            }

            XTypeDefinition enumTypeDef;
            if (type.IsEnum(out enumTypeDef))
            {
                var rUnboxed = frame.AllocateTemp(type.GetReference(targetPackage));
                var unboxValueMethod = enumTypeDef.Methods.First(x => x.Name == NameConstants.Enum.UnboxMethodName).GetReference(targetPackage);
                var first = builder.Add(sequencePoint, RCode.Invoke_static, unboxValueMethod, source);
                var last = builder.Add(sequencePoint, type.MoveResult(), rUnboxed);
                return new RLRange(first, last, rUnboxed);                
            }

            if (!type.IsGenericParameter)
            {
                // Just cast
                var checkCast = builder.Add(sequencePoint, RCode.Check_cast, type.GetReference(targetPackage), source);
                return new RLRange(checkCast, source);
            }

            // Do nothing
            var nop = builder.Add(sequencePoint, RCode.Nop);
            return new RLRange(nop, source);
        }