public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var index = (byte)((PrimitiveILInstructionParameter)parameter).Value; CheckNotEmpty(il, stack, () => "A value must be put onto the evaluation stack in order to perform the 'starg' instruction"); CheckCanBeAssigned(il, il.methodParameterTypes[index], stack.Pop()); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { if (stack.Count != 0) { throw new InvalidOperationException("The evaluation stack must be empty in order to perform the 'jmp' instruction\r\n" + il.GetILCode()); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var type = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "In order to perform the 'ldind' instruction load an address onto the evaluation stack"); var esType = stack.Pop(); CheckIsAPointer(il, esType); var pointer = esType.ToType(); if (pointer.IsByRef) { var elementType = pointer.GetElementType(); if (elementType.IsValueType) CheckCanBeAssigned(il, type.MakeByRefType(), pointer); else CheckCanBeAssigned(il, type, elementType); } else if (pointer.IsPointer) { var elementType = pointer.GetElementType(); if (elementType.IsValueType) CheckCanBeAssigned(il, type.MakePointerType(), pointer); else CheckCanBeAssigned(il, type, elementType); } else if (!type.IsPrimitive && type != typeof(object)) ThrowError(il, $"Unable to load an instance of type '{Formatter.Format(type)}' from a pointer of type '{Formatter.Format(pointer)}' indirectly"); stack.Push(type); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'cpobj' instruction a source address must be loaded onto the evaluation stack"); CheckIsAPointer(il, stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'cpobj' instruction a destination address must be loaded onto the evaluation stack"); CheckIsAPointer(il, stack.Pop()); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var type = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "In order to perform the 'newarr' instruction a length of an array must be loaded onto the evaluation stack"); CheckCanBeAssigned(il, typeof(int), stack.Pop()); stack.Push(type.MakeArrayType()); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var type = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "An object must be put onto the evaluation stack in order to perform the 'unbox_any' instruction"); CheckCanBeAssigned(il, typeof(object), stack.Pop()); stack.Push(type); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var type = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "To perform the 'box' instruction load a value on the evaluation stack"); CheckCanBeAssigned(il, type, stack.Pop()); stack.Push(type.IsEnum ? typeof(Enum) : typeof(object)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var type = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "In order to perform the 'isinst' instruction an instance must be put onto the evaluation stack"); CheckCanBeAssigned(il, typeof(object), stack.Pop()); stack.Push(type.IsValueType ? typeof(object) : type); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'cpblk' instruction a number of bytes to copy must be loaded onto the evaluation stack"); CheckCanBeAssigned(il, typeof(int), stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'cpblk' instruction a source address must be loaded onto the evaluation stack"); CheckIsAPointer(il, stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'cpblk' instruction a destination address must be loaded onto the evaluation stack"); CheckIsAPointer(il, stack.Pop()); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var local = ((LocalILInstructionParameter)parameter).Local; CheckNotEmpty(il, stack, () => "A value must be put onto the evaluation stack in order to perform the 'stloc' instruction"); var peek = stack.Pop(); CheckCanBeAssigned(il, local.Type, peek); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'initblk' instruction a number of bytes to initialize must be put onto the evaluation stack"); CheckCanBeAssigned(il, typeof(int), stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'initblk' instruction an initialization value must be put onto the evaluation stack"); CheckCanBeAssigned(il, typeof(int), stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'initblk' instruction a starting address must be put onto the evaluation stack"); CheckIsAPointer(il, stack.Pop()); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'ckfinite' instruction an instance must be loaded onto the evaluation stack"); var peek = stack.Peek(); if (ToCLIType(peek) != CLIType.Float) { ThrowError(il, $"It is only allowed to check if value is finite for floating point values but was '{peek}'"); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var method = ((MethodILInstructionParameter)parameter).Method; CheckNotEmpty(il, stack, () => "Ldvirtftn requires an instance to be loaded onto evaluation stack"); var instance = stack.Pop(); var declaringType = method.DeclaringType; CheckCanBeAssigned(il, declaringType, instance); stack.Push(typeof(IntPtr)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => $"In order to perform the instruction 'localloc' size must be loaded onto the evaluation stack"); var type = stack.Pop(); if (ToCLIType(type) != CLIType.NativeInt) { ThrowError(il, $"Unable to perform the instruction 'localloc' on type '{type}'"); } stack.Push(typeof(UIntPtr)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var labels = ((LabelsILInstructionParameter)parameter).Labels; CheckNotEmpty(il, stack, () => "A value must be put onto the evaluation stack in order to perform the 'switch' instruction"); CheckNotStruct(il, stack.Pop()); foreach (var label in labels) { SaveOrCheck(il, stack, label); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => $"In order to perform the instruction '{opCode}' an instance must be loaded onto the evaluation stack"); var type = stack.Pop(); if (!Allowed(type)) { ThrowError(il, $"Unable to perform the instruction '{opCode}' on type '{type}'"); } stack.Push(to); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var constructor = ((ConstructorILInstructionParameter)parameter).Constructor; var parameterTypes = ReflectionExtensions.GetParameterTypes(constructor); for (var i = parameterTypes.Length - 1; i >= 0; --i) { CheckNotEmpty(il, stack, () => string.Format("Expected exactly {0} parameters to call the constructor '{1}'", parameterTypes.Length, Formatter.Format(constructor))); CheckCanBeAssigned(il, parameterTypes[i], stack.Pop()); } stack.Push(constructor.ReflectedType); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'ldlen' instruction an array must be loaded onto the evaluation stack"); var esType = stack.Pop(); var array = esType.ToType(); if (!array.IsArray && array != typeof(Array)) { ThrowError(il, string.Format("An array expected but was '{0}'", esType)); } stack.Push(typeof(int)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'neg' operation an instance must be put onto the evaluation stack"); var esType = stack.Pop(); var cliType = ToCLIType(esType); if (cliType != CLIType.Int32 && cliType != CLIType.Int64 && cliType != CLIType.NativeInt && cliType != CLIType.Float && cliType != CLIType.Zero) { ThrowError(il, $"Unable to perform the 'neg' operation on type '{esType}'"); } stack.Push(Canonize(esType)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'not' operation an instance must be put onto the evaluation stack"); var esType = stack.Pop(); var cliType = ToCLIType(esType); if (cliType != CLIType.Int32 && cliType != CLIType.Int64 && cliType != CLIType.NativeInt && cliType != CLIType.Zero) { ThrowError(il, string.Format("Unable to perform the 'not' operation on type '{0}'", esType)); } // !zero = -1 -> native int stack.Push(cliType == CLIType.Zero ? typeof(IntPtr) : Canonize(esType)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { // todo test ALL! var to = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "In order to perform the 'castclass' instruction an instance must be loaded onto the evaluation stack"); var from = stack.Pop().ToType(); if (!(ToCLIType(from) == CLIType.Object && CanBeAssigned(to, from))) { CheckCanBeAssigned(il, from, to); } stack.Push(to); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var label = ((LabelILInstructionParameter)parameter).Label; if (stack != null) { SaveOrCheck(il, stack, label); } ESType[] labelStack; if (il.labelStacks.TryGetValue(label, out labelStack)) { stack = new EvaluationStack(labelStack); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { if (parameter is TypeILInstructionParameter) { stack.Push(typeof(RuntimeTypeHandle)); } if (parameter is MethodILInstructionParameter) { stack.Push(typeof(RuntimeMethodHandle)); } if (parameter is FieldILInstructionParameter) { stack.Push(typeof(RuntimeFieldHandle)); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var elementType = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "In order to perform the 'ldelema' instruction an index must be put onto the evaluation stack"); CheckCanBeAssigned(il, typeof(int), stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'ldelema' instruction an array must be put onto the evaluation stack"); var esType = stack.Pop(); var array = esType.ToType(); if (!array.IsArray && array != typeof(Array)) { throw new InvalidOperationException(string.Format("An array expected to perform the 'ldelema' instruction but was '{0}'", esType)); } stack.Push(elementType.MakeByRefType()); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var elementType = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "A value must be put onto the evaluation stack in order to perform the 'stelem' instruction"); CheckCanBeAssigned(il, elementType, stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'stelem' instruction an index must be put onto the evaluation stack"); CheckCanBeAssigned(il, typeof(int), stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'stelem' instruction an array must be put onto the evaluation stack"); var esType = stack.Pop(); var array = esType.ToType(); if (!array.IsArray && array != typeof(Array)) { ThrowError(il, $"An array expected to perform the 'stelem' instruction but was '{esType}'"); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => string.Format("Expected two arguments for the operation '{0}'", opCode)); var right = stack.Pop(); CheckNotEmpty(il, stack, () => string.Format("Expected two arguments for the operation '{0}'", opCode)); var left = stack.Pop(); if (!IsAllowed(ToCLIType(left), ToCLIType(right))) { ThrowError(il, string.Format("Cannot perform the instruction '{0}' on types '{1}' and '{2}'", opCode, left, right)); } var result = Canonize(GetResultType(Canonize(left), Canonize(right))); if (result != typeof(void)) { stack.Push(result); } PostAction(il, parameter, ref stack); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var label = ((LabelILInstructionParameter)parameter).Label; CheckNotEmpty(il, stack, () => "The 'brfalse' instruction required one argument but none is supplied"); var value = stack.Pop(); CheckNotStruct(il, value); var newStack = stack.Reverse().ToArray(); for (var i = 0; i < newStack.Length; ++i) { if (ReferenceEquals(newStack[i], value)) { newStack[i] = ESType.Zero; } } SaveOrCheck(il, new EvaluationStack(newStack), label); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var field = ((FieldILInstructionParameter)parameter).Field; CheckNotEmpty(il, stack, () => string.Format("In order to store the field '{0}' a value must be put onto the evaluation stack", Formatter.Format(field))); CheckCanBeAssigned(il, field.FieldType, stack.Pop()); if (!field.IsStatic) { var declaringType = field.DeclaringType; CheckNotEmpty(il, stack, () => string.Format("In order to store the field '{0}' an instance must be put onto the evaluation stack", Formatter.Format(field))); var instance = stack.Pop().ToType(); if (instance != null) { if (instance.IsValueType) { ThrowError(il, string.Format("In order to store the field '{0}' of a value type '{1}' load an instance by ref", Formatter.Format(field), Formatter.Format(instance))); } else if (!instance.IsByRef) { CheckCanBeAssigned(il, declaringType, instance); } else { var elementType = instance.GetElementType(); if (elementType.IsValueType) { if (declaringType != elementType) { ThrowError(il, string.Format("Cannot store the field '{0}' to an instance of type '{1}'", Formatter.Format(field), Formatter.Format(elementType))); } } else { ThrowError(il, string.Format("Cannot store the field '{0}' to an instance of type '{1}'", Formatter.Format(field), Formatter.Format(instance))); } } } } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { if (il.methodReturnType == typeof(void)) { if (stack.Count != 0) { ThrowError(il, "The function being emitted is void. Thus at the end the evaluation stack must be empty"); } } else if (stack.Count == 0) { ThrowError(il, "The function being emitted is not void. But the evaluation stack is empty"); } else if (stack.Count > 1) { ThrowError(il, "At the end the evaluation stack must contain exactly one element"); } else { var peek = stack.Pop(); CheckCanBeAssigned(il, il.methodReturnType, peek); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var calliParameter = (MethodByAddressILInstructionParameter)parameter; var returnType = calliParameter.ReturnType; var parameterTypes = calliParameter.ParameterTypes; CheckNotEmpty(il, stack, () => "In order to perform the 'calli' instruction an entry point must be loaded onto the evaluation stack"); var entryPoint = stack.Pop(); if (ToCLIType(entryPoint) != CLIType.NativeInt) { ThrowError(il, string.Format("An entry point must be a native int but was '{0}'", entryPoint)); } for (var i = parameterTypes.Length - 1; i >= 0; --i) { CheckNotEmpty(il, stack, () => string.Format("Expected exactly {0} parameters, but the evaluation stack is empty", parameterTypes.Length)); CheckCanBeAssigned(il, parameterTypes[i], stack.Pop()); } if (returnType != typeof(void)) { stack.Push(returnType); } }