Beispiel #1
0
 public bool Equals(CatchSet other)
 {
     if ((other == null) || (Count != other.Count) || (!Equals(CatchAll, other.CatchAll)))
     {
         return(false);
     }
     for (var i = 0; i < Count; i++)
     {
         if (!this[i].Equals(other[i]))
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #2
0
        /// <summary>
        /// Write a single code_item structure
        /// </summary>
        /// <returns>True if a code_item was written, false otherwise</returns>
        private bool WriteCodeItem(BinaryWriter writer, MethodDefinition method, uint sectionOffset)
        {
            codes.Add(method, 0);
            var body = method.Body;

            if (body == null)
            {
                return(false);
            }

            body.UpdateInstructionOffsets();
            writer.EnsureAlignment(sectionOffset, 4);
            codes[method] = (uint)writer.BaseStream.Position;

            writer.Write((ushort)body.Registers.Count);
            writer.Write(body.IncomingArguments);
            writer.Write(body.OutgoingArguments);
            writer.Write((ushort)body.Exceptions.Count);
            debugMarkers.Add(method, writer.MarkUInt());

            var iwriter = new InstructionWriter(this, method);

            iwriter.WriteTo(writer);

            if ((body.Exceptions.Count != 0) &&
                (iwriter.Codes.Length % 2 != 0))
            {
                writer.Write((ushort)0);
            }
            // padding (tries 4-byte alignment)

            var catchHandlers     = new Dictionary <CatchSet, List <ExceptionHandler> >();
            var exceptionsMarkers = new Dictionary <ExceptionHandler, UShortMarker>();

            foreach (var handler in body.Exceptions)
            {
                writer.Write(handler.TryStart.Offset);
                writer.Write((ushort)(iwriter.LookupLast[handler.TryEnd] - handler.TryStart.Offset + 1));
                exceptionsMarkers.Add(handler, writer.MarkUShort());

                var set = new CatchSet(handler);
                if (!catchHandlers.ContainsKey(set))
                {
                    catchHandlers.Add(set, new List <ExceptionHandler>());
                }
                catchHandlers[set].Add(handler);
            }

            var catchSets = catchHandlers.Keys.ToList();

            catchSets.Sort(new CatchSetComparer());

            if (catchSets.Count > 0)
            {
                var baseOffset = writer.BaseStream.Position;
                writer.WriteULEB128((uint)catchSets.Count);
                foreach (var set in catchSets)
                {
                    var itemoffset = writer.BaseStream.Position - baseOffset;

                    if (set.CatchAll != null)
                    {
                        writer.WriteSLEB128(-set.Count);
                    }
                    else
                    {
                        writer.WriteSLEB128(set.Count);
                    }

                    foreach (var handler in catchHandlers[set])
                    {
                        exceptionsMarkers[handler].Value = (ushort)itemoffset;
                    }

                    foreach (var @catch in set)
                    {
                        writer.WriteULEB128((uint)typeLookup[@catch.Type]);
                        writer.WriteULEB128((uint)@catch.Instruction.Offset);
                    }

                    if (set.CatchAll != null)
                    {
                        writer.WriteULEB128((uint)set.CatchAll.Offset);
                    }
                }
            }
            return(true);
        }