示例#1
0
        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);
        }
示例#2
0
        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);
        }