/// <inheritdoc /> public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); var variables = new IVariable[1]; if (environment.Architecture.GetReadVariables(instruction, variables) != 1) { throw new DispatchException( $"Architecture returned an incorrect number of variables being read from instruction {instruction}."); } switch (variables[0]) { case CilParameter parameter: var value = environment.CliMarshaller.ToCliValue( context.ProgramState.Variables[variables[0]], parameter.Parameter.ParameterType); context.ProgramState.Stack.Push(value); return(base.Execute(context, instruction)); default: return(DispatchResult.InvalidProgram()); } }
/// <inheritdoc /> public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction) { var stack = context.ProgramState.Stack; // Pop arguments. var lengthValue = (ICliValue)stack.Pop(); var sourceAddress = (ICliValue)stack.Pop(); var destinationAddress = (ICliValue)stack.Pop(); // Interpret arguments. if (!(destinationAddress is IPointerValue destinationPointer) || !(sourceAddress is IPointerValue sourcePointer)) { return(DispatchResult.InvalidProgram()); } if (!lengthValue.IsKnown) { throw new DispatchException("Number of bytes to copy is unknown."); } int length = lengthValue.InterpretAsI4().I32; // Copy data. Span <byte> data = stackalloc byte[length]; Span <byte> bitmask = stackalloc byte[length]; sourcePointer.ReadBytes(0, data, bitmask); destinationPointer.WriteBytes(0, data, bitmask); return(base.Execute(context, instruction)); }
/// <inheritdoc /> public DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); // If the containing method is expected to return a value, the stack should contain exactly one value, // and no values otherwise. int popCount = environment.Architecture.GetStackPopCount(instruction); if (context.ProgramState.Stack.Size != popCount) { return(DispatchResult.InvalidProgram()); } // Pop result. if (popCount == 1) { context.Result.ReturnValue = context.ProgramState.Stack.Pop(); } return(new DispatchResult { HasTerminated = true }); }
/// <inheritdoc /> public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); var variables = new IVariable[1]; if (environment.Architecture.GetWrittenVariables(instruction, variables) != 1) { throw new DispatchException( $"Architecture returned an incorrect number of variables being written by instruction {instruction}."); } switch (variables[0]) { case CilVariable cilVariable: var value = environment.CliMarshaller.ToCtsValue( (ICliValue)context.ProgramState.Stack.Pop(), cilVariable.Variable.VariableType); context.ProgramState.Variables[variables[0]] = value; return(base.Execute(context, instruction)); default: return(DispatchResult.InvalidProgram()); } }
/// <inheritdoc /> public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction) { var stack = context.ProgramState.Stack; // Pop arguments. var valueValue = (ICliValue)stack.Pop(); var indexValue = (ICliValue)stack.Pop(); var arrayValue = (ICliValue)stack.Pop(); // Check if both array and index are known. if (!arrayValue.IsKnown) { throw new DispatchException($"Destination array value for instruction at offset IL_{instruction.Offset:X4} is unknown."); } if (!indexValue.IsKnown) { throw new DispatchException($"Index for instruction at offset IL_{instruction.Offset:X4} is unknown."); } // Expect an int32 or a native int for index, and extract its value. if (indexValue.CliValueType != CliValueType.Int32 && indexValue.CliValueType != CliValueType.NativeInt) { return(DispatchResult.InvalidProgram()); } int index = indexValue.InterpretAsI4().I32; // Expect an O value with a .NET array in it. switch (arrayValue) { case OValue { IsZero: { Value : TrileanValue.True } } : // Pushed array object is null. return(new DispatchResult(new NullReferenceException()));
/// <inheritdoc /> public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); var factory = environment.Module.CorLibTypeFactory; var stack = context.ProgramState.Stack; var valueValue = stack.Pop(); var pointerValue = (IPointerValue)stack.Pop(); var marshaller = environment.CliMarshaller; switch (instruction.OpCode.Code) { case CilCode.Stind_I: if (pointerValue.Is32Bit) { pointerValue.WriteInteger32(0, valueValue.InterpretAsI4()); } else { pointerValue.WriteInteger64(0, valueValue.InterpretAsI8()); } break; case CilCode.Stind_I1: pointerValue.WriteInteger8(0, (Integer8Value)marshaller.ToCtsValue(valueValue.InterpretAsI1(), factory.SByte)); break; case CilCode.Stind_I2: pointerValue.WriteInteger16(0, (Integer16Value)marshaller.ToCtsValue(valueValue.InterpretAsI2(), factory.Int16)); break; case CilCode.Stind_I4: pointerValue.WriteInteger32(0, (Integer32Value)marshaller.ToCtsValue(valueValue.InterpretAsI4(), factory.Int32)); break; case CilCode.Stind_I8: pointerValue.WriteInteger64(0, (Integer64Value)marshaller.ToCtsValue(valueValue.InterpretAsI8(), factory.Int64)); break; case CilCode.Stind_R4: pointerValue.WriteFloat32(0, (Float32Value)marshaller.ToCtsValue(valueValue.InterpretAsR4(), factory.Single)); break; case CilCode.Stind_R8: pointerValue.WriteFloat64(0, (Float64Value)marshaller.ToCtsValue(valueValue.InterpretAsR8(), factory.Double)); break; default: return(DispatchResult.InvalidProgram()); } return(base.Execute(context, instruction)); }
/// <inheritdoc /> public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var stack = context.ProgramState.Stack; // Pop arguments. var indexValue = stack.Pop(); var arrayValue = stack.Pop(); // Check if both array and index are known. if (!arrayValue.IsKnown || !indexValue.IsKnown) { stack.Push(GetUnknownElementValue(context, instruction)); return(base.Execute(context, instruction)); } // Expect an int32 or a native int for index, and extract its value. if (indexValue.CliValueType != CliValueType.Int32 && indexValue.CliValueType != CliValueType.NativeInt) { return(DispatchResult.InvalidProgram()); } int index = indexValue.InterpretAsI4().I32; // Obtain element. ICliValue elementValue; switch (arrayValue) { case OValue { IsZero: { Value : TrileanValue.True } } : // Pushed array object is null. return(new DispatchResult(new NullReferenceException()));
/// <inheritdoc /> public DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var(left, right) = BinaryOperationHelper.PopBinaryOperationArguments(context); var result = (left, right) switch { (IntegerValue a, IntegerValue b) => Execute(context, instruction, a, b), (FValue a, FValue b) => Execute(context, instruction, a, b), (OValue a, OValue b) => Execute(context, instruction, a, b), _ => DispatchResult.InvalidProgram(), };
/// <inheritdoc /> public DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var argument = context.ProgramState.Stack.Pop(); var result = argument switch { FValue float64Value => Execute(context, float64Value), IntegerValue integerValue => Execute(context, integerValue), _ => DispatchResult.InvalidProgram() }; if (result.IsSuccess) { context.ProgramState.ProgramCounter += instruction.Size; } return(result); }
/// <inheritdoc /> public DispatchResult Execute(ExecutionContext context, CilInstruction instruction) { var(left, right) = PopArguments(context); var result = (left, right) switch { (IntegerValue value, int shiftCount) => Execute(context, instruction, value, shiftCount), (IntegerValue value, null) => ExecuteDefault(context, value, left), _ => DispatchResult.InvalidProgram() }; if (result.IsSuccess) { context.ProgramState.ProgramCounter += instruction.Size; } return(result); }
/// <inheritdoc /> public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); var stack = context.ProgramState.Stack; var sizeValue = (ICliValue)stack.Pop(); if (!sizeValue.IsKnown) { return(DispatchResult.InvalidProgram()); } int size = sizeValue.InterpretAsI4().I32; var memoryValue = environment.ValueFactory.AllocateMemory(size, true); stack.Push(environment.CliMarshaller.ToCliValue(memoryValue, new PointerTypeSignature(environment.Module.CorLibTypeFactory.Byte))); return(base.Execute(context, instruction)); }
/// <inheritdoc /> public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); var stack = context.ProgramState.Stack; var sizeValue = stack.Pop(); if (!sizeValue.IsKnown) { return(DispatchResult.InvalidProgram()); } var elementType = ((ITypeDefOrRef)instruction.Operand).ToTypeSignature(); int size = sizeValue.InterpretAsI4().I32; var array = environment.ValueFactory.AllocateArray(elementType, size); stack.Push(environment.CliMarshaller.ToCliValue(array, new SzArrayTypeSignature(elementType))); return(base.Execute(context, instruction)); }
/// <inheritdoc /> public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); var stack = context.ProgramState.Stack; // Pop address to dereference. var elementValue = stack.Pop(); var addressValue = stack.Pop(); if (!(addressValue is IPointerValue pointerValue)) { return(DispatchResult.InvalidProgram()); } // Determine type layout. var type = ((ITypeDefOrRef)instruction.Operand).ToTypeSignature(); var memoryLayout = environment.ValueFactory.GetTypeMemoryLayout(type); // Write pointerValue.WriteStruct(0, environment.ValueFactory, memoryLayout, elementValue); return(DispatchResult.Success()); }
/// <inheritdoc /> public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction) { var stack = context.ProgramState.Stack; // Pop arguments. var lengthValue = stack.Pop(); var initValue = stack.Pop(); var address = stack.Pop(); // Interpret arguments. if (!(address is IPointerValue pointerValue)) { return(DispatchResult.InvalidProgram()); } if (!lengthValue.IsKnown) { throw new DispatchException("Number of bytes to initialize is unknown."); } int length = lengthValue.InterpretAsI4().I32; var byteInitValue = initValue.InterpretAsU1(); // Prepare initialization data. Span <byte> data = stackalloc byte[length]; data.Fill((byte)(byteInitValue.U32 & 0xFF)); Span <byte> bitmask = stackalloc byte[length]; bitmask.Fill((byte)(byteInitValue.Mask & 0xFF)); // Write data. pointerValue.WriteBytes(0, data, bitmask); return(base.Execute(context, instruction)); }
/// <inheritdoc /> public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); var corLibTypeFactory = environment.Module.CorLibTypeFactory; var stack = context.ProgramState.Stack; var pointerValue = (IPointerValue)stack.Pop(); var(value, type) = instruction.OpCode.Code switch { CilCode.Ldind_I => (pointerValue.Is32Bit ? (IConcreteValue)pointerValue.ReadInteger32(0) : pointerValue.ReadInteger64(0), corLibTypeFactory.IntPtr), CilCode.Ldind_I1 => (pointerValue.ReadInteger8(0), corLibTypeFactory.SByte), CilCode.Ldind_I2 => (pointerValue.ReadInteger16(0), corLibTypeFactory.Int16), CilCode.Ldind_I4 => (pointerValue.ReadInteger32(0), corLibTypeFactory.Int32), CilCode.Ldind_I8 => (pointerValue.ReadInteger64(0), corLibTypeFactory.Int64), CilCode.Ldind_U1 => (pointerValue.ReadInteger8(0), corLibTypeFactory.Byte), CilCode.Ldind_U2 => (pointerValue.ReadInteger16(0), corLibTypeFactory.UInt16), CilCode.Ldind_U4 => (pointerValue.ReadInteger32(0), corLibTypeFactory.UInt32), CilCode.Ldind_R4 => (pointerValue.ReadFloat32(0), corLibTypeFactory.Single), CilCode.Ldind_R8 => (pointerValue.ReadFloat64(0), corLibTypeFactory.Double), _ => (null, null) }; if (value is null) { return(DispatchResult.InvalidProgram()); } var cliValue = environment.CliMarshaller.ToCliValue(value, type); stack.Push(cliValue); return(base.Execute(context, instruction)); }
/// <inheritdoc /> public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction) { var environment = context.GetService <ICilRuntimeEnvironment>(); var stack = context.ProgramState.Stack; // Pop address to dereference. var addressValue = stack.Pop(); if (!(addressValue is PointerValue pointerValue)) { return(DispatchResult.InvalidProgram()); } // Determine type layout. var type = ((ITypeDefOrRef)instruction.Operand).ToTypeSignature(); var memoryLayout = environment.MemoryAllocator.GetTypeMemoryLayout(type); // Dereference. var structureValue = pointerValue.ReadStruct(0, environment.MemoryAllocator, memoryLayout); stack.Push(environment.CliMarshaller.ToCliValue(structureValue, type)); return(DispatchResult.Success()); }
/// <inheritdoc /> protected override DispatchResult Execute(ExecutionContext context, CilInstruction instruction, OValue left, OValue right) { return DispatchResult.InvalidProgram(); }
/// <inheritdoc /> protected override DispatchResult Execute(ExecutionContext context, Float64Value value) => DispatchResult.InvalidProgram();