private void ValidateInstruction(CilInstructionExpression expression, CilInstruction instruction) { switch (instruction.OpCode.OperandType) { case CilOperandType.ShortInlineBrTarget: case CilOperandType.InlineBrTarget: if (!(instruction.Operand is CilInstruction)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a branch target operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineMethod: case CilOperandType.InlineField: case CilOperandType.InlineType: case CilOperandType.InlineTok: if (!(instruction.Operand is IMemberReference)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a member reference operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineSig: if (!(instruction.Operand is StandAloneSignature)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a signature operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineI: if (!(instruction.Operand is int)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected an int32 operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineI8: if (!(instruction.Operand is long)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected an int64 operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineNone: if (instruction.Operand != null) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Unexpected operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineR: if (!(instruction.Operand is double)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a float64 operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.ShortInlineI: if (!(instruction.Operand is sbyte)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected an int8 operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.ShortInlineR: if (!(instruction.Operand is float)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a float32 operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineString: if (!(instruction.Operand is string)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a string operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineSwitch: if (!(instruction.Operand is IList <CilInstruction>)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a switch table operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.ShortInlineVar: case CilOperandType.InlineVar: if (!(instruction.Operand is VariableSignature)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a variable operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; case CilOperandType.InlineArgument: case CilOperandType.ShortInlineArgument: if (!(instruction.Operand is ParameterSignature)) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Expected a parameter operand in '{expression.AcceptVisitor(_formatter)}'.")); } break; default: throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Unexpected opcode in '{expression.AcceptVisitor(_formatter)}'.")); } }
private void ValidateExpression(CilInstructionExpression expression) { int stackSize = expression.Arguments.Count; foreach (var instruction in expression.Instructions) { stackSize += instruction.GetStackPopCount(_context.MethodBody); if (stackSize < 0) { throw new CilCodeGeneratorException(InvalidAstMessage, new ArgumentException( $"Insufficient arguments are pushed onto the stack'{expression.AcceptVisitor(_formatter)}'.")); } stackSize += instruction.GetStackPushCount(_context.MethodBody); ValidateInstruction(expression, instruction); } }