private ILExpression BuildExpression(ILInstruction instruction, ILCompilationUnit result) { IILArgumentsProvider expression; switch (instruction.OpCode.Code) { case ILCode.VCALL: expression = new ILVCallExpression((VCallAnnotation)instruction.Annotation); break; case ILCode.PUSHR_BYTE: case ILCode.PUSHR_WORD: case ILCode.PUSHR_DWORD: case ILCode.PUSHR_QWORD: case ILCode.PUSHR_OBJECT: expression = BuildPushrExpression(instruction, result); break; default: expression = new ILInstructionExpression(instruction); break; } for (int i = 0; i < instruction.Dependencies.Count; i++) { ILExpression argument; var firstDataSource = instruction.Dependencies[i].DataSources.First(); if (firstDataSource.Offset == InstructionProcessor.PushExceptionOffset) { var exceptionType = (ITypeDefOrRef)firstDataSource.Operand; argument = new ILExceptionExpression(exceptionType); } else { // Get the variable containing the value of the argument and add it as an argument to the expression. string variableName = GetOperandVariableName(instruction, i); if (_sharedVariables.TryGetValue(variableName, out string realName)) { variableName = realName; } argument = new ILVariableExpression( result.GetOrCreateVariable(variableName)); } expression.Arguments.Add(argument); } return((ILExpression)expression); }
private ILExpression BuildExpression(ILInstruction instruction, ILCompilationUnit result) { IILArgumentsProvider expression; switch (instruction.OpCode.Code) { case ILCode.VCALL: expression = new ILVCallExpression((VCallAnnotation)instruction.Annotation); break; case ILCode.PUSHR_BYTE: case ILCode.PUSHR_WORD: case ILCode.PUSHR_DWORD: case ILCode.PUSHR_QWORD: case ILCode.PUSHR_OBJECT: // Since we treat registers as variables, we should interpret the operand as a variable and add it // as an argument to the expression instead of keeping it just as an operand. This makes it easier // to apply analysis and transformations (such as variable inlining) later, in the same way we do // that with normal variables. expression = new ILInstructionExpression(instruction); ILVariable registerVar; if (instruction.Operand is VMRegisters.FL) { var dataSources = instruction.ProgramState.Registers[VMRegisters.FL].DataSources .Select(i => i.Offset) .ToArray(); var flagsVariable = result.GetOrCreateFlagsVariable(dataSources); registerVar = flagsVariable; } else { registerVar = result.GetOrCreateVariable(instruction.Operand.ToString()); } var varExpression = new ILVariableExpression(registerVar); expression.Arguments.Add(varExpression); break; default: expression = new ILInstructionExpression(instruction); break; } for (int i = 0; i < instruction.Dependencies.Count; i++) { ILExpression argument; var firstDataSource = instruction.Dependencies[i].DataSources.First(); if (firstDataSource.Offset == InstructionProcessor.PushExceptionOffset) { var exceptionType = (ITypeDefOrRef)firstDataSource.Operand; argument = new ILExceptionExpression(exceptionType); } else { // Get the variable containing the value of the argument and add it as an argument to the expression. string variableName = GetOperandVariableName(instruction, i); if (_sharedVariables.TryGetValue(variableName, out string realName)) { variableName = realName; } argument = new ILVariableExpression( result.GetOrCreateVariable(variableName)); } expression.Arguments.Add(argument); } return((ILExpression)expression); }