public bool Match(StructureField fa, StructureField fb) { this.fa = fa; this.fb = fb; this.fNestedStruct = null; this.fOther = null; this.NextFieldA = null; this.NextFieldB = null; var strFa = fa.DataType.TypeReferenceAs <StructureType>(); var strFb = fb.DataType.TypeReferenceAs <StructureType>(); // only one field should be nested structure if ( (strFa == null && strFb == null) || (strFa != null && strFb != null)) { return(false); } // check which of two fields is nested structure and store it // and other field in corresponding variables. int strSize; if (strFa != null) { fNestedStruct = fa; fOther = fb; strSize = strFa.GetInferredSize(); } else { fNestedStruct = fb; fOther = fa; strSize = strFb.GetInferredSize(); } // check if other field is inside nested structure return( fOther.Offset >= fNestedStruct.Offset && fOther.Offset < fNestedStruct.Offset + strSize); }
public int Compare(StructureType x, StructureType y, int count) { int d; if (x.Size > 0 && y.Size > 0) { d = x.Size - y.Size; if (d != 0) { return(d); } } d = x.Fields.Count - y.Fields.Count; if (d != 0) { return(d); } ++count; IEnumerator <StructureField> ex = x.Fields.GetEnumerator(); IEnumerator <StructureField> ey = y.Fields.GetEnumerator(); while (ex.MoveNext()) { ey.MoveNext(); StructureField fx = ex.Current; StructureField fy = ey.Current; d = fx.Offset - fy.Offset; if (d != 0) { return(d); } d = Compare(fx.DataType, fy.DataType, count); if (d != 0) { return(d); } } return(0); }
/// <summary> /// Unifies two structures by merging the fields in offset order. /// </summary> /// <remarks> /// Fields are taken from /// </remarks> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public DataType UnifyStructures(StructureType a, StructureType b) { int newSize = 0; if (a.Size != 0 && b.Size != 0) { if (a.Size != b.Size) { return(MakeUnion(a, b)); } else { newSize = a.Size; } } else if (a.Size != 0) { newSize = a.Size; } else if (b.Size != 0) { newSize = b.Size; } string name = null; if (a.Name != null) { if (b.Name != null && a.Name != b.Name) { throw new NotSupportedException("Both structures have names! Woo! Return null and make union of it?"); } else { name = a.Name; } } else { name = b.Name; } StructureType mem = factory.CreateStructureType(name, newSize); mem.IsSegment = (a.IsSegment || b.IsSegment); IEnumerator <StructureField> ea = a.Fields.GetEnumerator(); IEnumerator <StructureField> eb = b.Fields.GetEnumerator(); StructureField fa = null; StructureField fb = null; for (;;) { if (fa == null && ea.MoveNext()) { fa = ea.Current; } if (fb == null && eb.MoveNext()) { fb = eb.Current; } if (fa == null || fb == null) { break; } if (fa.Offset < fb.Offset) { mem.Fields.Add(fa.Clone()); fa = null; } else if (fa.Offset > fb.Offset) { mem.Fields.Add(fb.Clone()); fb = null; } else { var fieldType = Unify(fa.DataType, fb.DataType); string fieldName; if (!TryMakeFieldName(fa, fb, out fieldName)) { throw new NotSupportedException( string.Format( "Failed to unify field '{0}' in structure '{1}' with field '{2}' in structure '{3}'.", fa.Name, a, fb.Name, b)); } mem.Fields.Add(fa.Offset, fieldType, fieldName); fa = null; fb = null; } } if (fa != null) { mem.Fields.Add(fa); while (ea.MoveNext()) { StructureField f = ea.Current; mem.Fields.Add(f.Clone()); } } if (fb != null) { mem.Fields.Add(fb); while (eb.MoveNext()) { StructureField f = eb.Current; mem.Fields.Add(f.Clone()); } } mem.ForceStructure = a.ForceStructure | b.ForceStructure; return(mem); }
public TypeVariable EnsureFieldTypeVariable(TypeFactory factory, StructureField field) { throw new NotImplementedException(); }