public static VariableDefinition AddLocalVariable(this MethodDefinition m, TypeReference type, string name = "") { if (m.Module == null) { throw new NullReferenceException($"This method has yet to be added to the assembly and doesn't have a module. Please provide a module."); } return(m.AddLocalVariable(m.Module, type, name)); }
public static VariableDefinition AddLocalVariable <T>(this MethodDefinition m, ModuleDefinition module, string name = "") { return(m.AddLocalVariable(module, module.ImportReference(typeof(T)), name)); }
public static Instruction[] GetKeyCheck(MethodDefinition method, VariableDefinition key, VariableDefinition stringKey, VariableDefinition keyLength, FieldDefinition field, MethodDefinition fieldSpan, out Instruction lengthLast, out Instruction checkLast, out bool isAdvanced) { Span <byte> binary = utf8.GetBytes(field.Name).AsSpan(); switch (binary.Length) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: isAdvanced = false; return(ByteKeyNameCheck(out lengthLast, out checkLast)); default: isAdvanced = true; return(SequenceEqualsCheck(binary.Length, out lengthLast, out checkLast)); } Instruction[] ByteKeyNameCheck(out Instruction length, out Instruction check) { ulong id = GetKeyName(field.Name); List <Instruction> i = new List <Instruction>(); i.AddRange(ILHelper.Ldloc(keyLength)); length = ILHelper.Int(field.Name.Length); i.Add(length); i.AddRange(ILHelper.Ldloc(key)); i.Add(ILHelper.ULong(id)); if (id < int.MaxValue) { i.Add(Instruction.Create(OpCodes.Conv_I8)); } check = i[i.Count - 1]; return(i.ToArray()); } Instruction[] SequenceEqualsCheck(int binaryLength, out Instruction length, out Instruction last) { VariableDefinition v = method.AddLocalVariable(method.Module.ImportReference(typeof(ReadOnlySpan <byte>))); MethodReference seqEqual = null; MethodInfo[] methods = typeof(MemoryExtensions).GetMethods(); for (int j = 0; j < methods.Length; j++) { if (methods[j].Name == "SequenceEqual") { ParameterInfo[] para = methods[j].GetParameters(); if (para.Length == 2 && IsSameType(para[0].ParameterType, typeof(ReadOnlySpan <>)) && IsSameType(para[1].ParameterType, typeof(ReadOnlySpan <>))) { seqEqual = method.Module.ImportReference(methods[j]).MakeGenericMethod(method.Module.GetTypeReference <byte>()); break; } } } if (seqEqual == null) { throw new NullReferenceException("Couldn't find the sequence equals method."); } List <Instruction> i = new List <Instruction>(); i.AddRange(ILHelper.Ldloc(keyLength)); length = ILHelper.Int(field.Name.Length); i.Add(length); i.AddRange(ILHelper.Ldloc(stringKey)); i.Add(Instruction.Create(OpCodes.Call, fieldSpan)); i.AddRange(ILHelper.Stloc(v)); i.AddRange(ILHelper.Ldloc(v, true)); i.Add(ILHelper.Int(GetHeaderLength(binaryLength))); i.Add(Instruction.Create(OpCodes.Call, method.Module.ImportReference(typeof(ReadOnlySpan <byte>).GetMethod("Slice", new[] { typeof(int) })))); i.Add(Instruction.Create(OpCodes.Call, seqEqual)); last = i[i.Count - 1]; return(i.ToArray()); bool IsSameType(Type typeA, Type typeB) { return($"{typeA.Namespace}.{typeA.Name}" == typeB.FullName); } } }