~ubuntu-branches/ubuntu/trusty/smuxi/trusty-proposed

« back to all changes in this revision

Viewing changes to lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/ComparisonBytecodeGeneratingVisitor.cs

  • Committer: Package Import Robot
  • Author(s): Mirco Bauer
  • Date: 2013-05-25 22:11:31 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20130525221131-nd2mc0kzubuwyx20
Tags: 0.8.11-1
* [22d13d5] Imported Upstream version 0.8.11
* [6d2b95a] Refreshed patches
* [89eb66e] Added ServiceStack libraries to smuxi-engine package
* [848ab10] Enable Campfire engine
* [c6dbdc7] Always build db4o for predictable build result
* [13ec489] Exclude OS X specific libraries from dh_clideps

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
2
 
 
3
 
using System;
4
 
using Db4objects.Db4o.Instrumentation.Api;
5
 
using Db4objects.Db4o.NativeQueries.Expr.Cmp;
6
 
using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
7
 
using Db4objects.Db4o.NativeQueries.Instrumentation;
8
 
 
9
 
namespace Db4objects.Db4o.NativeQueries.Instrumentation
10
 
{
11
 
        internal class ComparisonBytecodeGeneratingVisitor : IComparisonOperandVisitor
12
 
        {
13
 
                private IMethodBuilder _methodBuilder;
14
 
 
15
 
                private ITypeRef _predicateClass;
16
 
 
17
 
                private bool _inArithmetic = false;
18
 
 
19
 
                private ITypeRef _opClass = null;
20
 
 
21
 
                private ITypeRef _staticRoot = null;
22
 
 
23
 
                public ComparisonBytecodeGeneratingVisitor(IMethodBuilder methodBuilder, ITypeRef
24
 
                         predicateClass)
25
 
                {
26
 
                        this._methodBuilder = methodBuilder;
27
 
                        this._predicateClass = predicateClass;
28
 
                }
29
 
 
30
 
                public virtual void Visit(ConstValue operand)
31
 
                {
32
 
                        object value = operand.Value();
33
 
                        if (value != null)
34
 
                        {
35
 
                                _opClass = TypeRef(value.GetType());
36
 
                        }
37
 
                        _methodBuilder.Ldc(value);
38
 
                        if (value != null)
39
 
                        {
40
 
                                Box(_opClass, !_inArithmetic);
41
 
                        }
42
 
                }
43
 
 
44
 
                private ITypeRef TypeRef(Type type)
45
 
                {
46
 
                        return _methodBuilder.References.ForType(type);
47
 
                }
48
 
 
49
 
                public virtual void Visit(FieldValue fieldValue)
50
 
                {
51
 
                        ITypeRef lastFieldClass = fieldValue.Field.Type;
52
 
                        bool needConversion = lastFieldClass.IsPrimitive;
53
 
                        fieldValue.Parent().Accept(this);
54
 
                        if (_staticRoot != null)
55
 
                        {
56
 
                                _methodBuilder.LoadStaticField(fieldValue.Field);
57
 
                                _staticRoot = null;
58
 
                                return;
59
 
                        }
60
 
                        _methodBuilder.LoadField(fieldValue.Field);
61
 
                        Box(lastFieldClass, !_inArithmetic && needConversion);
62
 
                }
63
 
 
64
 
                public virtual void Visit(CandidateFieldRoot root)
65
 
                {
66
 
                        _methodBuilder.LoadArgument(1);
67
 
                }
68
 
 
69
 
                public virtual void Visit(PredicateFieldRoot root)
70
 
                {
71
 
                        _methodBuilder.LoadArgument(0);
72
 
                }
73
 
 
74
 
                public virtual void Visit(StaticFieldRoot root)
75
 
                {
76
 
                        _staticRoot = root.Type;
77
 
                }
78
 
 
79
 
                public virtual void Visit(ArrayAccessValue operand)
80
 
                {
81
 
                        ITypeRef cmpType = DeduceFieldClass(operand.Parent()).ElementType;
82
 
                        operand.Parent().Accept(this);
83
 
                        bool outerInArithmetic = _inArithmetic;
84
 
                        _inArithmetic = true;
85
 
                        operand.Index().Accept(this);
86
 
                        _inArithmetic = outerInArithmetic;
87
 
                        _methodBuilder.LoadArrayElement(cmpType);
88
 
                        Box(cmpType, !_inArithmetic);
89
 
                }
90
 
 
91
 
                public virtual void Visit(MethodCallValue operand)
92
 
                {
93
 
                        IMethodRef method = operand.Method;
94
 
                        ITypeRef retType = method.ReturnType;
95
 
                        // FIXME: this should be handled within conversions
96
 
                        bool needConversion = retType.IsPrimitive;
97
 
                        operand.Parent().Accept(this);
98
 
                        bool oldInArithmetic = _inArithmetic;
99
 
                        for (int paramIdx = 0; paramIdx < operand.Args.Length; paramIdx++)
100
 
                        {
101
 
                                _inArithmetic = operand.Method.ParamTypes[paramIdx].IsPrimitive;
102
 
                                operand.Args[paramIdx].Accept(this);
103
 
                        }
104
 
                        _inArithmetic = oldInArithmetic;
105
 
                        _methodBuilder.Invoke(method, operand.CallingConvention);
106
 
                        Box(retType, !_inArithmetic && needConversion);
107
 
                }
108
 
 
109
 
                public virtual void Visit(ArithmeticExpression operand)
110
 
                {
111
 
                        bool oldInArithmetic = _inArithmetic;
112
 
                        _inArithmetic = true;
113
 
                        operand.Left().Accept(this);
114
 
                        operand.Right().Accept(this);
115
 
                        ITypeRef operandType = ArithmeticType(operand);
116
 
                        switch (operand.Op().Id())
117
 
                        {
118
 
                                case ArithmeticOperator.AddId:
119
 
                                {
120
 
                                        _methodBuilder.Add(operandType);
121
 
                                        break;
122
 
                                }
123
 
 
124
 
                                case ArithmeticOperator.SubtractId:
125
 
                                {
126
 
                                        _methodBuilder.Subtract(operandType);
127
 
                                        break;
128
 
                                }
129
 
 
130
 
                                case ArithmeticOperator.MultiplyId:
131
 
                                {
132
 
                                        _methodBuilder.Multiply(operandType);
133
 
                                        break;
134
 
                                }
135
 
 
136
 
                                case ArithmeticOperator.DivideId:
137
 
                                {
138
 
                                        _methodBuilder.Divide(operandType);
139
 
                                        break;
140
 
                                }
141
 
 
142
 
                                default:
143
 
                                {
144
 
                                        throw new Exception("Unknown operand: " + operand.Op());
145
 
                                }
146
 
                        }
147
 
                        Box(_opClass, !oldInArithmetic);
148
 
                        _inArithmetic = oldInArithmetic;
149
 
                }
150
 
 
151
 
                // FIXME: need to map dX,fX,...
152
 
                private void Box(ITypeRef boxedType, bool canApply)
153
 
                {
154
 
                        if (!canApply)
155
 
                        {
156
 
                                return;
157
 
                        }
158
 
                        _methodBuilder.Box(boxedType);
159
 
                }
160
 
 
161
 
                private ITypeRef DeduceFieldClass(IComparisonOperand fieldValue)
162
 
                {
163
 
                        TypeDeducingVisitor visitor = new TypeDeducingVisitor(_methodBuilder.References, 
164
 
                                _predicateClass);
165
 
                        fieldValue.Accept(visitor);
166
 
                        return visitor.OperandClass();
167
 
                }
168
 
 
169
 
                private ITypeRef ArithmeticType(IComparisonOperand operand)
170
 
                {
171
 
                        if (operand is ConstValue)
172
 
                        {
173
 
                                return PrimitiveType(((ConstValue)operand).Value().GetType());
174
 
                        }
175
 
                        if (operand is FieldValue)
176
 
                        {
177
 
                                return ((FieldValue)operand).Field.Type;
178
 
                        }
179
 
                        if (operand is ArithmeticExpression)
180
 
                        {
181
 
                                ArithmeticExpression expr = (ArithmeticExpression)operand;
182
 
                                ITypeRef left = ArithmeticType(expr.Left());
183
 
                                ITypeRef right = ArithmeticType(expr.Right());
184
 
                                if (left == DoubleType() || right == DoubleType())
185
 
                                {
186
 
                                        return DoubleType();
187
 
                                }
188
 
                                if (left == FloatType() || right == FloatType())
189
 
                                {
190
 
                                        return FloatType();
191
 
                                }
192
 
                                if (left == LongType() || right == LongType())
193
 
                                {
194
 
                                        return LongType();
195
 
                                }
196
 
                                return IntType();
197
 
                        }
198
 
                        return null;
199
 
                }
200
 
 
201
 
                private ITypeRef PrimitiveType(Type klass)
202
 
                {
203
 
                        if (klass == typeof(int) || klass == typeof(short) || klass == typeof(bool) || klass
204
 
                                 == typeof(byte))
205
 
                        {
206
 
                                return IntType();
207
 
                        }
208
 
                        if (klass == typeof(double))
209
 
                        {
210
 
                                return DoubleType();
211
 
                        }
212
 
                        if (klass == typeof(float))
213
 
                        {
214
 
                                return FloatType();
215
 
                        }
216
 
                        if (klass == typeof(long))
217
 
                        {
218
 
                                return LongType();
219
 
                        }
220
 
                        return TypeRef(klass);
221
 
                }
222
 
 
223
 
                private ITypeRef IntType()
224
 
                {
225
 
                        return TypeRef(typeof(int));
226
 
                }
227
 
 
228
 
                private ITypeRef LongType()
229
 
                {
230
 
                        return TypeRef(typeof(long));
231
 
                }
232
 
 
233
 
                private ITypeRef FloatType()
234
 
                {
235
 
                        return TypeRef(typeof(float));
236
 
                }
237
 
 
238
 
                private ITypeRef DoubleType()
239
 
                {
240
 
                        return TypeRef(typeof(double));
241
 
                }
242
 
        }
243
 
}