<commit_before>﻿#if !NETSTANDARD1_X
using System;
using System.Reflection;
using System.Linq.Expressions;
using MonoMod.Utils;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using System.Linq;
using System.Diagnostics;
using System.ComponentModel;
using System.Security;
using System.IO;

namespace MonoMod.Utils {
    public sealed partial class DynamicMethodDefinition : IDisposable {

        private static OpCode[] _CecilOpCodes1X;
        private static OpCode[] _CecilOpCodes2X;

        private static void _InitCopier() {
            _CecilOpCodes1X = new OpCode[0xe1];
            _CecilOpCodes2X = new OpCode[0x1f];

            foreach (FieldInfo field in typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) {
                OpCode opcode = (OpCode) field.GetValue(null);
                if (opcode.OpCodeType == OpCodeType.Nternal)
                    continue;

                if (opcode.Size == 1)
                    _CecilOpCodes1X[opcode.Value] = opcode;
                else
                    _CecilOpCodes2X[opcode.Value & 0xff] = opcode;
            }
        }

        private void _CopyMethodToDefinition() {
            MethodBase method = Method;
            Module moduleFrom = method.Module;
            System.Reflection.MethodBody bodyFrom = method.GetMethodBody();
            byte[] data = bodyFrom?.GetILAsByteArray();
            if (data == null)
                throw new NotSupportedException("Body-less method");

            MethodDefinition def = Definition;
            ModuleDefinition moduleTo = def.Module;
            Mono.Cecil.Cil.MethodBody bodyTo = def.Body;
            ILProcessor processor = bodyTo.GetILProcessor();

            Type[] typeArguments = null;
            if (method.DeclaringType.IsGenericType)
                typeArguments = method.DeclaringType.GetGenericArguments();

            Type[] methodArguments = null;
            if (method.IsGenericMethod)
                methodArguments = method.GetGenericArguments();

            foreach (LocalVariableInfo info in bodyFrom.LocalVariables) {
                TypeReference type = moduleTo.ImportReference(info.LocalType);
                if (info.IsPinned)
                    type = new PinnedType(type);
                bodyTo.Variables.Add(new VariableDefinition(type));
            }

            using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) {
                while (reader.BaseStream.Position < reader.BaseStream.Length) {
                    int offset = (int) reader.BaseStream.Position;
                    Instruction instr = Instruction.Create(OpCodes.Nop);
                    byte op = reader.ReadByte();
                    instr.OpCode = op != 0xfe ? _CecilOpCodes1X[op] : _CecilOpCodes2X[reader.ReadByte()];
                    instr.Offset = offset;
                    ReadOperand(reader, instr);
                    bodyTo.Instructions.Add(instr);
                }
            }

            foreach (Instruction instr in bodyTo.Instructions) {
                switch (instr.OpCode.OperandType) {
                    case OperandType.ShortInlineBrTarget:
                    case OperandType.InlineBrTarget:
                        instr.Operand = GetInstruction((int) instr.Operand, false);
                        break;

                    case OperandType.InlineSwitch:
                        int[] offsets = (int[]) instr.Operand;
                        Instruction[] targets = new Instruction[offsets.Length];
                        for (int i = 0; i < offsets.Length; i++)
                            targets[i] = GetInstruction(offsets[i], false);
                        instr.Operand = targets;
                        break;
                }
            }

            foreach (ExceptionHandlingClause clause in bodyFrom.ExceptionHandlingClauses) {
                ExceptionHandler handler = new ExceptionHandler((ExceptionHandlerType) clause.Flags);
                bodyTo.ExceptionHandlers.Add(handler);

                handler.TryStart = GetInstruction(clause.TryOffset, false);
                handler.TryEnd = GetInstruction(handler.TryStart.Offset + clause.TryLength - 1, false);

                handler.HandlerStart = GetInstruction(clause.HandlerOffset, false);
                handler.FilterStart = GetInstruction(clause.FilterOffset, false);
                handler.HandlerEnd = GetInstruction((handler.FilterStart ?? handler.HandlerStart).Offset + clause.HandlerLength, true);

                handler.CatchType = clause.CatchType == null ? null : moduleTo.ImportReference(clause.CatchType);
            }

            void ReadOperand(BinaryReader reader, Instruction instr) {
                int index, offs, length;
                switch (instr.OpCode.OperandType) {
                    case OperandType.InlineNone:
                        instr.Operand = null;
                        break;

                    case OperandType.InlineSwitch:
                        length = reader.ReadInt32();
                        offs = (int) reader.BaseStream.Position + (4 * length);
                        int[] targets = new int[length];
                        for (int i = 0; i < length; i++)
                            targets[i] = reader.ReadInt32() + offs;
                        instr.Operand = targets;
                        break;

                    case OperandType.ShortInlineBrTarget:
                        offs = reader.ReadSByte();
                        instr.Operand = (int) reader.BaseStream.Position + offs;
                        break;

                    case OperandType.InlineBrTarget:
                        offs = reader.ReadInt32();
                        instr.Operand = (int) reader.BaseStream.Position + offs;
                        break;<commit_msg>Fix yet another off-by-one in DMD.Copy (thanks, Magnus!)<commit_after>﻿#if !NETSTANDARD1_X
using System;
using System.Reflection;
using System.Linq.Expressions;
using MonoMod.Utils;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using System.Linq;
using System.Diagnostics;
using System.ComponentModel;
using System.Security;
using System.IO;

namespace MonoMod.Utils {
    public sealed partial class DynamicMethodDefinition : IDisposable {

        private static OpCode[] _CecilOpCodes1X;
        private static OpCode[] _CecilOpCodes2X;

        private static void _InitCopier() {
            _CecilOpCodes1X = new OpCode[0xe1];
            _CecilOpCodes2X = new OpCode[0x1f];

            foreach (FieldInfo field in typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) {
                OpCode opcode = (OpCode) field.GetValue(null);
                if (opcode.OpCodeType == OpCodeType.Nternal)
                    continue;

                if (opcode.Size == 1)
                    _CecilOpCodes1X[opcode.Value] = opcode;
                else
                    _CecilOpCodes2X[opcode.Value & 0xff] = opcode;
            }
        }

        private void _CopyMethodToDefinition() {
            MethodBase method = Method;
            Module moduleFrom = method.Module;
            System.Reflection.MethodBody bodyFrom = method.GetMethodBody();
            byte[] data = bodyFrom?.GetILAsByteArray();
            if (data == null)
                throw new NotSupportedException("Body-less method");

            MethodDefinition def = Definition;
            ModuleDefinition moduleTo = def.Module;
            Mono.Cecil.Cil.MethodBody bodyTo = def.Body;
            ILProcessor processor = bodyTo.GetILProcessor();

            Type[] typeArguments = null;
            if (method.DeclaringType.IsGenericType)
                typeArguments = method.DeclaringType.GetGenericArguments();

            Type[] methodArguments = null;
            if (method.IsGenericMethod)
                methodArguments = method.GetGenericArguments();

            foreach (LocalVariableInfo info in bodyFrom.LocalVariables) {
                TypeReference type = moduleTo.ImportReference(info.LocalType);
                if (info.IsPinned)
                    type = new PinnedType(type);
                bodyTo.Variables.Add(new VariableDefinition(type));
            }

            using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) {
                while (reader.BaseStream.Position < reader.BaseStream.Length) {
                    int offset = (int) reader.BaseStream.Position;
                    Instruction instr = Instruction.Create(OpCodes.Nop);
                    byte op = reader.ReadByte();
                    instr.OpCode = op != 0xfe ? _CecilOpCodes1X[op] : _CecilOpCodes2X[reader.ReadByte()];
                    instr.Offset = offset;
                    ReadOperand(reader, instr);
                    bodyTo.Instructions.Add(instr);
                }
            }

            foreach (Instruction instr in bodyTo.Instructions) {
                switch (instr.OpCode.OperandType) {
                    case OperandType.ShortInlineBrTarget:
                    case OperandType.InlineBrTarget:
                        instr.Operand = GetInstruction((int) instr.Operand, false);
                        break;

                    case OperandType.InlineSwitch:
                        int[] offsets = (int[]) instr.Operand;
                        Instruction[] targets = new Instruction[offsets.Length];
                        for (int i = 0; i < offsets.Length; i++)
                            targets[i] = GetInstruction(offsets[i], false);
                        instr.Operand = targets;
                        break;
                }
            }

            foreach (ExceptionHandlingClause clause in bodyFrom.ExceptionHandlingClauses) {
                ExceptionHandler handler = new ExceptionHandler((ExceptionHandlerType) clause.Flags);
                bodyTo.ExceptionHandlers.Add(handler);

                handler.TryStart = GetInstruction(clause.TryOffset, false);
                handler.TryEnd = GetInstruction(handler.TryStart.Offset + clause.TryLength - 1, false);

                handler.HandlerStart = GetInstruction(clause.HandlerOffset, false);
                handler.FilterStart = GetInstruction(clause.FilterOffset, false);
                handler.HandlerEnd = GetInstruction((handler.FilterStart ?? handler.HandlerStart).Offset + clause.HandlerLength + 1, true);

                handler.CatchType = clause.CatchType == null ? null : moduleTo.ImportReference(clause.CatchType);
            }

            void ReadOperand(BinaryReader reader, Instruction instr) {
                int index, offs, length;
                switch (instr.OpCode.OperandType) {
                    case OperandType.InlineNone:
                        instr.Operand = null;
                        break;

                    case OperandType.InlineSwitch:
                        length = reader.ReadInt32();
                        offs = (int) reader.BaseStream.Position + (4 * length);
                        int[] targets = new int[length];
                        for (int i = 0; i < length; i++)
                            targets[i] = reader.ReadInt32() + offs;
                        instr.Operand = targets;
                        break;

                    case OperandType.ShortInlineBrTarget:
                        offs = reader.ReadSByte();
                        instr.Operand = (int) reader.BaseStream.Position + offs;
                        break;

                    case OperandType.InlineBrTarget:
                        offs = reader.ReadInt32();
                        instr.Operand = (int) reader.BaseStream.Position + offs;
                        break;
{'fraction_non_alphanumeric': 0.08447819779844697, 'fraction_numerical': 0.004522570185169383, 'mean_word_length': 1.6642418731529893, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, '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': '3435045', 'n_tokens_mistral': 2949, 'n_tokens_neox': 2829, 'n_words': 609}