|
11 | 11 |
|
12 | 12 | import com.oracle.truffle.api.RootCallTarget;
|
13 | 13 | import com.oracle.truffle.api.dsl.CachedLanguage;
|
| 14 | +import com.oracle.truffle.api.dsl.Fallback; |
14 | 15 | import com.oracle.truffle.api.object.Shape;
|
15 | 16 | import org.truffleruby.Layouts;
|
16 | 17 | import org.truffleruby.RubyContext;
|
@@ -113,6 +114,9 @@ protected boolean equal(VirtualFrame frame, Object a, Object b) {
|
113 | 114 |
|
114 | 115 | }
|
115 | 116 |
|
| 117 | + /** This node is not trivial because primitives must be compared by value and never by identity. Also, this node |
| 118 | + * must consider (byte) n and (short) n and (int) n and (long) n equal, as well as (float) n and (double) n. So even |
| 119 | + * if a and b have different classes they might still be equal if they are primitives. */ |
116 | 120 | @CoreMethod(names = { "equal?", "==" }, required = 1)
|
117 | 121 | public abstract static class ReferenceEqualNode extends CoreMethodArrayArgumentsNode {
|
118 | 122 |
|
@@ -142,57 +146,16 @@ protected boolean equal(double a, double b) {
|
142 | 146 | return Double.doubleToRawLongBits(a) == Double.doubleToRawLongBits(b);
|
143 | 147 | }
|
144 | 148 |
|
145 |
| - @Specialization |
146 |
| - protected boolean equal(RubyDynamicObject a, RubyDynamicObject b) { |
| 149 | + @Specialization(guards = { "a.getClass() == b.getClass()", "!isPrimitive(a)" }) // since a and b have the same class, implies !isPrimitive(b) |
| 150 | + protected boolean equalSameClassNonPrimitive(Object a, Object b) { |
147 | 151 | return a == b;
|
148 | 152 | }
|
149 | 153 |
|
150 |
| - @Specialization( |
151 |
| - guards = { |
152 |
| - "isNotRubyDynamicObject(a)", |
153 |
| - "isNotRubyDynamicObject(b)", |
154 |
| - "!sameClass(a, b)", |
155 |
| - "isNotIntLong(a) || isNotIntLong(b)" }) |
156 |
| - protected boolean equalIncompatiblePrimitiveTypes(Object a, Object b) { |
157 |
| - return false; |
158 |
| - } |
159 |
| - |
160 |
| - @Specialization( |
161 |
| - guards = { |
162 |
| - "isNotRubyDynamicObject(a)", |
163 |
| - "isNotRubyDynamicObject(b)", |
164 |
| - "sameClass(a, b)", |
165 |
| - "isNotIntLongDouble(a) || isNotIntLongDouble(b)" }) |
166 |
| - protected boolean equalOtherSameClass(Object a, Object b) { |
167 |
| - return a == b; |
168 |
| - } |
169 |
| - |
170 |
| - @Specialization(guards = "isNotRubyDynamicObject(a)") |
171 |
| - protected boolean equal(Object a, RubyDynamicObject b) { |
172 |
| - return false; |
173 |
| - } |
174 |
| - |
175 |
| - @Specialization(guards = "isNotRubyDynamicObject(b)") |
176 |
| - protected boolean equal(RubyDynamicObject a, Object b) { |
| 154 | + @Fallback |
| 155 | + protected boolean fallback(Object a, Object b) { |
177 | 156 | return false;
|
178 | 157 | }
|
179 | 158 |
|
180 |
| - protected boolean isNotRubyDynamicObject(Object value) { |
181 |
| - return !(value instanceof RubyDynamicObject); |
182 |
| - } |
183 |
| - |
184 |
| - protected boolean sameClass(Object a, Object b) { |
185 |
| - return a.getClass() == b.getClass(); |
186 |
| - } |
187 |
| - |
188 |
| - protected boolean isNotIntLong(Object v) { |
189 |
| - return !(v instanceof Integer) && !(v instanceof Long); |
190 |
| - } |
191 |
| - |
192 |
| - protected boolean isNotIntLongDouble(Object v) { |
193 |
| - return !(v instanceof Integer) && !(v instanceof Long) && !(v instanceof Double); |
194 |
| - } |
195 |
| - |
196 | 159 | }
|
197 | 160 |
|
198 | 161 | @GenerateUncached
|
|
0 commit comments