Exemplo n.º 1
0
        /// <summary>
        /// Create and add GenericInstance field.
        /// </summary>
        protected virtual void CreateGenericInstanceFields(DexTargetPackage targetPackage)
        {
            var accessFlags = AccessFlags.Synthetic;

            accessFlags |= Type.IsInterface ? AccessFlags.Public : AccessFlags.Protected;

            if (BuildGenericInstanceFieldAsArray)
            {
                var field = new FieldDefinition
                {
                    Name        = CreateUniqueFieldName("$g"),
                    Type        = FrameworkReferences.ClassArray,
                    AccessFlags = accessFlags,
                    Owner       = Class
                };
                Class.Fields.Add(field);
                Class.GenericInstanceFields.Add(field);
            }
            else
            {
                for (int i = 0; i < typeDef.GenericParameters.Count; ++i)
                {
                    var field = new FieldDefinition
                    {
                        Name        = CreateUniqueFieldName("$g", 1),
                        Type        = FrameworkReferences.Class,
                        AccessFlags = accessFlags,
                        Owner       = Class
                    };
                    Class.Fields.Add(field);
                    Class.GenericInstanceFields.Add(field);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Create and add GenericInstance field.
        /// </summary>
        protected virtual void CreateGenericInstanceField(DexTargetPackage targetPackage)
        {
            var field = new FieldDefinition {
                Name        = CreateUniqueFieldName("$g"),
                Type        = FrameworkReferences.ClassArray,
                AccessFlags = AccessFlags.Protected | AccessFlags.Synthetic,
                Owner       = Class
            };

            Class.Fields.Add(field);
            Class.GenericInstanceField = field;
            var annType    = compiler.GetDot42InternalType(InternalConstants.GenericInstanceClassAnnotation).GetClassReference(targetPackage);
            var annotation = new Annotation(annType, AnnotationVisibility.Runtime,
                                            new AnnotationArgument(InternalConstants.GenericInstanceClassArgumentsField, field));

            Class.Annotations.Add(annotation);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Implement the class now that all classes have been created
        /// </summary>
        protected override void CreateMembers(DexTargetPackage targetPackage)
        {
            // Build ctors
            foreach (var baseCtor in GetBaseClassCtors())
            {
                // Build ctor
                var prototype = PrototypeBuilder.BuildPrototype(Compiler, targetPackage, null, baseCtor);
                var ctor      = new MethodDefinition(Class, "<init>", prototype);
                ctor.AccessFlags = AccessFlags.Public | AccessFlags.Constructor;
                Class.Methods.Add(ctor);
                // Create ctor body
                var ctorBody = CreateCtorBody(prototype);
                targetPackage.Record(new CompiledMethod {
                    DexMethod = ctor, RLBody = ctorBody
                });
            }

            // build original type field
            // Create field definition
            var dfield = new Dot42.DexLib.FieldDefinition();

            dfield.Owner       = Class;
            dfield.Name        = "underlying$";
            dfield.IsSynthetic = true;
            dfield.IsFinal     = true;
            dfield.IsStatic    = true;
            dfield.IsPublic    = true;

            dfield.Type = Compiler.Module.TypeSystem.Type.GetClassReference(targetPackage);

            // not sure if GetClassReference is the best way to go forward here.
            // might depend on the sort order of the class builders.
            var underlyingType = XBuilder.AsTypeReference(Compiler.Module, Type);

            dfield.Value = underlyingType.GetClassReference(targetPackage);

            Class.Fields.Add(dfield);
        }
Exemplo n.º 4
0
 public bool Equals(FieldDefinition other)
 {
     // Should be enough (ownership)
     return base.Equals(other);
 }
Exemplo n.º 5
0
        /// <summary>
        /// Create the body of the equals method.
        /// </summary>
        private static MethodBody CreateEqualsBody(ISourceLocation sequencePoint, AssemblyCompiler compiler, DexTargetPackage targetPackage, XMethodDefinition equalsMethod, Prototype equalsPrototype, FieldDefinition instanceField, ClassReference delegateClass)
        {
            MethodBody body = new MethodBody(null);

            // This pointer and method argument.
            Register rthis = body.AllocateRegister(RCategory.Argument, RType.Object);
            Register rother = body.AllocateRegister(RCategory.Argument, RType.Object);

            // Create code.
            var ins = body.Instructions;

            // Temporary parameter result.
            Register result = body.AllocateRegister(RCategory.Temp, RType.Value);

            // Prepare the return instruction.
            Instruction returnInstruction = new Instruction(RCode.Return, result);

            // Check if other object can be casted.
            ins.Add(new Instruction(RCode.Instance_of, delegateClass, new[] { result, rother }));
            ins.Add(new Instruction(RCode.If_eqz, returnInstruction, new[] { result })); // compare instance members

            // Cast of the other object.
            ins.Add(new Instruction(RCode.Check_cast, delegateClass, new[] { rother }));

            // Get instance fields of this and other.
            var thisInstance = body.AllocateRegister(RCategory.Temp, RType.Object);
            var otherInstance = body.AllocateRegister(RCategory.Temp, RType.Object);

            // Load the instance fields.
            ins.Add(new Instruction(RCode.Iget_object, thisInstance, rthis) { Operand = instanceField });
            ins.Add(new Instruction(RCode.Iget_object, otherInstance, rother) { Operand = instanceField });

            // Compare the instance fields.
            ins.Add(new Instruction(RCode.If_eq, returnInstruction, new[] { thisInstance, otherInstance })); // compare instance members

            // Set result to false if not equal.
            ins.Add(new Instruction(RCode.Const, 0, new[] { result }));

            // Add return instructions
            ins.Add(returnInstruction);

            return body;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        internal static DelegateInstanceType Create(
            ISourceLocation sequencePoint,
            AssemblyCompiler compiler,
            DexTargetPackage targetPackage,
            ClassDefinition delegateClass,
            XMethodDefinition invokeMethod,
            Prototype invokePrototype,
            XMethodDefinition equalsMethod,
            Prototype equalsPrototype,
            XMethodDefinition calledMethod)
        {
            // Prepare called method
            var target = targetPackage.DexFile;
            var owner = target.GetClass(calledMethod.DeclaringType.GetClassReference(targetPackage).Fullname) ??
                targetPackage.GetOrCreateGeneratedCodeClass();
            var calledMethodPrototype = PrototypeBuilder.BuildPrototype(compiler, targetPackage, owner, calledMethod);
            var calledMethodRef = calledMethod.GetReference(targetPackage);

            if (calledMethod.DeclaringType.HasDexImportAttribute())
            {
                // Delegate method is a Dex import method
            }
            else
            {
                // Delegate method is a .NET method
                var calledDexMethod = owner.Methods.Single(x => (x.Name == calledMethodRef.Name) && (x.Prototype.Equals(calledMethodRef.Prototype)));
                if (calledDexMethod.IsPrivate)
                {
                    calledDexMethod.IsPrivate = false;
                    calledDexMethod.IsProtected = true;
                }
            }

            var @class = new ClassDefinition();
            @class.Name = CreateInstanceTypeName(owner);
            @class.Namespace = owner.Namespace;
            @class.AccessFlags = AccessFlags.Public | AccessFlags.Final;
            owner.InnerClasses.Add(@class);

            // Set super class
            @class.SuperClass = delegateClass;

            // Implement delegate interface
            //@class.Interfaces.Add(delegateInterface);

            // Get type of instance 
            XTypeDefinition instanceType = calledMethod.DeclaringType;
            TypeReference instanceTypeRef = instanceType.GetReference(targetPackage);

            // Add instance field
            FieldDefinition instanceField = null;
            if (!calledMethod.IsStatic)
            {
                instanceField = new FieldDefinition();
                instanceField.Name = "instance";
                instanceField.Owner = @class;
                instanceField.Type = instanceTypeRef;
                instanceField.AccessFlags = AccessFlags.Private | AccessFlags.Final;
                @class.Fields.Add(instanceField);
            }

            // Add ctor
            var ctor = new Dot42.DexLib.MethodDefinition();
            ctor.Owner = @class;
            ctor.Name = "<init>";
            ctor.AccessFlags = AccessFlags.Public | AccessFlags.Constructor;
            ctor.Prototype = new Prototype(PrimitiveType.Void);
            if (!calledMethod.IsStatic)
            {
                ctor.Prototype.Parameters.Add(new Parameter(instanceTypeRef, "this"));
            }
            @class.Methods.Add(ctor);
            // Create ctor body
            var ctorBody = CreateCtorBody(calledMethod, instanceField, delegateClass);
            targetPackage.Record(new CompiledMethod() { DexMethod = ctor, RLBody = ctorBody });

            // Add Invoke method
            var invoke = new Dot42.DexLib.MethodDefinition(@class, "Invoke", invokePrototype) { AccessFlags = AccessFlags.Public };
            @class.Methods.Add(invoke);
            // Create body
            var invokeBody = CreateInvokeBody(sequencePoint, compiler, targetPackage, calledMethod, invokeMethod, invokePrototype, calledMethodPrototype, instanceField, delegateClass);
            targetPackage.Record(new CompiledMethod() { DexMethod = invoke, RLBody = invokeBody });

            // Add Equals method
            if (null != equalsMethod)
            {
                var equals = new Dot42.DexLib.MethodDefinition(@class, "equals", equalsPrototype) { AccessFlags = AccessFlags.Public };
                @class.Methods.Add(equals);
                // Create body
                if (!calledMethod.IsStatic)
                {
                    var equalsBody = CreateEqualsBody(sequencePoint, compiler, targetPackage, equalsMethod, equalsPrototype, instanceField, @class);
                    targetPackage.Record(new CompiledMethod() { DexMethod = equals, RLBody = equalsBody });
                }
                else
                {
                    var equalsBody = CreateEqualsBody();
                    targetPackage.Record(new CompiledMethod() { DexMethod = equals, RLBody = equalsBody });
                }
            }

            return new DelegateInstanceType(calledMethod, @class, ctor);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Create the body of the invoke method.
        /// </summary>
        private static MethodBody CreateInvokeBody(ISourceLocation sequencePoint, AssemblyCompiler compiler, DexTargetPackage targetPackage, XMethodDefinition calledMethod, XMethodDefinition invokeMethod, Prototype invokePrototype, Prototype calledMethodPrototype, FieldDefinition instanceField, ClassReference delegateClass)
        {
            var body = new MethodBody(null);
            var rthis = body.AllocateRegister(RCategory.Argument, RType.Object);
            foreach (var p in invokePrototype.Parameters)
            {
                if (p.Type.IsWide())
                {
                    body.AllocateWideRegister(RCategory.Argument);
                }
                else
                {
                    var type = (p.Type is PrimitiveType) ? RType.Value : RType.Object;
                    body.AllocateRegister(RCategory.Argument, type);
                }
            }
            var incomingMethodArgs = body.Registers.ToArray();

            // Create code
            var ins = body.Instructions;
            Register instance = null;
            if (!calledMethod.IsStatic)
            {
                // load instance
                instance = body.AllocateRegister(RCategory.Temp, RType.Object);
                ins.Add(new Instruction(RCode.Iget_object, instance, rthis) { Operand = instanceField });
            }
            // Invoke
            var calledMethodRef = calledMethod.GetReference(targetPackage);
            var inputArgs = calledMethod.IsStatic ? incomingMethodArgs.Skip(1).ToArray() : incomingMethodArgs;
            
            // Cast arguments (if needed)
            var outputArgs = new List<Register>();
            if (!calledMethod.IsStatic)
            {
                outputArgs.Add(instance);
            }
            var parameterIndex = 0;
            for (var i = calledMethod.IsStatic ? 0 : 1; i < inputArgs.Length; )
            {
                var invokeType = invokePrototype.Parameters[parameterIndex].Type;
                var inputIsWide = invokeType.IsWide();
                var calledType = calledMethodPrototype.Parameters[parameterIndex].Type;
                if (!invokeType.Equals(calledType))
                {
                    // Add cast / unbox
                    var source = inputIsWide
                                     ? new RegisterSpec(inputArgs[i], inputArgs[i + 1], invokeType)
                                     : new RegisterSpec(inputArgs[i], null, invokeType);
                    var tmp = ins.Unbox(sequencePoint, source, calledMethod.Parameters[parameterIndex].ParameterType, compiler, targetPackage, body);
                    outputArgs.Add(tmp.Result.Register);
                    if (calledType.IsWide())
                    {
                        outputArgs.Add(tmp.Result.Register2);
                    }
                }
                else
                {
                    outputArgs.Add(inputArgs[i]);
                    if (calledType.IsWide())
                    {
                        outputArgs.Add(inputArgs[i + 1]);
                    }
                }
                i += inputIsWide ? 2 : 1;
                parameterIndex++;
            }

            // Actual call
            ins.Add(new Instruction(calledMethod.Invoke(calledMethod, null), calledMethodRef, outputArgs.ToArray()));

            // Collect return value
            var invokeReturnType = invokePrototype.ReturnType;
            var calledReturnType = calledMethodPrototype.ReturnType;
            var needsBoxing = !invokeReturnType.Equals(calledReturnType);
            Instruction returnInstruction;

            if (calledReturnType.IsWide())
            {
                var r = body.AllocateWideRegister(RCategory.Temp);
                ins.Add(new Instruction(RCode.Move_result_wide, r.Item1));
                if (needsBoxing)
                {
                    // Box
                    var source = new RegisterSpec(r.Item1, r.Item2, calledReturnType);
                    var tmp = ins.Box(sequencePoint, source, calledMethod.ReturnType, targetPackage, body);
                    returnInstruction = new Instruction(RCode.Return_object, tmp.Result.Register);
                }
                else
                {
                    // Return wide
                    returnInstruction = new Instruction(RCode.Return_wide, r.Item1);
                }
            }
            else if (calledMethod.ReturnType.IsVoid())
            {
                // Void return
                returnInstruction = new Instruction(RCode.Return_void);
            }
            else if (calledReturnType is PrimitiveType)
            {
                // Single register return
                var r = body.AllocateRegister(RCategory.Temp, RType.Value);
                ins.Add(new Instruction(RCode.Move_result, r));
                if (needsBoxing)
                {
                    // Box
                    var source = new RegisterSpec(r, null, invokeReturnType);
                    var tmp = ins.Box(sequencePoint, source, calledMethod.ReturnType, targetPackage, body);
                    returnInstruction = new Instruction(RCode.Return_object, tmp.Result.Register);
                }
                else
                {
                    // Return 
                    returnInstruction = new Instruction(RCode.Return, r);
                }
            }
            else
            {
                var r = body.AllocateRegister(RCategory.Temp, RType.Object);
                ins.Add(new Instruction(RCode.Move_result_object, r));
                if (needsBoxing)
                {
                    // Box
                    var source = new RegisterSpec(r, null, invokeReturnType);
                    var tmp = ins.Box(sequencePoint, source, invokeMethod.ReturnType, targetPackage, body);
                    returnInstruction = new Instruction(RCode.Return_object, tmp.Result.Register);
                }
                else
                {
                    // Return 
                    returnInstruction = new Instruction(RCode.Return_object, r);
                }
            }

            // Call next delegate (if any)
            var next = body.AllocateRegister(RCategory.Temp, RType.Object);
            var multicastDelegateType = new ClassReference(targetPackage.NameConverter.GetConvertedFullName("System.MulticastDelegate"));
            var nextReference = new FieldReference(multicastDelegateType, "next", multicastDelegateType);
            ins.Add(new Instruction(RCode.Iget_object, nextReference, new[] { next, rthis })); // load this.next
            var afterCallNext = new Instruction(RCode.Nop);
            ins.Add(new Instruction(RCode.If_eqz, afterCallNext, new[] { next })); // if next == null, continue
            ins.Add(new Instruction(RCode.Check_cast, delegateClass, new[] { next }));
            var nextInvokeMethod = new MethodReference(delegateClass, "Invoke", invokePrototype);
            var nextInvokeArgs = new[] { next }.Concat(incomingMethodArgs.Skip(1)).ToArray();
            ins.Add(new Instruction(RCode.Invoke_virtual, nextInvokeMethod, nextInvokeArgs));
            ins.Add(afterCallNext);

            // Add return instructions
            ins.Add(returnInstruction);

            return body;
        }
Exemplo n.º 8
0
 /// <summary>
 /// Create the body of the ctor.
 /// </summary>
 private static MethodBody CreateCtorBody(XMethodDefinition calledMethod, FieldDefinition instanceField, ClassReference baseClass)
 {
     var body = new MethodBody(null);
     // Create code
     var ins = body.Instructions;
     var rthis = body.AllocateRegister(RCategory.Argument, RType.Object);
     // Call base ctor
     var baseCtorRef = new MethodReference(baseClass, "<init>", new Prototype(PrimitiveType.Void));
     ins.Add(new Instruction(RCode.Invoke_direct, rthis) { Operand = baseCtorRef });
     if (!calledMethod.IsStatic)
     {
         // load instance into field
         var rvalue = body.AllocateRegister(RCategory.Argument, RType.Object);
         ins.Add(new Instruction(RCode.Iput_object, rvalue, rthis) {Operand = instanceField});
     }
     ins.Add(new Instruction(RCode.Return_void));
     return body;
 }
Exemplo n.º 9
0
        /// <summary>
        /// Create and add GenericInstance field.
        /// </summary>
        protected virtual void CreateGenericInstanceFields(DexTargetPackage targetPackage)
        {
            if (BuildGenericInstanceFieldAsArray)
            {
                var field = new FieldDefinition
                {
                    Name = CreateUniqueFieldName("$g"),
                    Type = FrameworkReferences.ClassArray,
                    AccessFlags = AccessFlags.Protected | AccessFlags.Synthetic,
                    Owner = Class
                };
                Class.Fields.Add(field);
                Class.GenericInstanceFields.Add(field);
            }
            else
            {
                for (int i = 0; i < typeDef.GenericParameters.Count; ++i)
                {
                    var field = new FieldDefinition
                    {
                        Name = CreateUniqueFieldName("$g", 1),
                        Type = FrameworkReferences.Class,
                        AccessFlags = AccessFlags.Protected | AccessFlags.Synthetic,
                        Owner = Class
                    };
                    Class.Fields.Add(field);
                    Class.GenericInstanceFields.Add(field);
                }
            }

        }
Exemplo n.º 10
0
        private static void CreateCompareArrayInstructions(InstructionList ins, MethodBody body, Register rthis, Register rother, FieldDefinition field, Register rThisValue, Register rOtherValue, Instruction returnFalseInstruction)
        {
            Instruction done = new Instruction(RCode.Nop);
            // Load the instance fields.
            ins.Add(new Instruction(RCode.Iget_object, rThisValue, rthis) {Operand = field});
            ins.Add(new Instruction(RCode.Iget_object, rOtherValue, rother) {Operand = field});

            var rThisLen = body.AllocateRegister(RCategory.Temp, RType.Value);
            var rOtherLen = body.AllocateRegister(RCategory.Temp, RType.Value);

            // load length
            ins.Add(new Instruction(RCode.Array_length, rThisLen, rThisValue));
            ins.Add(new Instruction(RCode.Array_length, rOtherLen, rOtherValue));

            // Compare the length
            ins.Add(new Instruction(RCode.If_ne, returnFalseInstruction, new[] { rThisLen, rOtherLen }));
            ins.Add(new Instruction(RCode.If_eqz, done, new[] {rThisLen}));

            // now iterate over all elements in the array.
            var thisType = body.AllocateRegister(RCategory.Temp, RType.Object);
            var otherType = body.AllocateRegister(RCategory.Temp, RType.Object);
            var counter = body.AllocateRegister(RCategory.Temp, RType.Object);
            ins.Add(new Instruction(RCode.Const, 0, new[] {counter}));

            var loadThisVal = new Instruction(RCode.Aget_object, thisType, rThisValue, counter);
            ins.Add(loadThisVal);
            ins.Add(new Instruction(RCode.Aget_object, otherType, rOtherValue, counter));

            // compare types.
            ins.Add(new Instruction(RCode.If_ne, returnFalseInstruction, new[] {thisType, otherType}));

            ins.Add(new Instruction(RCode.Add_int_lit8, 1, new[] {counter, counter}));
            ins.Add(new Instruction(RCode.If_ne, loadThisVal, new[] {counter, rThisLen}));
            
            ins.Add(done);
        }
Exemplo n.º 11
0
        public DelegateInstanceType Create()
        {
            instanceField = null; // actually at the momennt, we are not called multiple times...
            genericMethodTypeFields.Clear();
            genericInstanceTypeFields.Clear();

            // Prepare called method
            var target = targetPackage.DexFile;
            var owner = target.GetClass(calledMethod.DeclaringType.GetClassReference(targetPackage).Fullname)
                        ?? targetPackage.GetOrCreateGeneratedCodeClass();
            var calledMethodPrototype = PrototypeBuilder.BuildPrototype(compiler, targetPackage, owner, calledMethod);
            var calledMethodRef = calledMethod.GetReference(targetPackage);

            if (calledMethod.DeclaringType.HasDexImportAttribute())
            {
                // Delegate method is a Dex import method
            }
            else
            {
                // Delegate method is a .NET method
                var calledDexMethod = owner.Methods.Single(x => (x.Name == calledMethodRef.Name) && (x.Prototype.Equals(calledMethodRef.Prototype)));
                if (calledDexMethod.IsPrivate)
                {
                    calledDexMethod.IsPrivate = false;
                    calledDexMethod.IsProtected = true;
                }
            }

            var @class = new ClassDefinition
            {
                Name = CreateInstanceTypeName(owner),
                Namespace = owner.Namespace,
                AccessFlags = AccessFlags.Public | AccessFlags.Final,
                MapFileId = compiler.GetNextMapFileId(),
            };
            owner.AddInnerClass(@class);

            // Set super class
            @class.SuperClass = delegateClass;

            // Implement delegate interface
            //@class.Interfaces.Add(delegateInterface);

            // Get type of instance 
            XTypeDefinition instanceType = calledMethod.DeclaringType;
            TypeReference instanceTypeRef = instanceType.GetReference(targetPackage);

            // Add ctor
            var ctor = new MethodDefinition
            {
                Owner = @class,
                Name = "<init>",
                AccessFlags = AccessFlags.Public | AccessFlags.Constructor,
                Prototype = new Prototype(PrimitiveType.Void),
            };

            ctor.Prototype.Unfreeze();
            if (!calledMethod.IsStatic)
            {
                ctor.Prototype.Parameters.Add(new Parameter(instanceTypeRef, "this"));
            }

            PrototypeBuilder.AddGenericParameters(compiler, targetPackage, calledMethod, ctor.Prototype);
            ctor.Prototype.Freeze();
            @class.Methods.Add(ctor);

            // Add methodInfo field
            methodInfoField = new FieldDefinition();
            methodInfoField.Name = "methodInfo";
            methodInfoField.Owner = @class;
            methodInfoField.Type = compiler.GetDot42InternalType("System.Reflection", "MethodInfo").GetReference(targetPackage);
            methodInfoField.AccessFlags = AccessFlags.Private | AccessFlags.Final | AccessFlags.Static;
            @class.Fields.Add(methodInfoField);

            // Add instance field & getTargetImpl method
            if (!calledMethod.IsStatic)
            {
                instanceField = new FieldDefinition();
                instanceField.Name = "instance";
                instanceField.Owner = @class;
                instanceField.Type = instanceTypeRef;
                instanceField.AccessFlags = AccessFlags.Private | AccessFlags.Final;
                @class.Fields.Add(instanceField);

                AddMethod(@class, "GetTargetImpl", new Prototype(FrameworkReferences.Object), AccessFlags.Protected,
                          CreateGetTargetImplBody());
            }

            // Add generic instance type and method fields
            var gtpa = compiler.GetDot42InternalType(InternalConstants.GenericTypeParameterAnnotation).GetClassReference(targetPackage);
            var gmpa = compiler.GetDot42InternalType(InternalConstants.GenericMethodParameterAnnotation).GetClassReference(targetPackage);
            foreach (var parameter in ctor.Prototype.Parameters)
            {
                bool isGtpa = parameter.Annotations.Any(a => a.Type.Equals(gtpa));
                bool isGmpa = parameter.Annotations.Any(a => a.Type.Equals(gmpa));
                if (isGmpa || isGtpa)
                {
                    var list = isGtpa ? genericInstanceTypeFields : genericMethodTypeFields;
                    var field = new FieldDefinition();
                    field.Name = isGtpa ? "$git" : "$gmt";
                    if (parameter.Type.Equals(FrameworkReferences.Class))
                        field.Name += list.Count + 1;
                    field.Owner = @class;
                    field.Type = parameter.Type;
                    field.AccessFlags = AccessFlags.Private | AccessFlags.Final;
                    @class.Fields.Add(field);
                    list.Add(field);
                }
            }

            // Create ctor body
            var ctorBody = CreateCtorBody();
            targetPackage.Record(new CompiledMethod() { DexMethod = ctor, RLBody = ctorBody });

            // add class static ctor
            AddMethod(@class, "<clinit>", new Prototype(PrimitiveType.Void),
                      AccessFlags.Public | AccessFlags.Constructor | AccessFlags.Static,
                      CreateCctorBody());

            // Add Invoke method
            AddMethod(@class, "Invoke", invokePrototype, AccessFlags.Public, CreateInvokeBody(calledMethodPrototype));

            // Add Equals method
            var typeOnlyEqualsSuffices = calledMethod.IsStatic && !calledMethod.NeedsGenericInstanceTypeParameter && !calledMethod.NeedsGenericInstanceMethodParameter;
            var equalsBody = typeOnlyEqualsSuffices ? CreateEqualsCheckTypeOnlyBody(@class) : CreateEqualsBody(@class);

            var equalsPrototype = new Prototype(PrimitiveType.Boolean, new Parameter(multicastDelegateClass, "other"));
            AddMethod(@class, "EqualsWithoutInvocationList", equalsPrototype, AccessFlags.Protected, equalsBody);

            if (!typeOnlyEqualsSuffices)
            {
                var hashCodePrototype = new Prototype(PrimitiveType.Int);
                AddMethod(@class, "HashCodeWithoutInvocationList", hashCodePrototype, AccessFlags.Protected, CreateHashCodeBody(@class));
            }

            var clonePrototype = new Prototype(multicastDelegateClass, new Parameter(new ArrayType(multicastDelegateClass), "invocationList"), new Parameter(PrimitiveType.Int, "invocationListLength"));
            AddMethod(@class, "CloneWithNewInvocationList", clonePrototype, AccessFlags.Protected, 
                        CreateCloneBody(ctor, @class));

            AddMethod(@class, "GetMethodInfoImpl", new Prototype(methodInfoField.Type),AccessFlags.Protected, 
                      CreateGetMethodInfoImplBody());

            return new DelegateInstanceType(calledMethod, @class, ctor);            
        }
Exemplo n.º 12
0
 /// <summary>
 /// Create and add GenericInstance field.
 /// </summary>
 protected virtual void CreateGenericInstanceField(DexTargetPackage targetPackage)
 {
     var field = new FieldDefinition {
         Name = CreateUniqueFieldName("$g"),
         Type = FrameworkReferences.ClassArray,
         AccessFlags = AccessFlags.Protected | AccessFlags.Synthetic,
         Owner = Class
     };
     Class.Fields.Add(field);
     Class.GenericInstanceField = field;
     var annType = compiler.GetDot42InternalType(InternalConstants.GenericInstanceClassAnnotation).GetClassReference(targetPackage);
     var annotation = new Annotation(annType, AnnotationVisibility.Runtime,
         new AnnotationArgument(InternalConstants.GenericInstanceClassArgumentsField, field));
     Class.Annotations.Add(annotation);
 }
Exemplo n.º 13
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public DexFieldDefinitionNode(FieldDefinition fieldDef)
 {
     this.fieldDef = fieldDef;
     Text = fieldDef.Name;
     ImageIndex = 4;
 }
Exemplo n.º 14
0
        /// <summary>
        /// Implement the class now that all classes have been created
        /// </summary>
        protected override void CreateMembers(DexTargetPackage targetPackage)
        {
            // Build ctors
            foreach (var baseCtor in GetBaseClassCtors())
            {
                // Build ctor
                var prototype = PrototypeBuilder.BuildPrototype(Compiler, targetPackage, null, baseCtor);
                var ctor = new MethodDefinition(Class, "<init>", prototype);
                ctor.AccessFlags = AccessFlags.Public | AccessFlags.Constructor;
                Class.Methods.Add(ctor);
                // Create ctor body
                var ctorBody = CreateCtorBody(prototype);
                targetPackage.Record(new CompiledMethod { DexMethod = ctor, RLBody = ctorBody });                
            }

            // build original type field
            // Create field definition
            var dfield = new Dot42.DexLib.FieldDefinition();

            dfield.Owner = Class;
            dfield.Name = "underlying$";
            dfield.IsSynthetic = true;
            dfield.IsFinal = true;
            dfield.IsStatic= true;
            dfield.IsPublic = true;

            dfield.Type = Compiler.Module.TypeSystem.Type.GetClassReference(targetPackage);

            // not sure if GetClassReference is the best way to go forward here.
            // might depend on the sort order of the class builders.
            var underlyingType = XBuilder.AsTypeReference(Compiler.Module, Type);
            dfield.Value = underlyingType.GetClassReference(targetPackage);

            Class.Fields.Add(dfield);

        }