public void LdcI4Macro(CilCode code, int expected) { var result = Dispatcher.Execute(ExecutionContext, new CilInstruction(code.ToOpCode())); Assert.True(result.IsSuccess); Assert.Equal(new I4Value(expected), ExecutionContext.ProgramState.Stack.Top); }
// taken from System.Reflection.Emit.OpCode internal CilOpCode(CilCode value, int flags) : this() { Name = value.ToString().ToLowerInvariant().Replace('_', '.'); StackBehaviourPop = (CilStackBehaviour)(flags >> 12 & 31); StackBehaviourPush = (CilStackBehaviour)(flags >> 17 & 31); OperandType = (CilOperandType)(flags & 31); OpCodeType = (CilOpCodeType)(flags >> 9 & 7); Size = (flags >> 22 & 3); Op1 = (byte)((ushort)value >> 8); Op2 = (byte)value; Code = value; FlowControl = (CilFlowControl)(flags >> 5 & 15); // m_endsUncondJmpBlk = ((flags & 16777216) != 0); // m_stackChange = flags >> 28; if (Size == 1) { CilOpCodes.SingleByteOpCodes[Op2] = this; } else { CilOpCodes.MultiByteOpCodes[Op2] = this; } }
/// <summary> /// Transforms the raw CIL code to a <see cref="CilOpCode"/>. /// </summary> /// <param name="code">The code to convert.</param> /// <returns>The operation code.</returns> public static CilOpCode ToOpCode(this CilCode code) { if (code < (CilCode)0x100) { return(CilOpCodes.SingleByteOpCodes[(int)code]); } return(CilOpCodes.MultiByteOpCodes[(int)code - 0xFE00]); }
private static int ResolveArithmethics(CilCode code, int a, int b) { return(code switch { CilCode.And => a & b, CilCode.Or => a | b, _ => a ^ b, });
public void InvalidPrimitiveOperandShouldThrow(CilCode code, object operand) { var stream = new MemoryStream(); var writer = new BinaryStreamWriter(stream); var assembler = new CilAssembler(writer, new MockOperandBuilder()); Assert.ThrowsAny <ArgumentException>(() => assembler.WriteInstruction(new CilInstruction(code.ToOpCode(), operand))); }
private CilOpCode GetOpCode(CilCode opcode) { return(opcode switch { CilCode.Stsfld => CilOpCodes.Stloc, CilCode.Ldsfld => CilOpCodes.Ldloc, CilCode.Ldsflda => CilOpCodes.Ldloca, _ => CilOpCodes.Nop });
public static CilOpCode GetOpCode(CilCode code) { var value = (int)code; if ((value & 0xFE00) == 0xFE00) { return(MultiByteOpCodes[value & 0xFF]); } return(SingleByteOpCodes[value & 0xFF]); }
public void FloatComparison(CilCode code, double a, double b, TrileanValue expected) { var stack = ExecutionContext.ProgramState.Stack; stack.Push(new FValue(a)); stack.Push(new FValue(b)); var result = Dispatcher.Execute(ExecutionContext, new CilInstruction(code.ToOpCode())); Assert.True(result.IsSuccess); Assert.Equal(expected, ((I4Value)stack.Top).IsNonZero); }
public void OptimizeFirst4ArgumentsToMacros(int index, CilCode expectedMacro) { var instructions = CreateDummyMethod(false, 4, 0); instructions.Add(CilOpCodes.Ldarg, instructions.Owner.Owner.Parameters[index]); instructions.Add(CilOpCodes.Ret); instructions.OptimizeMacros(); Assert.Equal(expectedMacro.ToOpCode(), instructions[0].OpCode); Assert.Null(instructions[0].Operand); }
public void I4Comparison(CilCode code, int a, int b, bool expectedToTakeBranch) { var instruction = new CilInstruction(code.ToOpCode(), new CilOffsetLabel(0x1234)); int expectedOffset = expectedToTakeBranch ? 0x1234 : instruction.Offset + instruction.Size; var stack = ExecutionContext.ProgramState.Stack; stack.Push(new I4Value(a)); stack.Push(new I4Value(b)); var result = Dispatcher.Execute(ExecutionContext, instruction); Assert.True(result.IsSuccess); Assert.Equal(0, stack.Size); Assert.Equal(expectedOffset, ExecutionContext.ProgramState.ProgramCounter); }
private static CilOpCode GetOpCode(CilCode opcode) { switch (opcode) { case CilCode.Stsfld: return(CilOpCodes.Stloc); case CilCode.Ldsfld: return(CilOpCodes.Ldloc); case CilCode.Ldsflda: return(CilOpCodes.Ldloca); } return(CilOpCodes.Nop); }
public void ConvertI4OnStackToInt64(CilCode code, int value, long?expected) { var stack = ExecutionContext.ProgramState.Stack; stack.Push(new I4Value(value)); var result = Dispatcher.Execute(ExecutionContext, new CilInstruction(code.ToOpCode())); Assert.Equal(expected.HasValue, result.IsSuccess); if (expected.HasValue) { Assert.Equal(new I8Value(expected.Value), stack.Top); } else { Assert.IsAssignableFrom <OverflowException>(result.Exception); } }
public void LdelemOnInt32ArrayShouldTruncateAndSignExtendWhenNecessary(CilCode code, int arrayElementValue, int expectedValue) { var environment = ExecutionContext.GetService <ICilRuntimeEnvironment>(); var marshaller = environment.CliMarshaller; var array = environment.ValueFactory.AllocateArray(environment.Module.CorLibTypeFactory.Int32, 1); array.StoreElementI4(0, new I4Value(arrayElementValue), marshaller); var stack = ExecutionContext.ProgramState.Stack; stack.Push(marshaller.ToCliValue(array, array.Type)); stack.Push(new I4Value(0)); var result = Dispatcher.Execute(ExecutionContext, new CilInstruction(code.ToOpCode())); Assert.True(result.IsSuccess, $"Unexpected {result.Exception?.GetType()}: {result.Exception?.Message}"); Assert.Equal(new I4Value(expectedValue), stack.Top); }
public void ArithmeticShouldBePure(CilCode code) { var instruction = new CilInstruction(code.ToOpCode()); Assert.Equal(Trilean.True, _classifier.IsPure(instruction)); }
public void PushingConstantsShouldBePure(CilCode code, object operand) { var instruction = new CilInstruction(code.ToOpCode(), operand); Assert.Equal(Trilean.True, _classifier.IsPure(instruction)); }