1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 namespace System.ServiceModel.Dispatcher 5 { 6 using System.Runtime; 7 8 internal enum MathOperator 9 { 10 None, 11 Plus, 12 Minus, 13 Div, 14 Multiply, 15 Mod, 16 Negate 17 } 18 19 internal class MathOpcode : Opcode 20 { 21 MathOperator mathOp; 22 MathOpcode(OpcodeID id, MathOperator op)23 internal MathOpcode(OpcodeID id, MathOperator op) 24 : base(id) 25 { 26 this.mathOp = op; 27 } 28 Equals(Opcode op)29 internal override bool Equals(Opcode op) 30 { 31 if (base.Equals(op)) 32 { 33 return (this.mathOp == ((MathOpcode) op).mathOp); 34 } 35 36 return false; 37 } 38 39 #if DEBUG_FILTER ToString()40 public override string ToString() 41 { 42 return string.Format("{0} {1}", base.ToString(), this.mathOp.ToString()); 43 } 44 #endif 45 } 46 47 internal class PlusOpcode : MathOpcode 48 { PlusOpcode()49 internal PlusOpcode() 50 : base(OpcodeID.Plus, MathOperator.Plus) 51 { 52 } 53 Eval(ProcessingContext context)54 internal override Opcode Eval(ProcessingContext context) 55 { 56 StackFrame argX = context.TopArg; 57 StackFrame argY = context.SecondArg; 58 Fx.Assert(argX.Count == argY.Count, ""); 59 60 Value[] values = context.Values; 61 62 for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) 63 { 64 Fx.Assert(values[x].IsType(ValueDataType.Double), ""); 65 Fx.Assert(values[y].IsType(ValueDataType.Double), ""); 66 values[y].Add(values[x].Double); 67 } 68 69 context.PopFrame(); 70 return this.next; 71 } 72 } 73 74 internal class MinusOpcode : MathOpcode 75 { MinusOpcode()76 internal MinusOpcode() 77 : base(OpcodeID.Minus, MathOperator.Minus) 78 { 79 } 80 Eval(ProcessingContext context)81 internal override Opcode Eval(ProcessingContext context) 82 { 83 StackFrame argX = context.TopArg; 84 StackFrame argY = context.SecondArg; 85 Fx.Assert(argX.Count == argY.Count, ""); 86 87 Value[] values = context.Values; 88 89 for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) 90 { 91 Fx.Assert(values[x].IsType(ValueDataType.Double), ""); 92 Fx.Assert(values[y].IsType(ValueDataType.Double), ""); 93 values[y].Double = values[x].Double - values[y].Double; 94 } 95 96 context.PopFrame(); 97 return this.next; 98 } 99 } 100 101 internal class MultiplyOpcode : MathOpcode 102 { MultiplyOpcode()103 internal MultiplyOpcode() 104 : base(OpcodeID.Multiply, MathOperator.Multiply) 105 { 106 } 107 Eval(ProcessingContext context)108 internal override Opcode Eval(ProcessingContext context) 109 { 110 StackFrame argX = context.TopArg; 111 StackFrame argY = context.SecondArg; 112 Fx.Assert(argX.Count == argY.Count, ""); 113 114 Value[] values = context.Values; 115 116 for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) 117 { 118 Fx.Assert(values[x].IsType(ValueDataType.Double), ""); 119 Fx.Assert(values[y].IsType(ValueDataType.Double), ""); 120 values[y].Multiply(values[x].Double); 121 } 122 123 context.PopFrame(); 124 return this.next; 125 } 126 } 127 128 internal class DivideOpcode : MathOpcode 129 { DivideOpcode()130 internal DivideOpcode() 131 : base(OpcodeID.Divide, MathOperator.Div) 132 { 133 } 134 Eval(ProcessingContext context)135 internal override Opcode Eval(ProcessingContext context) 136 { 137 StackFrame argX = context.TopArg; 138 StackFrame argY = context.SecondArg; 139 Fx.Assert(argX.Count == argY.Count, ""); 140 Value[] values = context.Values; 141 142 for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) 143 { 144 Fx.Assert(values[x].IsType(ValueDataType.Double), ""); 145 Fx.Assert(values[y].IsType(ValueDataType.Double), ""); 146 values[y].Double = values[x].Double / values[y].Double; 147 } 148 149 context.PopFrame(); 150 return this.next; 151 } 152 } 153 154 internal class ModulusOpcode : MathOpcode 155 { ModulusOpcode()156 internal ModulusOpcode() 157 : base(OpcodeID.Mod, MathOperator.Mod) 158 { 159 } 160 Eval(ProcessingContext context)161 internal override Opcode Eval(ProcessingContext context) 162 { 163 StackFrame argX = context.TopArg; 164 StackFrame argY = context.SecondArg; 165 Value[] values = context.Values; 166 167 Fx.Assert(argX.Count == argY.Count, ""); 168 for (int x = argX.basePtr, y = argY.basePtr; x <= argX.endPtr; ++x, ++y) 169 { 170 Fx.Assert(values[x].IsType(ValueDataType.Double), ""); 171 Fx.Assert(values[y].IsType(ValueDataType.Double), ""); 172 values[y].Double = values[x].Double % values[y].Double; 173 } 174 175 context.PopFrame(); 176 return this.next; 177 } 178 } 179 180 internal class NegateOpcode : MathOpcode 181 { NegateOpcode()182 internal NegateOpcode() 183 : base(OpcodeID.Negate, MathOperator.Negate) 184 { 185 } 186 Eval(ProcessingContext context)187 internal override Opcode Eval(ProcessingContext context) 188 { 189 StackFrame frame = context.TopArg; 190 Value[] values = context.Values; 191 192 for (int i = frame.basePtr; i <= frame.endPtr; ++i) 193 { 194 values[i].Negate(); 195 } 196 return this.next; 197 } 198 } 199 200 } 201