예제 #1
0
        protected void ImplementSetValue(IPropertyInfo[] propertyPath)
        {
            IMethodVisitor mv = VisitMethod(template_m_setValue);

            IPropertyInfo lastProperty = propertyPath[propertyPath.Length - 1];

            if (lastProperty is MethodPropertyInfo && ((MethodPropertyInfo)lastProperty).Setter == null)
            {
                throw new Exception("Property not writable: " + lastProperty.EntityType.FullName + "." + lastProperty.Name);
            }
            mv.LoadArg(0);
            Type typeOfArgumentOnStack = typeof(Object);

            for (int a = 0, size = propertyPath.Length - 1; a < size; a++)
            {
                typeOfArgumentOnStack = InvokeGetProperty(mv, propertyPath[a], typeOfArgumentOnStack);
            }
            if (!lastProperty.DeclaringType.Equals(typeOfArgumentOnStack))
            {
                mv.CheckCast(lastProperty.DeclaringType);
            }
            mv.LoadArg(1);
            Type lastPropertyType = lastProperty.PropertyType;

            if (lastProperty.PropertyType.IsPrimitive)
            {
                Type  pType            = lastProperty.PropertyType;
                Label l_valueIsNonNull = mv.NewLabel();
                Label l_valueIsValid   = mv.NewLabel();

                mv.IfNonNull(l_valueIsNonNull);
                mv.PushNullOrZero(pType);
                mv.GoTo(l_valueIsValid);

                mv.Mark(l_valueIsNonNull);
                mv.LoadArg(1);
                mv.Unbox(pType);
                mv.Mark(l_valueIsValid);
            }
            else
            {
                mv.CheckCast(lastPropertyType);
            }
            InvokeSetProperty(mv, lastProperty);
            mv.ReturnValue();

            mv.EndMethod();
        }
예제 #2
0
 public virtual void LoadArg(int argIndex)
 {
     if (mv != null)
     {
         mv.LoadArg(argIndex);
     }
 }
예제 #3
0
        protected void ImplementNotifyPropertyChanged(PropertyInstance p_propertyChangeTemplate, MethodInstance m_getPropertyChangeSupport)
        {
            // implement IPropertyChanged
            foreach (MethodInfo rMethod in typeof(INotifyPropertyChanged).GetMethods())
            {
                MethodInstance existingMethod = MethodInstance.FindByTemplate(rMethod, true);
                if (existingMethod != null)
                {
                    continue;
                }
                MethodInstance method = new MethodInstance(rMethod);

                IMethodVisitor mg = VisitMethod(method);
                mg.CallThisGetter(p_propertyChangeTemplate);
                // this.propertyChangeSupport
                mg.CallThisGetter(m_getPropertyChangeSupport);
                // listener
                mg.LoadArg(0);
                if ("add_PropertyChanged".Equals(method.Name))
                {
                    // addPropertyChangeListener(propertyChangeSupport, listener)
                    mg.InvokeVirtual(m_addPropertyChangeListener);
                }
                else
                {
                    // removePropertyChangeListener(propertyChangeSupport, listener)
                    mg.InvokeVirtual(m_removePropertyChangeListener);
                }
                mg.ReturnValue();
                mg.EndMethod();
            }
        }
예제 #4
0
        protected void ImplementSetRelation(RelationMember[] relationMembers, FieldInstance[] f_relations)
        {
            MethodInstance template_m_setRelation = new MethodInstance(null, typeof(RootCacheValue), typeof(void), "SetRelation", typeof(int), typeof(IObjRef[]));

            IMethodVisitor mv       = VisitMethod(template_m_setRelation);
            Label          l_finish = mv.NewLabel();

            for (int relationIndex = 0, size = f_relations.Length; relationIndex < size; relationIndex++)
            {
                FieldInstance f_relation = f_relations[relationIndex];

                Label l_notEqual = mv.NewLabel();

                mv.LoadArg(0);
                mv.Push(relationIndex);

                mv.IfCmp(typeof(int), CompareOperator.NE, l_notEqual);

                mv.PutThisField(f_relation, delegate(IMethodVisitor mg)
                {
                    mg.LoadArg(1);
                });
                mv.GoTo(l_finish);
                mv.Mark(l_notEqual);
            }
            mv.ThrowException(typeof(ArgumentException), "Given relationIndex not known");
            mv.Mark(l_finish);
            mv.ReturnValue();
            mv.EndMethod();
        }
예제 #5
0
        protected void ImplementGetRelation(RelationMember[] relationMembers, FieldInstance[] f_relations)
        {
            MethodInstance template_m_getRelation = new MethodInstance(null, typeof(RootCacheValue), typeof(IObjRef[]), "GetRelation", typeof(int));

            IMethodVisitor mv = VisitMethod(template_m_getRelation);

            if (f_relations.Length > 0)
            {
                Label   l_default   = mv.NewLabel();
                Label[] l_relations = new Label[f_relations.Length];
                for (int relationIndex = 0, size = l_relations.Length; relationIndex < size; relationIndex++)
                {
                    l_relations[relationIndex] = mv.NewLabel();
                }

                mv.LoadArg(0);
                mv.Switch(0, l_relations.Length - 1, l_default, l_relations);

                for (int relationIndex = 0, size = f_relations.Length; relationIndex < size; relationIndex++)
                {
                    FieldInstance f_relation = f_relations[relationIndex];

                    mv.Mark(l_relations[relationIndex]);
                    mv.GetThisField(f_relation);
                    mv.ReturnValue();
                }
                mv.Mark(l_default);
            }
            mv.ThrowException(typeof(ArgumentException), "Given relationIndex not known");
            mv.PushNull();
            mv.ReturnValue();
            mv.EndMethod();
        }
예제 #6
0
        public override void VisitEnd()
        {
            Type entityType = metaData.EntityType;
            {
                IMethodVisitor mv = VisitMethod(template_m_getEntityType);
                mv.Push(entityType);
                mv.ReturnValue();
                mv.EndMethod();
            }

            {
                IMethodVisitor mv = VisitMethod(template_m_getIdIndex);
                mv.Push(idIndex);
                mv.ReturnValue();
                mv.EndMethod();
            }

            FieldInstance f_id = ImplementNativeField(this, metaData.GetIdMemberByIdIndex(idIndex), template_m_getId, template_m_setId);

            if (f_id.Type.Type.IsPrimitive)
            {
                // id is a primitive type. So we use an improved version of the 3-tuple equals without boxing the id
                IMethodVisitor mv         = VisitMethod(template_m_isEqualTo);
                Label          l_notEqual = mv.NewLabel();

                mv.Push(entityType);
                mv.LoadArg(0);
                mv.IfCmp(typeof(Type), CompareOperator.NE, l_notEqual);

                mv.Push(idIndex);
                mv.LoadArg(1);
                mv.IfCmp(typeof(bool), CompareOperator.NE, l_notEqual);

                mv.GetThisField(f_id);
                mv.LoadArg(2);
                mv.Unbox(f_id.Type.Type);
                mv.IfCmp(f_id.Type.Type, CompareOperator.NE, l_notEqual);

                mv.Push(true);
                mv.ReturnValue();
                mv.Mark(l_notEqual);
                mv.Push(false);
                mv.ReturnValue();
                mv.EndMethod();
            }
            base.VisitEnd();
        }
예제 #7
0
        protected void ImplementGetPrimitive(Member[] primitiveMember, FieldInstance[] f_primitives, FieldInstance[] f_nullFlags)
        {
            MethodInstance template_m_getPrimitive = new MethodInstance(null, typeof(RootCacheValue), typeof(Object), "GetPrimitive", typeof(int));

            IMethodVisitor mv = VisitMethod(template_m_getPrimitive);

            if (f_primitives.Length > 0)
            {
                Label   l_default    = mv.NewLabel();
                Label[] l_primitives = new Label[f_primitives.Length];
                for (int primitiveIndex = 0, size = f_primitives.Length; primitiveIndex < size; primitiveIndex++)
                {
                    l_primitives[primitiveIndex] = mv.NewLabel();
                }

                mv.LoadArg(0);
                mv.Switch(0, l_primitives.Length - 1, l_default, l_primitives);

                for (int primitiveIndex = 0, size = f_primitives.Length; primitiveIndex < size; primitiveIndex++)
                {
                    FieldInstance f_primitive = f_primitives[primitiveIndex];
                    FieldInstance f_nullFlag  = f_nullFlags[primitiveIndex];

                    mv.Mark(l_primitives[primitiveIndex]);

                    Label?l_fieldIsNull = null;

                    if (f_nullFlag != null)
                    {
                        l_fieldIsNull = mv.NewLabel();
                        // only do something if the field is non-null
                        mv.GetThisField(f_nullFlag);
                        mv.IfZCmp(CompareOperator.NE, l_fieldIsNull.Value);
                    }
                    mv.GetThisField(f_primitive);
                    mv.ValueOf(f_primitive.Type.Type);
                    mv.ReturnValue();

                    if (f_nullFlag != null)
                    {
                        mv.Mark(l_fieldIsNull.Value);
                        mv.PushNull();
                    }
                    mv.ReturnValue();
                }
                mv.Mark(l_default);
            }
            mv.ThrowException(typeof(ArgumentException), "Given relationIndex not known");
            mv.PushNull();
            mv.ReturnValue();
            mv.EndMethod();
        }
예제 #8
0
        protected void ImplementConstructor(MethodInstance template_m_setPrimitivePropertyPrivilege, MethodInstance template_m_setRelationPropertyPrivilege)
        {
            IBytecodeBehaviorState state       = State;
            ConstructorInfo        constructor = state.CurrentType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool),
                                                                                                                                                                           typeof(IPropertyPrivilege[]), typeof(IPropertyPrivilege[]) }, null);
            ConstructorInstance c_method = new ConstructorInstance(constructor);

            IMethodVisitor mg = VisitMethod(c_method);

            mg.LoadThis();
            mg.LoadArgs();
            mg.InvokeConstructor(c_method);

            Type propertyPrivilegeType = typeof(IPropertyPrivilege);

            for (int primitiveIndex = 0, size = metaData.PrimitiveMembers.Length; primitiveIndex < size; primitiveIndex++)
            {
                mg.LoadThis();
                mg.Push(primitiveIndex);
                mg.LoadArg(5);
                mg.Push(primitiveIndex);
                mg.ArrayLoad(propertyPrivilegeType);
                mg.InvokeVirtual(template_m_setPrimitivePropertyPrivilege);
            }
            for (int relationIndex = 0, size = metaData.RelationMembers.Length; relationIndex < size; relationIndex++)
            {
                mg.LoadThis();
                mg.Push(relationIndex);
                mg.LoadArg(6);
                mg.Push(relationIndex);
                mg.ArrayLoad(propertyPrivilegeType);
                mg.InvokeVirtual(template_m_setRelationPropertyPrivilege);
            }

            mg.ReturnValue();
            mg.EndMethod();
        }
예제 #9
0
        protected void ImplementGetAttribute(IPropertyInfo[] property)
        {
            HashMap <Type, Attribute> typeToAttributeMap = new HashMap <Type, Attribute>();

            Attribute[] annotations = property[property.Length - 1].GetAnnotations();
            foreach (Attribute annotation in annotations)
            {
                typeToAttributeMap.Put(annotation.GetType(), annotation);
            }
            FieldInstance  f_typeToAttributeMap = ImplementStaticAssignedField("sf__typeToAttributeMap", typeToAttributeMap);
            IMethodVisitor mv = VisitMethod(template_m_getAttribute);

            mv.GetThisField(f_typeToAttributeMap);
            mv.LoadArg(0);
            mv.InvokeVirtual(new MethodInstance(null, typeof(HashMap <Type, Attribute>), typeof(Attribute), "Get", typeof(Type)));
            //		mv.CheckCast(typeof(Attribute));
            mv.ReturnValue();
            mv.EndMethod();
        }
예제 #10
0
        protected void ImplementEmbeddedConstructor(FieldInstance f_parentObject, ConstructorInstance superConstructor)
        {
            if (superConstructor.Parameters.Length > 0 && superConstructor.Parameters[0].Equals(f_parentObject.Type))
            {
                // super constructor already enhanced
                return;
            }
            bool baseIsEnhanced = false;//EntityEnhancer.IsEnhancedType(vs.CurrentType);

            NewType[] parameters = superConstructor.Parameters;
            NewType[] types;
            if (baseIsEnhanced)
            {
                // Only Pass-through constructors necessary. So signature remains the same
                types = null;//TypeUtil.GetClassesToTypes(..GetTypes(parameters);
            }
            else
            {
                types = new NewType[parameters.Length + 1];
                for (int a = parameters.Length + 1; a-- > 1;)
                {
                    types[a] = parameters[a - 1];
                }
                types[0] = f_parentObject.Type;
            }
            IMethodVisitor mv = VisitMethod(new ConstructorInstance(MethodAttributes.Public, types));

            mv.LoadThis();
            for (int a = 1, size = types.Length; a < size; a++)
            {
                mv.LoadArg(a); // Load constructor argument one by one, starting with the 2nd constructor argument
            }
            mv.InvokeConstructor(superConstructor);
            mv.PutThisField(f_parentObject, delegate(IMethodVisitor mv2)
            {
                mv2.LoadArg(0);
            });
            mv.ReturnValue();
            mv.EndMethod();
        }
예제 #11
0
        public MethodInstance ImplementSwitchByIndex(MethodInstance method, String exceptionMessageOnIllegalIndex, int indexSize, ScriptWithIndex script)
        {
            IMethodVisitor mv = VisitMethod(method);

            if (indexSize == 0)
            {
                mv.ThrowException(typeof(ArgumentException), exceptionMessageOnIllegalIndex);
                mv.PushNull();
                mv.ReturnValue();
                mv.EndMethod();
                return(mv.Method);
            }

            Label l_default = mv.NewLabel();

            Label[] l_fields = new Label[indexSize];
            for (int index = 0, size = indexSize; index < size; index++)
            {
                l_fields[index] = mv.NewLabel();
            }

            mv.LoadArg(0);
            mv.VisitTableSwitchInsn(0, l_fields.Length - 1, l_default, l_fields);

            for (int index = 0, size = l_fields.Length; index < size; index++)
            {
                mv.Mark(l_fields[index]);

                script(mv, index);
            }
            mv.Mark(l_default);

            mv.ThrowException(typeof(ArgumentException), "Given relationIndex not known");
            mv.PushNull();
            mv.ReturnValue();
            mv.EndMethod();
            return(mv.Method);
        }
예제 #12
0
        protected PropertyInstance ImplementNotifyPropertyChangedSource(PropertyInstance p_propertyChangeTemplate,
                                                                        FieldInstance f_propertyChangeSupport)
        {
            MethodInstance m_onPropertyChanged_Values = MethodInstance.FindByTemplate(template_m_onPropertyChanged_Values, true);

            if (m_onPropertyChanged_Values == null)
            {
                IMethodVisitor mv = VisitMethod(template_m_onPropertyChanged_Values);
                mv.CallThisGetter(p_propertyChangeTemplate);
                mv.LoadThis();
                mv.GetThisField(f_propertyChangeSupport);

                // getMethodHandle(sender, propertyName)
                mv.CallThisGetter(p_propertyChangeTemplate);
                mv.LoadThis();
                mv.LoadArg(0);
                mv.InvokeVirtual(m_getMethodHandle);

                mv.LoadArg(1);
                mv.LoadArg(2);
                // firePropertyChange(sender, propertyChangeSupport, property, oldValue, newValue)
                mv.InvokeVirtual(m_firePropertyChange);
                mv.PopIfReturnValue(m_firePropertyChange);
                mv.ReturnVoidOrThis();
                mv.EndMethod();
                m_onPropertyChanged_Values = mv.Method;
            }
            MethodInstance m_onPropertyChanged = MethodInstance.FindByTemplate(template_m_onPropertyChanged, true);

            if (m_onPropertyChanged == null)
            {
                IMethodVisitor mv = VisitMethod(template_m_onPropertyChanged);
                mv.LoadThis();
                mv.LoadArg(0);
                mv.PushNull();
                mv.PushNull();
                mv.InvokeVirtual(m_onPropertyChanged_Values);
                mv.PopIfReturnValue(m_onPropertyChanged_Values);
                mv.ReturnVoidOrThis();
                mv.EndMethod();
                m_onPropertyChanged = mv.Method;
            }
            PropertyInstance p_pceHandlers = PropertyInstance.FindByTemplate(p_propertyChangeSupport, true);

            if (p_pceHandlers == null)
            {
                HideFromDebug(ImplementGetter(p_propertyChangeSupport.Getter, f_propertyChangeSupport));
                p_pceHandlers = PropertyInstance.FindByTemplate(p_propertyChangeSupport, false);
            }
            if (EmbeddedEnhancementHint.HasMemberPath(State.Context))
            {
                PropertyInstance p_parentEntity = EmbeddedTypeVisitor.GetParentObjectProperty(this);
                if (MethodInstance.FindByTemplate(p_parentChildEventHandler.Getter, true) == null)
                {
                    IMethodVisitor mv = VisitMethod(p_parentChildEventHandler.Getter);
                    mv.CallThisGetter(p_parentEntity);
                    mv.InvokeInterface(p_parentChildEventHandler.Getter);
                    mv.ReturnValue();
                    mv.EndMethod();
                    HideFromDebug(mv.Method);
                }
                if (MethodInstance.FindByTemplate(p_collectionEventHandler.Getter, true) == null)
                {
                    IMethodVisitor mv = VisitMethod(p_collectionEventHandler.Getter);
                    mv.CallThisGetter(p_parentEntity);
                    mv.InvokeInterface(p_collectionEventHandler.Getter);
                    mv.ReturnValue();
                    mv.EndMethod();
                    HideFromDebug(mv.Method);
                }
            }
            else
            {
                if (MethodInstance.FindByTemplate(p_parentChildEventHandler.Getter, true) == null)
                {
                    HideFromDebug(ImplementLazyInitProperty(p_parentChildEventHandler, delegate(IMethodVisitor mv)
                    {
                        MethodInstance method = new MethodInstance(null, typeof(NotifyPropertyChangedClassVisitor), typeof(PropertyChangedEventHandler), "CreateParentChildEventHandler", typeof(Object));
                        mv.LoadThis();
                        mv.InvokeStatic(method);
                    }));
                }
                if (MethodInstance.FindByTemplate(p_collectionEventHandler.Getter, true) == null)
                {
                    HideFromDebug(ImplementLazyInitProperty(p_collectionEventHandler, delegate(IMethodVisitor mv)
                    {
                        MethodInstance method = new MethodInstance(null, typeof(NotifyPropertyChangedClassVisitor), typeof(NotifyCollectionChangedEventHandler), "CreateCollectionEventHandler", typeof(Object));
                        mv.LoadThis();
                        mv.InvokeStatic(method);
                    }));
                }
            }

            //MethodAttributes ma = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
            //{
            //    ConstructorInfo pceaCI = typeof(PropertyChangedEventArgs).GetConstructor(new Type[] { typeof(String) });

            //    MethodBuilder mb = VisitorUtil.DefineMethod(vs, onPropertyChangedMI_string, ma);
            //    ILGenerator gen = mb.GetILGenerator();
            //    gen.Emit(OpCodes.Ldarg_0);
            //    gen.Emit(OpCodes.Ldarg_1);
            //    gen.Emit(OpCodes.Newobj, pceaCI);
            //    gen.Emit(OpCodes.Call, onPropertyChangedMI_pceArg);
            //    gen.Emit(OpCodes.Ret);
            //}
            //{
            //    MethodBuilder mb = VisitorUtil.DefineMethod(vs, onPropertyChangedMI_pceArg, ma);
            //    ILGenerator gen = mb.GetILGenerator();
            //    gen.Emit(OpCodes.Ldarg_0);
            //    gen.Emit(OpCodes.Call, pctPI.GetGetMethod());
            //    gen.Emit(OpCodes.Ldarg_0);
            //    gen.Emit(OpCodes.Ldarg_1);
            //    gen.Emit(OpCodes.Call, FirePropertyChangedMI);
            //    gen.Emit(OpCodes.Ret);
            //}
            //    List<PropertyChangedEventHandler> PropertyChangedEventHandlers { get; }

            //void OnPropertyChanged(String propertyName);

            //void OnPropertyChanged(PropertyChangedEventArgs args);
            return(p_pceHandlers);
        }
예제 #13
0
        protected void ImplementPropertyChangeOnProperty(PropertyInstance propertyInfo,
                                                         PropertyInstance p_propertyChangeTemplate, MethodInstance m_firePropertyChange, FieldInstance f_propertyChangeSupport)
        {
            // add property change detection and notification
            if (propertyInfo.Getter == null || propertyInfo.Setter == null)
            {
                return;
            }
            if (InitializeEmbeddedMemberVisitor.IsEmbeddedMember(metaData, propertyInfo.Name))
            {
                return;
            }
            PropertyInstance p_getterMethodHandle = ImplementAssignedReadonlyProperty(propertyInfo.Name + "$MethodHandle",
                                                                                      new MethodHandleValueResolver(PropertyInfoProvider, propertyInfo.Name));
            Type           propertyType         = propertyInfo.PropertyType.Type;
            MethodInstance m_hasPropertyChanged = GetApplicableHasPropertyChangedOverload(propertyType);

            // check value type of last parameter
            bool isBoxingNeededForHasPropertyChanged = IsBoxingNeededForHasPropertyChangedOverload(m_hasPropertyChanged, propertyType);

            IMethodVisitor    mg              = VisitMethod(propertyInfo.Setter);
            Label             l_finish        = mg.NewLabel();
            Label             l_noOldValue    = mg.NewLabel();
            Label             l_noChangeCheck = mg.NewLabel();
            LocalVariableInfo loc_oldValue;

            if (isBoxingNeededForHasPropertyChanged)
            {
                loc_oldValue = mg.NewLocal(typeof(Object));
            }
            else
            {
                loc_oldValue = mg.NewLocal(propertyType);
            }
            LocalVariableInfo loc_valueChanged = mg.NewLocal <bool>();

            MethodInstance m_getSuper       = EnhancerUtil.GetSuperGetter(propertyInfo);
            bool           relationProperty = m_getSuper.Name.EndsWith(ValueHolderIEC.GetNoInitSuffix());

            // initialize flag with false
            mg.Push(false);
            mg.StoreLocal(loc_valueChanged);

            // initialize oldValue with null
            mg.PushNullOrZero(loc_oldValue.LocalType);
            mg.StoreLocal(loc_oldValue);

            if (relationProperty)
            {
                // check if a setter call to an UNINITIALIZED relation occured with value null
                // if it the case there would be no PCE because oldValue & newValue are both null
                // but we need a PCE in this special case
                Label         l_noSpecialHandling = mg.NewLabel();
                FieldInstance f_state             = State.GetAlreadyImplementedField(ValueHolderIEC.GetInitializedFieldName(propertyInfo.Name));
                mg.GetThisField(f_state);
                mg.PushEnum(ValueHolderState.INIT);
                mg.IfCmp(typeof(ValueHolderState), CompareOperator.EQ, l_noSpecialHandling);
                mg.Push(true);
                mg.StoreLocal(loc_valueChanged);
                mg.Mark(l_noSpecialHandling);
            }

            // check if value should be checked to decide for a PCE
            mg.LoadLocal(loc_valueChanged);
            mg.IfZCmp(CompareOperator.NE, l_noOldValue);

            // get old field value calling super property getter
            mg.LoadThis();
            mg.InvokeOnExactOwner(m_getSuper);
            if (isBoxingNeededForHasPropertyChanged)
            {
                mg.Box(propertyType);
            }
            mg.StoreLocal(loc_oldValue);

            mg.Mark(l_noOldValue);

            // set new field value calling super property setter
            mg.LoadThis();
            mg.LoadArg(0);
            mg.InvokeOnExactOwner(EnhancerUtil.GetSuperSetter(propertyInfo));
            mg.PopIfReturnValue(EnhancerUtil.GetSuperSetter(propertyInfo));

            // check if value should be checked to decide for a PCE
            mg.LoadLocal(loc_valueChanged);
            mg.IfZCmp(CompareOperator.NE, l_noChangeCheck);

            LocalVariableInfo loc_newValue = null;

            if (isBoxingNeededForHasPropertyChanged)
            {
                loc_newValue = mg.NewLocal(typeof(Object)); // loc_1  Object newValue
                // Object loc_1 = (Object)value;
                mg.LoadArg(0);
                mg.Box(propertyType);
                mg.StoreLocal(loc_newValue);
            }
            mg.CallThisGetter(p_propertyChangeTemplate);
            // call HasPropertyChanged (static)
            mg.LoadThis();              // "this" as Object obj
            mg.Push(propertyInfo.Name); // String propertyName
            mg.LoadLocal(loc_oldValue);
            if (loc_newValue != null)
            {
                mg.LoadLocal(loc_newValue);
            }
            else
            {
                mg.LoadArg(0);
            }
            mg.InvokeVirtual(m_hasPropertyChanged);
            //// if (!result)
            //// { return; }
            mg.IfZCmp(CompareOperator.EQ, l_finish);

            mg.Mark(l_noChangeCheck);
            // call firePropertyChange on this
            mg.LoadThis();
            // propertyChangeSupport
            mg.GetThisField(f_propertyChangeSupport);
            // property
            mg.CallThisGetter(p_getterMethodHandle);
            // oldValue
            mg.LoadLocal(loc_oldValue);
            if (!isBoxingNeededForHasPropertyChanged && propertyType.IsValueType)
            {
                // old value has not already been boxed but it is now necessary
                mg.ValueOf(propertyType);
            }
            // newValue
            if (loc_newValue != null)
            {
                mg.LoadLocal(loc_newValue);
            }
            else
            {
                mg.LoadArg(0);
                if (propertyType.IsValueType)
                {
                    mg.ValueOf(propertyType);
                }
            }
            // firePropertyChange(propertyChangeSupport, property, oldValue, newValue)
            mg.InvokeVirtual(m_firePropertyChange);

            // return
            mg.Mark(l_finish);
            mg.ReturnVoidOrThis();
            mg.EndMethod();
        }
예제 #14
0
        protected void ImplementGetValueIntern(MethodInstance template_m_getValue, IPropertyInfo[] propertyPath)
        {
            IMethodVisitor mv = VisitMethod(template_m_getValue);

            Type  declaringType = propertyPath[0].EntityType;
            Label l_finish      = mv.NewLabel();

            mv.LoadArg(0);
            Type typeOfArgumentOnStack = typeof(Object);

            for (int a = 0, size = propertyPath.Length - 1; a < size; a++)
            {
                typeOfArgumentOnStack = InvokeGetProperty(mv, propertyPath[a], typeOfArgumentOnStack);
                mv.Dup();
                mv.IfNull(l_finish);
            }
            IPropertyInfo lastProperty = propertyPath[propertyPath.Length - 1];

            typeOfArgumentOnStack = InvokeGetProperty(mv, lastProperty, typeOfArgumentOnStack);
            if (lastProperty.PropertyType.IsPrimitive)
            {
                Type pType = lastProperty.PropertyType;
                LocalVariableInfo loc_value = mv.NewLocal(pType);
                mv.StoreLocal(loc_value);
                mv.LoadLocal(loc_value);
                Label l_valueIsNonZero = mv.NewLabel();

                mv.IfZCmp(pType, CompareOperator.NE, l_valueIsNonZero);

                if (mv.Method.Parameters.Length == 2)
                {
                    Label l_nullAllowed = mv.NewLabel();
                    // check null-equi flag
                    mv.LoadArg(1);
                    mv.IfZCmp(CompareOperator.EQ, l_nullAllowed);
                    mv.PushNullOrZero(pType);
                    if (!mv.Method.ReturnType.Type.IsValueType)
                    {
                        mv.ValueOf(pType);
                    }
                    mv.ReturnValue();

                    mv.Mark(l_nullAllowed);
                }
                mv.PushNullOrZero(mv.Method.ReturnType);
                mv.ReturnValue();

                mv.Mark(l_valueIsNonZero);
                mv.LoadLocal(loc_value);
                mv.ValueOf(pType);
            }
            else if (lastProperty.PropertyType.IsValueType)
            {
                Type pType = lastProperty.PropertyType;

                MethodInfo m_hasValue = pType.GetMethod("get_HasValue");
                if (m_hasValue != null)
                {
                    LocalVariableInfo loc_value = mv.NewLocal(pType);
                    mv.StoreLocal(loc_value);
                    mv.LoadLocal(loc_value);

                    MethodInfo        m_getValue    = pType.GetMethod("get_Value");
                    LocalVariableInfo loc_realValue = mv.NewLocal(m_getValue.ReturnType);
                    Label             l_hasNoValue  = mv.NewLabel();

                    mv.InvokeOnExactOwner(m_hasValue);
                    mv.IfZCmp(CompareOperator.EQ, l_hasNoValue);
                    mv.LoadLocal(loc_value);
                    mv.InvokeOnExactOwner(m_getValue);
                    mv.StoreLocal(loc_realValue);
                    mv.LoadLocal(loc_realValue);
                    mv.IfZCmp(CompareOperator.EQ, l_hasNoValue);
                    mv.LoadLocal(loc_realValue);
                    if (!mv.Method.ReturnType.Type.IsValueType)
                    {
                        mv.ValueOf(m_getValue.ReturnType);
                    }
                    mv.ReturnValue();

                    mv.Mark(l_hasNoValue);

                    if (mv.Method.Parameters.Length == 2)
                    {
                        Label l_nullEquivalentValueAllowed = mv.NewLabel();
                        // check null-equi flag
                        mv.LoadArg(1);
                        mv.IfZCmp(CompareOperator.NE, l_nullEquivalentValueAllowed);
                        mv.PushNull();
                        mv.ReturnValue();

                        mv.Mark(l_nullEquivalentValueAllowed);
                    }
                    mv.PushNullOrZero(m_getValue.ReturnType);
                    if (!mv.Method.ReturnType.Type.IsValueType)
                    {
                        mv.ValueOf(m_getValue.ReturnType);
                    }
                }
                else
                {
                    mv.Box(pType);
                }
            }
            mv.Mark(l_finish);
            mv.ReturnValue();
            mv.EndMethod();
        }