Пример #1
0
		private int ParseStatement (Collection<Instruction> instructions, int index, List<Statement> result, out bool isNewBlock)
		{
			Expression expression = null;
			Statement statement = null;
			isNewBlock = false;

			bool needToRepeat = true;
			while (index < instructions.Count) {
				Instruction inst = instructions [index++];
				Code opcode = inst.OpCode.Code;
				bool isStatement = false;
				switch (opcode) {
				case Code.Nop:
					statement = new Statement (NodeType.Nop);
					needToRepeat = false;
					break;
				case Code.Ldarg_0:
				case Code.Ldarg_1:
				case Code.Ldarg_2:
				case Code.Ldarg_3:
					expression = GetParameterExpression (opcode - Code.Ldarg_0);
					break;
				case Code.Ldarg_S:
					expression = GetParameterExpression ((int) inst.Operand);
					break;
				case Code.Ldloc_0:
				case Code.Ldloc_1:
				case Code.Ldloc_2:
				case Code.Ldloc_3:
					expression = GetLocalExpression (opcode - Code.Ldloc_0);
					break;
				case Code.Ldloc_S:
					expression = GetLocalExpression ((int) (inst.Operand));
					break;
				case Code.Stloc_0:
				case Code.Stloc_1:
				case Code.Stloc_2:
				case Code.Stloc_3:
					statement = new AssignmentStatement (PopOperand (), GetLocalExpression ((opcode - Code.Stloc_0)));
					needToRepeat = false;
					break;
				case Code.Stloc_S:
					statement = new AssignmentStatement (PopOperand (), GetLocalExpression ((VariableDefinition) (inst.Operand)));
					needToRepeat = false;
					break;
				case Code.Starg_S:
					statement = new AssignmentStatement (PopOperand (), GetParameterExpression ((int) (inst.Operand)));
					needToRepeat = false;
					break;
				case Code.Ldarga_S:
					throw new NotImplementedException ();
				case Code.Ldloca_S:
					throw new NotImplementedException ();
				case Code.Ldnull:
					expression = Literal.Null;
					break;
				case Code.Ldc_I4_M1:
				case Code.Ldc_I4_0:
				case Code.Ldc_I4_1:
				case Code.Ldc_I4_2:
				case Code.Ldc_I4_3:
				case Code.Ldc_I4_4:
				case Code.Ldc_I4_5:
				case Code.Ldc_I4_6:
				case Code.Ldc_I4_7:
				case Code.Ldc_I4_8:
					expression = GetLiteral ((opcode - Code.Ldc_I4_0), CoreSystemTypes.Instance.TypeInt32);
					break;
				case Code.Ldc_I8:
					expression = GetLiteral ((Int64) inst.Operand, CoreSystemTypes.Instance.TypeInt64);
					break;
				case Code.Ldc_I4_S:
					expression = GetLiteral ((int) (sbyte) inst.Operand, CoreSystemTypes.Instance.TypeInt32);
					break;
				case Code.Ldc_I4:
					expression = GetLiteral ((int) inst.Operand, CoreSystemTypes.Instance.TypeInt32);
					break;
				case Code.Ldc_R4:
					expression = GetLiteral ((float) inst.Operand, CoreSystemTypes.Instance.TypeSingle);
					break;
				case Code.Ldc_R8:
					expression = GetLiteral ((double) inst.Operand, CoreSystemTypes.Instance.TypeDouble);
					break;
				case Code.Ret:
					statement = new Return (TypeIsVoid (this.method.ReturnType) ? null : PopOperand ());
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Br_S:
					statement = ParseBranch (inst, NodeType.Nop, 0, true, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Brfalse_S:
					statement = ParseBranch (inst, NodeType.LogicalNot, 1, true, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Brtrue_S:
					statement = ParseBranch (inst, NodeType.Nop, 1, true, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Bne_Un_S:
					statement = ParseBranch (inst, NodeType.Ne, 2, true, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Bge_Un_S:
					statement = ParseBranch (inst, NodeType.Ge, 2, true, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Bgt_Un_S:
					statement = ParseBranch (inst, NodeType.Gt, 2, true, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Ble_S:
					statement = ParseBranch (inst, NodeType.Le, 2, true, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Blt_Un_S:
					statement = ParseBranch (inst, NodeType.Lt, 2, true, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Br:
					statement = ParseBranch (inst, NodeType.Nop, 0, false, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Brfalse:
					statement = ParseBranch (inst, NodeType.LogicalNot, 0, false, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Brtrue:
					statement = ParseBranch (inst, NodeType.Nop, 1, false, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Beq:
					statement = ParseBranch (inst, NodeType.Eq, 2, false, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Bge:
					statement = ParseBranch (inst, NodeType.Ge, 2, false, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Bgt:
					statement = ParseBranch (inst, NodeType.Gt, 2, false, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Ble:
					statement = ParseBranch (inst, NodeType.Le, 2, false, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Blt:
					statement = ParseBranch (inst, NodeType.Lt, 2, false, false);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Bne_Un:
					statement = ParseBranch (inst, NodeType.LogicalNot, 2, false, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Bge_Un:
					statement = ParseBranch (inst, NodeType.Ge, 2, false, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Bgt_Un:
					statement = ParseBranch (inst, NodeType.Gt, 2, false, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Ble_Un:
					statement = ParseBranch (inst, NodeType.Le, 2, false, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Blt_Un:
					statement = ParseBranch (inst, NodeType.Lt, 2, false, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Leave:
					statement = ParseBranch (inst, NodeType.Nop, 0, false, false, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Leave_S:
					statement = ParseBranch (inst, NodeType.Nop, 0, true, false, true);
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Endfinally:
					statement = new EndFinally ();
					isNewBlock = true;
					needToRepeat = false;
					break;
				case Code.Switch:
					break;
				case Code.Ldind_I1:
					break;
				case Code.Ldind_U1:
					break;
				case Code.Ldind_I2:
					break;
				case Code.Ldind_U2:
					break;
				case Code.Ldind_I4:
					break;
				case Code.Ldind_U4:
					break;
				case Code.Ldind_I8:
					break;
				case Code.Ldind_I:
					break;
				case Code.Ldind_R4:
					break;
				case Code.Ldind_R8:
					break;
				case Code.Ldind_Ref:
					break;
				case Code.Stind_Ref:
					break;
				case Code.Stind_I1:
					break;
				case Code.Stind_I2:
					break;
				case Code.Stind_I4:
					break;
				case Code.Stind_I8:
					break;
				case Code.Stind_R4:
					break;
				case Code.Stind_R8:
					break;
				case Code.Add:
					expression = ParseBinaryOperation (NodeType.Add);
					break;
				case Code.Sub:
					expression = ParseBinaryOperation (NodeType.Sub);
					break;
				case Code.Mul:
					expression = ParseBinaryOperation (NodeType.Mul);
					break;
				case Code.Div:
					expression = ParseBinaryOperation (NodeType.Div);
					break;
				case Code.Div_Un:
					expression = ParseBinaryOperation (NodeType.Div_Un);
					break;
				case Code.Rem:
					expression = ParseBinaryOperation (NodeType.Rem);
					break;
				case Code.Rem_Un:
					expression = ParseBinaryOperation (NodeType.Rem_Un);
					break;
				case Code.And:
					expression = ParseBinaryOperation (NodeType.And);
					break;
				case Code.Or:
					expression = ParseBinaryOperation (NodeType.Or);
					break;
				case Code.Xor:
					expression = ParseBinaryOperation (NodeType.Xor);
					break;
				case Code.Shl:
					expression = ParseBinaryOperation (NodeType.Shl);
					break;
				case Code.Shr:
					expression = ParseBinaryOperation (NodeType.Shr);
					break;
				case Code.Shr_Un:
					expression = ParseBinaryOperation (NodeType.Shr_Un);
					break;
				case Code.Neg:
					expression = ParseUnaryOperation (NodeType.Neg);
					break;
				case Code.Not:
					expression = ParseUnaryOperation (NodeType.Not);
					break;
				case Code.Conv_I1:
					expression = new UnaryExpression (NodeType.Conv_I1, PopOperand (), CoreSystemTypes.Instance.TypeSByte);
					break;
				case Code.Conv_I2:
					expression = new UnaryExpression (NodeType.Conv_I2, PopOperand (), CoreSystemTypes.Instance.TypeInt16);
					break;
				case Code.Conv_I4:
					expression = new UnaryExpression (NodeType.Conv_I4, PopOperand (), CoreSystemTypes.Instance.TypeInt32);
					break;
				case Code.Conv_I8:
					expression = new UnaryExpression (NodeType.Conv_I8, PopOperand (), CoreSystemTypes.Instance.TypeInt64);
					break;
				case Code.Conv_R4:
					expression = new UnaryExpression (NodeType.Conv_R4, PopOperand (), CoreSystemTypes.Instance.TypeSingle);
					break;
				case Code.Conv_R8:
					expression = new UnaryExpression (NodeType.Conv_R8, PopOperand (), CoreSystemTypes.Instance.TypeDouble);
					break;
				case Code.Conv_U4:
					expression = new UnaryExpression (NodeType.Conv_R8, PopOperand (), CoreSystemTypes.Instance.TypeUInt32);
					break;
				case Code.Conv_U8:
					expression = new UnaryExpression (NodeType.Conv_R8, PopOperand (), CoreSystemTypes.Instance.TypeUInt64);
					break;
				case Code.Call:
					expression = ParseCall (inst, NodeType.Call, out isStatement);
					if (isStatement)
						needToRepeat = false;
					break;
				case Code.Callvirt:
					expression = ParseCall (inst, NodeType.CallVirt, out isStatement);
					if (isStatement)
						needToRepeat = false;
					break;
				case Code.Cpobj:
					break;
				case Code.Ldobj:
					break;
				case Code.Ldstr:
					expression = GetLiteral (inst.Operand, CoreSystemTypes.Instance.TypeString);
					break;
				case Code.Newobj:
					expression = ParseNewObjectCreation (inst);
					break;
				case Code.Castclass:
					break;
				case Code.Isinst:
					break;
				case Code.Conv_R_Un:
					break;
				case Code.Unbox:
					break;
				case Code.Throw:
					isNewBlock = true;
					break;
				case Code.Ldfld:
					break;
				case Code.Ldflda:
					break;
				case Code.Stfld:
					break;
				case Code.Ldsfld:
					break;
				case Code.Ldsflda:
					break;
				case Code.Stsfld:
					break;
				case Code.Stobj:
					break;
				case Code.Conv_Ovf_I1_Un:
					break;
				case Code.Conv_Ovf_I2_Un:
					break;
				case Code.Conv_Ovf_I4_Un:
					break;
				case Code.Conv_Ovf_I8_Un:
					break;
				case Code.Conv_Ovf_U1_Un:
					break;
				case Code.Conv_Ovf_U2_Un:
					break;
				case Code.Conv_Ovf_U4_Un:
					break;
				case Code.Conv_Ovf_U8_Un:
					break;
				case Code.Conv_Ovf_I_Un:
					break;
				case Code.Conv_Ovf_U_Un:
					break;
				case Code.Box:
					break;
				case Code.Newarr:
					break;
				case Code.Ldlen:
					break;
				case Code.Ldelema:
					break;
				case Code.Ldelem_I1:
					break;
				case Code.Ldelem_U1:
					break;
				case Code.Ldelem_I2:
					break;
				case Code.Ldelem_U2:
					break;
				case Code.Ldelem_I4:
					break;
				case Code.Ldelem_U4:
					break;
				case Code.Ldelem_I8:
					break;
				case Code.Ldelem_I:
					break;
				case Code.Ldelem_R4:
					break;
				case Code.Ldelem_R8:
					break;
				case Code.Ldelem_Ref:
					break;
				case Code.Stelem_I:
					break;
				case Code.Stelem_I1:
					break;
				case Code.Stelem_I2:
					break;
				case Code.Stelem_I4:
					break;
				case Code.Stelem_I8:
					break;
				case Code.Stelem_R4:
					break;
				case Code.Stelem_R8:
					break;
				case Code.Stelem_Ref:
					break;
				case Code.Ldelem_Any:
					break;
				case Code.Stelem_Any:
					break;
				case Code.Unbox_Any:
					break;
				case Code.Conv_Ovf_I1:
					break;
				case Code.Conv_Ovf_U1:
					break;
				case Code.Conv_Ovf_I2:
					break;
				case Code.Conv_Ovf_U2:
					break;
				case Code.Conv_Ovf_I4:
					break;
				case Code.Conv_Ovf_U4:
					break;
				case Code.Conv_Ovf_I8:
					break;
				case Code.Conv_Ovf_U8:
					break;
				case Code.Refanyval:
					break;
				case Code.Ckfinite:
					break;
				case Code.Mkrefany:
					break;
				case Code.Ldtoken:
					break;
				case Code.Conv_U2:
					break;
				case Code.Conv_U1:
					break;
				case Code.Conv_I:
					break;
				case Code.Conv_Ovf_I:
					break;
				case Code.Conv_Ovf_U:
					break;
				case Code.Add_Ovf:
					break;
				case Code.Add_Ovf_Un:
					break;
				case Code.Mul_Ovf:
					break;
				case Code.Mul_Ovf_Un:
					break;
				case Code.Sub_Ovf:
					break;
				case Code.Sub_Ovf_Un:
					break;

				case Code.Stind_I:
					break;
				case Code.Conv_U:
					break;
				case Code.Arglist:
					break;
				case Code.Ceq:
					expression = ParseBinaryComparison (NodeType.Ceq);
					break;
				case Code.Cgt:
					expression = ParseBinaryComparison (NodeType.Cgt);
					break;
				case Code.Cgt_Un:
					break;
				case Code.Clt:
					expression = ParseBinaryComparison (NodeType.Clt);
					break;
				case Code.Clt_Un:
					break;
				case Code.Ldftn:
					break;
				case Code.Ldvirtftn:
					break;
				case Code.Ldarg:
					break;
				case Code.Ldarga:
					break;
				case Code.Starg:
					break;
				case Code.Ldloc:
					break;
				case Code.Ldloca:
					break;
				case Code.Stloc:
					break;
				case Code.Localloc:
					break;
				case Code.Endfilter:
					isNewBlock = true;
					break;
				case Code.Unaligned:
					break;
				case Code.Volatile:
					break;
				case Code.Tail:
					break;
				case Code.Initobj:
					break;
				case Code.Constrained:
					break;
				case Code.Cpblk:
					break;
				case Code.Initblk:
					break;
				case Code.No:
					break;
				case Code.Rethrow:
					isNewBlock = true;
					break;
				case Code.Sizeof:
					break;
				case Code.Refanytype:
					break;
				case Code.Readonly:
					break;
				default:
					needToRepeat = false;
					break;
				}
				if (!needToRepeat)
					break;

				int offset = inst.Next == null ? inst.Offset + 1 : inst.Next.Offset;
				if (!this.block_map.ContainsKey (offset))
					this.evaluation_stack.Push (expression);
				else {
					isNewBlock = true;
					break;
				}
			}


			while (this.evaluation_stack.Count > 0) {
				Statement stmt = new ExpressionStatement (this.evaluation_stack.Pop ());
				result.Add (stmt);
			}

			if (statement == null)
				statement = new ExpressionStatement (expression);

			result.Add (statement);
			if (!isNewBlock)
				isNewBlock = this.block_map.ContainsKey (instructions [index].Offset);

			return index;
		}
Пример #2
0
        private int ParseStatement(Collection <Instruction> instructions, int index, List <Statement> result, out bool isNewBlock)
        {
            Expression expression = null;
            Statement  statement  = null;

            isNewBlock = false;

            bool needToRepeat = true;

            while (index < instructions.Count)
            {
                Instruction inst        = instructions [index++];
                Code        opcode      = inst.OpCode.Code;
                bool        isStatement = false;
                switch (opcode)
                {
                case Code.Nop:
                    statement    = new Statement(NodeType.Nop);
                    needToRepeat = false;
                    break;

                case Code.Ldarg_0:
                case Code.Ldarg_1:
                case Code.Ldarg_2:
                case Code.Ldarg_3:
                    expression = GetParameterExpression(opcode - Code.Ldarg_0);
                    break;

                case Code.Ldarg_S:
                    expression = GetParameterExpression((int)inst.Operand);
                    break;

                case Code.Ldloc_0:
                case Code.Ldloc_1:
                case Code.Ldloc_2:
                case Code.Ldloc_3:
                    expression = GetLocalExpression(opcode - Code.Ldloc_0);
                    break;

                case Code.Ldloc_S:
                    expression = GetLocalExpression((int)(inst.Operand));
                    break;

                case Code.Stloc_0:
                case Code.Stloc_1:
                case Code.Stloc_2:
                case Code.Stloc_3:
                    statement    = new AssignmentStatement(PopOperand(), GetLocalExpression((opcode - Code.Stloc_0)));
                    needToRepeat = false;
                    break;

                case Code.Stloc_S:
                    statement    = new AssignmentStatement(PopOperand(), GetLocalExpression((VariableDefinition)(inst.Operand)));
                    needToRepeat = false;
                    break;

                case Code.Starg_S:
                    statement    = new AssignmentStatement(PopOperand(), GetParameterExpression((int)(inst.Operand)));
                    needToRepeat = false;
                    break;

                case Code.Ldarga_S:
                    throw new NotImplementedException();

                case Code.Ldloca_S:
                    throw new NotImplementedException();

                case Code.Ldnull:
                    expression = Literal.Null;
                    break;

                case Code.Ldc_I4_M1:
                case Code.Ldc_I4_0:
                case Code.Ldc_I4_1:
                case Code.Ldc_I4_2:
                case Code.Ldc_I4_3:
                case Code.Ldc_I4_4:
                case Code.Ldc_I4_5:
                case Code.Ldc_I4_6:
                case Code.Ldc_I4_7:
                case Code.Ldc_I4_8:
                    expression = GetLiteral((opcode - Code.Ldc_I4_0), CoreSystemTypes.Instance.TypeInt32);
                    break;

                case Code.Ldc_I8:
                    expression = GetLiteral((Int64)inst.Operand, CoreSystemTypes.Instance.TypeInt64);
                    break;

                case Code.Ldc_I4_S:
                    expression = GetLiteral((int)(sbyte)inst.Operand, CoreSystemTypes.Instance.TypeInt32);
                    break;

                case Code.Ldc_I4:
                    expression = GetLiteral((int)inst.Operand, CoreSystemTypes.Instance.TypeInt32);
                    break;

                case Code.Ldc_R4:
                    expression = GetLiteral((float)inst.Operand, CoreSystemTypes.Instance.TypeSingle);
                    break;

                case Code.Ldc_R8:
                    expression = GetLiteral((double)inst.Operand, CoreSystemTypes.Instance.TypeDouble);
                    break;

                case Code.Ret:
                    statement    = new Return(TypeIsVoid(this.method.ReturnType) ? null : PopOperand());
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Br_S:
                    statement    = ParseBranch(inst, NodeType.Nop, 0, true, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Brfalse_S:
                    statement    = ParseBranch(inst, NodeType.LogicalNot, 1, true, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Brtrue_S:
                    statement    = ParseBranch(inst, NodeType.Nop, 1, true, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Bne_Un_S:
                    statement    = ParseBranch(inst, NodeType.Ne, 2, true, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Bge_Un_S:
                    statement    = ParseBranch(inst, NodeType.Ge, 2, true, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Bgt_Un_S:
                    statement    = ParseBranch(inst, NodeType.Gt, 2, true, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Ble_S:
                    statement    = ParseBranch(inst, NodeType.Le, 2, true, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Blt_Un_S:
                    statement    = ParseBranch(inst, NodeType.Lt, 2, true, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Br:
                    statement    = ParseBranch(inst, NodeType.Nop, 0, false, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Brfalse:
                    statement    = ParseBranch(inst, NodeType.LogicalNot, 0, false, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Brtrue:
                    statement    = ParseBranch(inst, NodeType.Nop, 1, false, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Beq:
                    statement    = ParseBranch(inst, NodeType.Eq, 2, false, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Bge:
                    statement    = ParseBranch(inst, NodeType.Ge, 2, false, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Bgt:
                    statement    = ParseBranch(inst, NodeType.Gt, 2, false, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Ble:
                    statement    = ParseBranch(inst, NodeType.Le, 2, false, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Blt:
                    statement    = ParseBranch(inst, NodeType.Lt, 2, false, false);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Bne_Un:
                    statement    = ParseBranch(inst, NodeType.LogicalNot, 2, false, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Bge_Un:
                    statement    = ParseBranch(inst, NodeType.Ge, 2, false, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Bgt_Un:
                    statement    = ParseBranch(inst, NodeType.Gt, 2, false, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Ble_Un:
                    statement    = ParseBranch(inst, NodeType.Le, 2, false, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Blt_Un:
                    statement    = ParseBranch(inst, NodeType.Lt, 2, false, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Leave:
                    statement    = ParseBranch(inst, NodeType.Nop, 0, false, false, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Leave_S:
                    statement    = ParseBranch(inst, NodeType.Nop, 0, true, false, true);
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Endfinally:
                    statement    = new EndFinally();
                    isNewBlock   = true;
                    needToRepeat = false;
                    break;

                case Code.Switch:
                    break;

                case Code.Ldind_I1:
                    break;

                case Code.Ldind_U1:
                    break;

                case Code.Ldind_I2:
                    break;

                case Code.Ldind_U2:
                    break;

                case Code.Ldind_I4:
                    break;

                case Code.Ldind_U4:
                    break;

                case Code.Ldind_I8:
                    break;

                case Code.Ldind_I:
                    break;

                case Code.Ldind_R4:
                    break;

                case Code.Ldind_R8:
                    break;

                case Code.Ldind_Ref:
                    break;

                case Code.Stind_Ref:
                    break;

                case Code.Stind_I1:
                    break;

                case Code.Stind_I2:
                    break;

                case Code.Stind_I4:
                    break;

                case Code.Stind_I8:
                    break;

                case Code.Stind_R4:
                    break;

                case Code.Stind_R8:
                    break;

                case Code.Add:
                    expression = ParseBinaryOperation(NodeType.Add);
                    break;

                case Code.Sub:
                    expression = ParseBinaryOperation(NodeType.Sub);
                    break;

                case Code.Mul:
                    expression = ParseBinaryOperation(NodeType.Mul);
                    break;

                case Code.Div:
                    expression = ParseBinaryOperation(NodeType.Div);
                    break;

                case Code.Div_Un:
                    expression = ParseBinaryOperation(NodeType.Div_Un);
                    break;

                case Code.Rem:
                    expression = ParseBinaryOperation(NodeType.Rem);
                    break;

                case Code.Rem_Un:
                    expression = ParseBinaryOperation(NodeType.Rem_Un);
                    break;

                case Code.And:
                    expression = ParseBinaryOperation(NodeType.And);
                    break;

                case Code.Or:
                    expression = ParseBinaryOperation(NodeType.Or);
                    break;

                case Code.Xor:
                    expression = ParseBinaryOperation(NodeType.Xor);
                    break;

                case Code.Shl:
                    expression = ParseBinaryOperation(NodeType.Shl);
                    break;

                case Code.Shr:
                    expression = ParseBinaryOperation(NodeType.Shr);
                    break;

                case Code.Shr_Un:
                    expression = ParseBinaryOperation(NodeType.Shr_Un);
                    break;

                case Code.Neg:
                    expression = ParseUnaryOperation(NodeType.Neg);
                    break;

                case Code.Not:
                    expression = ParseUnaryOperation(NodeType.Not);
                    break;

                case Code.Conv_I1:
                    expression = new UnaryExpression(NodeType.Conv_I1, PopOperand(), CoreSystemTypes.Instance.TypeSByte);
                    break;

                case Code.Conv_I2:
                    expression = new UnaryExpression(NodeType.Conv_I2, PopOperand(), CoreSystemTypes.Instance.TypeInt16);
                    break;

                case Code.Conv_I4:
                    expression = new UnaryExpression(NodeType.Conv_I4, PopOperand(), CoreSystemTypes.Instance.TypeInt32);
                    break;

                case Code.Conv_I8:
                    expression = new UnaryExpression(NodeType.Conv_I8, PopOperand(), CoreSystemTypes.Instance.TypeInt64);
                    break;

                case Code.Conv_R4:
                    expression = new UnaryExpression(NodeType.Conv_R4, PopOperand(), CoreSystemTypes.Instance.TypeSingle);
                    break;

                case Code.Conv_R8:
                    expression = new UnaryExpression(NodeType.Conv_R8, PopOperand(), CoreSystemTypes.Instance.TypeDouble);
                    break;

                case Code.Conv_U4:
                    expression = new UnaryExpression(NodeType.Conv_R8, PopOperand(), CoreSystemTypes.Instance.TypeUInt32);
                    break;

                case Code.Conv_U8:
                    expression = new UnaryExpression(NodeType.Conv_R8, PopOperand(), CoreSystemTypes.Instance.TypeUInt64);
                    break;

                case Code.Call:
                    expression = ParseCall(inst, NodeType.Call, out isStatement);
                    if (isStatement)
                    {
                        needToRepeat = false;
                    }
                    break;

                case Code.Callvirt:
                    expression = ParseCall(inst, NodeType.CallVirt, out isStatement);
                    if (isStatement)
                    {
                        needToRepeat = false;
                    }
                    break;

                case Code.Cpobj:
                    break;

                case Code.Ldobj:
                    break;

                case Code.Ldstr:
                    expression = GetLiteral(inst.Operand, CoreSystemTypes.Instance.TypeString);
                    break;

                case Code.Newobj:
                    expression = ParseNewObjectCreation(inst);
                    break;

                case Code.Castclass:
                    break;

                case Code.Isinst:
                    break;

                case Code.Conv_R_Un:
                    break;

                case Code.Unbox:
                    break;

                case Code.Throw:
                    isNewBlock = true;
                    break;

                case Code.Ldfld:
                    break;

                case Code.Ldflda:
                    break;

                case Code.Stfld:
                    break;

                case Code.Ldsfld:
                    break;

                case Code.Ldsflda:
                    break;

                case Code.Stsfld:
                    break;

                case Code.Stobj:
                    break;

                case Code.Conv_Ovf_I1_Un:
                    break;

                case Code.Conv_Ovf_I2_Un:
                    break;

                case Code.Conv_Ovf_I4_Un:
                    break;

                case Code.Conv_Ovf_I8_Un:
                    break;

                case Code.Conv_Ovf_U1_Un:
                    break;

                case Code.Conv_Ovf_U2_Un:
                    break;

                case Code.Conv_Ovf_U4_Un:
                    break;

                case Code.Conv_Ovf_U8_Un:
                    break;

                case Code.Conv_Ovf_I_Un:
                    break;

                case Code.Conv_Ovf_U_Un:
                    break;

                case Code.Box:
                    break;

                case Code.Newarr:
                    break;

                case Code.Ldlen:
                    break;

                case Code.Ldelema:
                    break;

                case Code.Ldelem_I1:
                    break;

                case Code.Ldelem_U1:
                    break;

                case Code.Ldelem_I2:
                    break;

                case Code.Ldelem_U2:
                    break;

                case Code.Ldelem_I4:
                    break;

                case Code.Ldelem_U4:
                    break;

                case Code.Ldelem_I8:
                    break;

                case Code.Ldelem_I:
                    break;

                case Code.Ldelem_R4:
                    break;

                case Code.Ldelem_R8:
                    break;

                case Code.Ldelem_Ref:
                    break;

                case Code.Stelem_I:
                    break;

                case Code.Stelem_I1:
                    break;

                case Code.Stelem_I2:
                    break;

                case Code.Stelem_I4:
                    break;

                case Code.Stelem_I8:
                    break;

                case Code.Stelem_R4:
                    break;

                case Code.Stelem_R8:
                    break;

                case Code.Stelem_Ref:
                    break;

                case Code.Ldelem_Any:
                    break;

                case Code.Stelem_Any:
                    break;

                case Code.Unbox_Any:
                    break;

                case Code.Conv_Ovf_I1:
                    break;

                case Code.Conv_Ovf_U1:
                    break;

                case Code.Conv_Ovf_I2:
                    break;

                case Code.Conv_Ovf_U2:
                    break;

                case Code.Conv_Ovf_I4:
                    break;

                case Code.Conv_Ovf_U4:
                    break;

                case Code.Conv_Ovf_I8:
                    break;

                case Code.Conv_Ovf_U8:
                    break;

                case Code.Refanyval:
                    break;

                case Code.Ckfinite:
                    break;

                case Code.Mkrefany:
                    break;

                case Code.Ldtoken:
                    break;

                case Code.Conv_U2:
                    break;

                case Code.Conv_U1:
                    break;

                case Code.Conv_I:
                    break;

                case Code.Conv_Ovf_I:
                    break;

                case Code.Conv_Ovf_U:
                    break;

                case Code.Add_Ovf:
                    break;

                case Code.Add_Ovf_Un:
                    break;

                case Code.Mul_Ovf:
                    break;

                case Code.Mul_Ovf_Un:
                    break;

                case Code.Sub_Ovf:
                    break;

                case Code.Sub_Ovf_Un:
                    break;

                case Code.Stind_I:
                    break;

                case Code.Conv_U:
                    break;

                case Code.Arglist:
                    break;

                case Code.Ceq:
                    expression = ParseBinaryComparison(NodeType.Ceq);
                    break;

                case Code.Cgt:
                    expression = ParseBinaryComparison(NodeType.Cgt);
                    break;

                case Code.Cgt_Un:
                    break;

                case Code.Clt:
                    expression = ParseBinaryComparison(NodeType.Clt);
                    break;

                case Code.Clt_Un:
                    break;

                case Code.Ldftn:
                    break;

                case Code.Ldvirtftn:
                    break;

                case Code.Ldarg:
                    break;

                case Code.Ldarga:
                    break;

                case Code.Starg:
                    break;

                case Code.Ldloc:
                    break;

                case Code.Ldloca:
                    break;

                case Code.Stloc:
                    break;

                case Code.Localloc:
                    break;

                case Code.Endfilter:
                    isNewBlock = true;
                    break;

                case Code.Unaligned:
                    break;

                case Code.Volatile:
                    break;

                case Code.Tail:
                    break;

                case Code.Initobj:
                    break;

                case Code.Constrained:
                    break;

                case Code.Cpblk:
                    break;

                case Code.Initblk:
                    break;

                case Code.No:
                    break;

                case Code.Rethrow:
                    isNewBlock = true;
                    break;

                case Code.Sizeof:
                    break;

                case Code.Refanytype:
                    break;

                case Code.Readonly:
                    break;

                default:
                    needToRepeat = false;
                    break;
                }
                if (!needToRepeat)
                {
                    break;
                }

                int offset = inst.Next == null ? inst.Offset + 1 : inst.Next.Offset;
                if (!this.block_map.ContainsKey(offset))
                {
                    this.evaluation_stack.Push(expression);
                }
                else
                {
                    isNewBlock = true;
                    break;
                }
            }


            while (this.evaluation_stack.Count > 0)
            {
                Statement stmt = new ExpressionStatement(this.evaluation_stack.Pop());
                result.Add(stmt);
            }

            if (statement == null)
            {
                statement = new ExpressionStatement(expression);
            }

            result.Add(statement);
            if (!isNewBlock)
            {
                isNewBlock = this.block_map.ContainsKey(instructions [index].Offset);
            }

            return(index);
        }
Пример #3
0
		public override void VisitAssignmentStatement (AssignmentStatement node)
		{
			if (node.Target is Local && IsResultExpression (node.Source))
				this.exempt_result_local = (Local) node.Target;
			base.VisitAssignmentStatement (node);
		}