public virtual void Dup() { if (mv != null) { mv.Dup(); } }
protected MethodInstance ImplementUsePropertyChangeSupport(PropertyInstance p_propertyChangeTemplate, FieldInstance f_propertyChangeSupport) { MethodInstance m_getPropertyChangeSupport = MethodInstance.FindByTemplate(template_m_usePropertyChangeSupport, true); if (m_getPropertyChangeSupport == null) { // create field that holds propertyChangeSupport f_propertyChangeSupport = ImplementField(f_propertyChangeSupport); IMethodVisitor mg = VisitMethod(template_m_usePropertyChangeSupport); HideFromDebug(mg.Method); Label l_pcsValid = mg.NewLabel(); mg.GetThisField(f_propertyChangeSupport); mg.Dup(); mg.IfNonNull(l_pcsValid); mg.Pop(); // remove 2nd null instance from stack caused by previous dup mg.PutThisField(f_propertyChangeSupport, delegate(IMethodVisitor mg2) { mg.CallThisGetter(p_propertyChangeTemplate); mg.LoadThis(); mg.InvokeVirtual(m_newPropertyChangeSupport); }); mg.GetThisField(f_propertyChangeSupport); mg.Mark(l_pcsValid); mg.ReturnValue(); // return instance already on the stack by both branches mg.EndMethod(); m_getPropertyChangeSupport = mg.Method; } return(m_getPropertyChangeSupport); }
protected void ImplementGetPrimitives(Member[] primitiveMembers, FieldInstance[] f_primitives, FieldInstance[] f_nullFlags) { MethodInstance template_m_getPrimitives = new MethodInstance(null, typeof(RootCacheValue), typeof(Object[]), "GetPrimitives"); IMethodVisitor mv = VisitMethod(template_m_getPrimitives); mv.Push(f_primitives.Length); mv.NewArray(objType); for (int primitiveIndex = 0, size = f_primitives.Length; primitiveIndex < size; primitiveIndex++) { FieldInstance f_primitive = f_primitives[primitiveIndex]; FieldInstance f_nullFlag = f_nullFlags[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); } // duplicate array instance on stack mv.Dup(); mv.Push(primitiveIndex); mv.GetThisField(f_primitive); mv.ValueOf(f_primitive.Type.Type); mv.ArrayStore(objType); if (f_nullFlag != null) { mv.Mark(l_fieldIsNull.Value); } } mv.ReturnValue(); mv.EndMethod(); }
protected void ImplementGetRelations(RelationMember[] relationMembers, FieldInstance[] f_relations) { MethodInstance template_m_getRelations = new MethodInstance(null, typeof(RootCacheValue), typeof(IObjRef[][]), "GetRelations"); IMethodVisitor mv = VisitMethod(template_m_getRelations); mv.Push(f_relations.Length); mv.NewArray(objRefArrayType); for (int relationIndex = 0, size = f_relations.Length; relationIndex < size; relationIndex++) { FieldInstance f_primitive = f_relations[relationIndex]; // duplicate array instance on stack mv.Dup(); mv.Push(relationIndex); mv.GetThisField(f_primitive); mv.ArrayStore(objRefArrayType); } mv.ReturnValue(); mv.EndMethod(); }
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(); }