//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ namespace System.ServiceModel.Dispatcher { using System.Runtime; internal enum MathOperator { None, Plus, Minus, Div, Multiply, Mod, Negate } internal class MathOpcode : Opcode { MathOperator mathOp; internal MathOpcode(OpcodeID id, MathOperator op) : base(id) { this.mathOp = op; } internal override bool Equals(Opcode op) { if (base.Equals(op)) { return (this.mathOp == ((MathOpcode) op).mathOp); } return false; } #if DEBUG_FILTER public override string ToString() { return string.Format("{0} {1}", base.ToString(), this.mathOp.ToString()); } #endif } internal class PlusOpcode : MathOpcode { internal PlusOpcode() : base(OpcodeID.Plus, MathOperator.Plus) { } internal override Opcode Eval(ProcessingContext context) { StackFrame argX = context.TopArg; StackFrame argY = context.SecondArg; Fx.Assert(argX.Count == argY.Count, ""); Value[] values = context.Values; for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) { Fx.Assert(values[x].IsType(ValueDataType.Double), ""); Fx.Assert(values[y].IsType(ValueDataType.Double), ""); values[y].Add(values[x].Double); } context.PopFrame(); return this.next; } } internal class MinusOpcode : MathOpcode { internal MinusOpcode() : base(OpcodeID.Minus, MathOperator.Minus) { } internal override Opcode Eval(ProcessingContext context) { StackFrame argX = context.TopArg; StackFrame argY = context.SecondArg; Fx.Assert(argX.Count == argY.Count, ""); Value[] values = context.Values; for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) { Fx.Assert(values[x].IsType(ValueDataType.Double), ""); Fx.Assert(values[y].IsType(ValueDataType.Double), ""); values[y].Double = values[x].Double - values[y].Double; } context.PopFrame(); return this.next; } } internal class MultiplyOpcode : MathOpcode { internal MultiplyOpcode() : base(OpcodeID.Multiply, MathOperator.Multiply) { } internal override Opcode Eval(ProcessingContext context) { StackFrame argX = context.TopArg; StackFrame argY = context.SecondArg; Fx.Assert(argX.Count == argY.Count, ""); Value[] values = context.Values; for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) { Fx.Assert(values[x].IsType(ValueDataType.Double), ""); Fx.Assert(values[y].IsType(ValueDataType.Double), ""); values[y].Multiply(values[x].Double); } context.PopFrame(); return this.next; } } internal class DivideOpcode : MathOpcode { internal DivideOpcode() : base(OpcodeID.Divide, MathOperator.Div) { } internal override Opcode Eval(ProcessingContext context) { StackFrame argX = context.TopArg; StackFrame argY = context.SecondArg; Fx.Assert(argX.Count == argY.Count, ""); Value[] values = context.Values; for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) { Fx.Assert(values[x].IsType(ValueDataType.Double), ""); Fx.Assert(values[y].IsType(ValueDataType.Double), ""); values[y].Double = values[x].Double / values[y].Double; } context.PopFrame(); return this.next; } } internal class ModulusOpcode : MathOpcode { internal ModulusOpcode() : base(OpcodeID.Mod, MathOperator.Mod) { } internal override Opcode Eval(ProcessingContext context) { StackFrame argX = context.TopArg; StackFrame argY = context.SecondArg; Value[] values = context.Values; Fx.Assert(argX.Count == argY.Count, ""); for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) { Fx.Assert(values[x].IsType(ValueDataType.Double), ""); Fx.Assert(values[y].IsType(ValueDataType.Double), ""); values[y].Double = values[x].Double % values[y].Double; } context.PopFrame(); return this.next; } } internal class NegateOpcode : MathOpcode { internal NegateOpcode() : base(OpcodeID.Negate, MathOperator.Negate) { } internal override Opcode Eval(ProcessingContext context) { StackFrame frame = context.TopArg; Value[] values = context.Values; for (int i = frame.basePtr; i <= frame.endPtr; ++i) { values[i].Negate(); } return this.next; } } }