<commit_before>using System;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace MFMetaDataProcessor {

    /// <summary>
    /// Encaplulates logic related for writing correct byte code and calculating stack size.
    /// </summary>
    /// <remarks>
    /// This class initially copy-pasted from Mono.Cecil codebase but changed a lot.
    /// </remarks>
	internal sealed class CodeWriter
    {
        /// <summary>
        /// Original method body information in Mono.Cecil format.
        /// </summary>
        private readonly MethodBody _body;

        /// <summary>
        /// Binary writer for writing byte code in correct endianess.
        /// </summary>
	    private readonly TinyBinaryWriter _writer;

        /// <summary>
        /// String literals table (used for obtaining string literal ID).
        /// </summary>
        private readonly TinyStringTable _stringTable;

        /// <summary>
        /// Assembly tables context - contains all tables used for building target assembly.
        /// </summary>
        private readonly TinyTablesContext _context;

        /// <summary>
        /// Creates new instance of <see cref="Mono.Cecil.Cil.CodeWriter"/> object.
        /// </summary>
        /// <param name="method">Original method body in Mono.Cecil format.</param>
        /// <param name="writer">Binary writer for writing byte code in correct endianess.</param>
        /// <param name="stringTable">String references table (for obtaining string ID).</param>
        /// <param name="context">
        /// Assembly tables context - contains all tables used for building target assembly.
        /// </param>
        public CodeWriter(
	        MethodDefinition method,
            TinyBinaryWriter writer,
            TinyStringTable stringTable,
            TinyTablesContext context)
	    {
            _stringTable = stringTable;

            _body = method.Body;
            _context = context;
            _writer = writer;
        }

        /// <summary>
        /// Writes method body into binary writer originally passed into constructor.
        /// </summary>
        public void WriteMethodBody()
        {
            foreach (var instruction in _body.Instructions)
            {
                WriteOpCode(instruction.OpCode);
                WriteOperand(instruction);
            }

            WriteExceptionsTable();
        }

        /// <summary>
        /// Fixes instructions offsets according .NET Micro Framework operands sizes.
        /// </summary>
        /// <param name="methodDefinition">Target method for fixing offsets</param>
        /// <param name="stringTable">String table for populating strings from method.</param>
        public static void PreProcessMethod(
            MethodDefinition methodDefinition,
            TinyStringTable stringTable)
        {
            if (!methodDefinition.HasBody)
            {
                return;
            }

            var offset = 0;
            foreach (var instruction in methodDefinition.Body.Instructions)
            {
                instruction.Offset += offset;

                switch (instruction.OpCode.OperandType)
                {
                    case OperandType.InlineString:
                        stringTable.GetOrCreateStringId((String) instruction.Operand);
                        offset -= 2;
                        break;
                    case OperandType.InlineMethod:
                    case OperandType.InlineField:
                    case OperandType.InlineType:
                    case OperandType.InlineBrTarget:
                        // In full .NET these instructions followed by double word operand
                        // but in .NET Micro Framework these instruction's operand are word
                        offset -= 2;
                        break;
                }
            }
        }

        /// <summary>
        /// Calculates method stack size for passed <paramref name="methodBody"/> method.
        /// </summary>
        /// <param name="methodBody">Method body in Mono.Cecil format.</param>
        /// <returns>Maximal evaluated stack size for passed method body.</returns>
	    public static Byte CalculateStackSize(
	        MethodBody methodBody)
	    {
            if (methodBody == null)
            {
                return 0;
            }

            var size = 0;
            var maxSize = 0;
	        foreach (var instruction in methodBody.Instructions)
	        {
	            switch (instruction.OpCode.Code)
	            {
                    case Code.Throw:
                    case Code.Endfinally:
                    case Code.Endfilter:
                    case Code.Leave_S:
                    case Code.Leave:
                        size = 0;
                        continue;
                    case Code.Callvirt:
	                    {
                            var method = (MethodReference)instruction.Operand;
                            if (method.HasThis)
                            {
                                --size;
                            }
                            size -= method.Parameters.Count;
                        }
                        break;
                    case Code.Call:
	                    {
                            var method = (MethodReference)instruction.Operand;
                            if (method.HasThis)
                            {
                                --size;
                            }
                            size -= method.Parameters.Count;
                            if (method.ReturnType.FullName != "System.Void")
                            {<commit_msg>Fix stack caclulation size issue (one strange still exists).<commit_after>using System;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace MFMetaDataProcessor {

    /// <summary>
    /// Encaplulates logic related for writing correct byte code and calculating stack size.
    /// </summary>
    /// <remarks>
    /// This class initially copy-pasted from Mono.Cecil codebase but changed a lot.
    /// </remarks>
	internal sealed class CodeWriter
    {
        /// <summary>
        /// Original method body information in Mono.Cecil format.
        /// </summary>
        private readonly MethodBody _body;

        /// <summary>
        /// Binary writer for writing byte code in correct endianess.
        /// </summary>
	    private readonly TinyBinaryWriter _writer;

        /// <summary>
        /// String literals table (used for obtaining string literal ID).
        /// </summary>
        private readonly TinyStringTable _stringTable;

        /// <summary>
        /// Assembly tables context - contains all tables used for building target assembly.
        /// </summary>
        private readonly TinyTablesContext _context;

        /// <summary>
        /// Creates new instance of <see cref="Mono.Cecil.Cil.CodeWriter"/> object.
        /// </summary>
        /// <param name="method">Original method body in Mono.Cecil format.</param>
        /// <param name="writer">Binary writer for writing byte code in correct endianess.</param>
        /// <param name="stringTable">String references table (for obtaining string ID).</param>
        /// <param name="context">
        /// Assembly tables context - contains all tables used for building target assembly.
        /// </param>
        public CodeWriter(
	        MethodDefinition method,
            TinyBinaryWriter writer,
            TinyStringTable stringTable,
            TinyTablesContext context)
	    {
            _stringTable = stringTable;

            _body = method.Body;
            _context = context;
            _writer = writer;
        }

        /// <summary>
        /// Writes method body into binary writer originally passed into constructor.
        /// </summary>
        public void WriteMethodBody()
        {
            foreach (var instruction in _body.Instructions)
            {
                WriteOpCode(instruction.OpCode);
                WriteOperand(instruction);
            }

            WriteExceptionsTable();
        }

        /// <summary>
        /// Fixes instructions offsets according .NET Micro Framework operands sizes.
        /// </summary>
        /// <param name="methodDefinition">Target method for fixing offsets</param>
        /// <param name="stringTable">String table for populating strings from method.</param>
        public static void PreProcessMethod(
            MethodDefinition methodDefinition,
            TinyStringTable stringTable)
        {
            if (!methodDefinition.HasBody)
            {
                return;
            }

            var offset = 0;
            foreach (var instruction in methodDefinition.Body.Instructions)
            {
                instruction.Offset += offset;

                switch (instruction.OpCode.OperandType)
                {
                    case OperandType.InlineString:
                        stringTable.GetOrCreateStringId((String) instruction.Operand);
                        offset -= 2;
                        break;
                    case OperandType.InlineMethod:
                    case OperandType.InlineField:
                    case OperandType.InlineType:
                    case OperandType.InlineBrTarget:
                        // In full .NET these instructions followed by double word operand
                        // but in .NET Micro Framework these instruction's operand are word
                        offset -= 2;
                        break;
                }
            }
        }

        /// <summary>
        /// Calculates method stack size for passed <paramref name="methodBody"/> method.
        /// </summary>
        /// <param name="methodBody">Method body in Mono.Cecil format.</param>
        /// <returns>Maximal evaluated stack size for passed method body.</returns>
	    public static Byte CalculateStackSize(
	        MethodBody methodBody)
	    {
            if (methodBody == null)
            {
                return 0;
            }

            var size = 0;
            var maxSize = 0;
	        foreach (var instruction in methodBody.Instructions)
	        {
	            switch (instruction.OpCode.Code)
	            {
                    case Code.Throw:
                    case Code.Endfinally:
                    case Code.Endfilter:
                    case Code.Leave_S:
                    case Code.Leave:
                        size = 0;
                        continue;
                    case Code.Br:
                    case Code.Br_S:
                    case Code.Brtrue:
                    case Code.Brtrue_S:
                    case Code.Brfalse:
                    case Code.Brfalse_S:
                    case Code.Break:
                        break;
                    case Code.Newobj:
	                    {
                            var method = (MethodReference)instruction.Operand;
                            size -= method.Parameters.Count;
                        }
                        break;
                    case Code.Callvirt:
                    case Code.Call:
	                    {
                            var method = (MethodReference)instruction.Operand;
                            if (method.HasThis)
                            {
                                --size;
                            }
                            size -= method.Parameters.Count;
                            if (method.ReturnType.FullName != "System.Void")
                            {
{'fraction_non_alphanumeric': 0.08349900596421471, 'fraction_numerical': 0.001210130521220503, 'mean_word_length': 1.2444228903976722, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6277520', 'n_tokens_mistral': 2642, 'n_tokens_neox': 2498, 'n_words': 742}