74
74
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodesFactory .UnionNodeGen ;
75
75
import com .oracle .graal .python .builtins .objects .dict .PDict ;
76
76
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
77
- import com .oracle .graal .python .builtins .objects .ints .PInt ;
78
77
import com .oracle .graal .python .builtins .objects .object .PythonObject ;
79
78
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
80
79
import com .oracle .graal .python .builtins .objects .set .PSet ;
102
101
import com .oracle .graal .python .runtime .ExecutionContext .IndirectCallContext ;
103
102
import com .oracle .graal .python .runtime .PythonContext ;
104
103
import com .oracle .graal .python .runtime .exception .PException ;
105
- import com .oracle .graal .python .runtime .exception .PythonErrorType ;
106
104
import com .oracle .graal .python .runtime .sequence .PSequence ;
107
105
import com .oracle .truffle .api .Assumption ;
108
106
import com .oracle .truffle .api .CompilerAsserts ;
125
123
import com .oracle .truffle .api .nodes .Node ;
126
124
import com .oracle .truffle .api .nodes .NodeCost ;
127
125
import com .oracle .truffle .api .nodes .NodeInfo ;
128
- import com .oracle .truffle .api .nodes .UnexpectedResultException ;
129
126
import com .oracle .truffle .api .object .DynamicObject ;
130
127
import com .oracle .truffle .api .object .FinalLocationException ;
131
128
import com .oracle .truffle .api .object .IncompatibleLocationException ;
@@ -141,60 +138,15 @@ public abstract class HashingStorageNodes {
141
138
private static final int MAX_STORAGES = 8 ;
142
139
143
140
public static class PythonEquivalence extends Equivalence {
144
- @ Child private PRaiseNode raise ;
145
- @ Child private LookupAndCallUnaryNode callHashNode = LookupAndCallUnaryNode .create (__HASH__ );
141
+ @ Child private PythonObjectLibrary library = PythonObjectLibrary .getFactory ().createDispatched (3 );
146
142
@ Child private BinaryComparisonNode callEqNode = BinaryComparisonNode .create (__EQ__ , __EQ__ , "==" , null , null );
147
143
@ Child private CastToBooleanNode castToBoolean = CastToBooleanNode .createIfTrueNode ();
148
- @ CompilationFinal private int state = 0 ;
149
144
150
145
@ Override
151
146
public int hashCode (Object o ) {
152
- try {
153
- if (state == 0 ) { // int hash
154
- return callHashNode .executeInt (null , o );
155
- } else if (state == 1 ) { // long hash
156
- return (int ) (callHashNode .executeLong (null , o ));
157
- } else if (state == 2 ) { // object hash
158
- Object hash = callHashNode .executeObject (null , o );
159
- if (hash instanceof Integer ) {
160
- return (int ) hash ;
161
- } else if (hash instanceof Long ) {
162
- return (int ) ((long ) hash );
163
- } else if (hash instanceof PInt ) {
164
- return ((PInt ) hash ).intValue ();
165
- } else {
166
- throw hashCodeTypeError ();
167
- }
168
- } else {
169
- throw new IllegalStateException ();
170
- }
171
- } catch (UnexpectedResultException ex ) {
172
- CompilerDirectives .transferToInterpreterAndInvalidate ();
173
- if (ex .getResult () instanceof Integer ) {
174
- // the default state is executeInt, so when we get here, we already
175
- // switched to executeLong and now got an int again, so we cannot
176
- // specialize on either primitive type and have to switch to
177
- // the executeObject state.
178
- state = 2 ;
179
- return (int ) ex .getResult ();
180
- } else if (ex .getResult () instanceof Long ) {
181
- state = 1 ;
182
- return (int ) ((long ) ex .getResult ());
183
- } else if (ex .getResult () instanceof PInt ) {
184
- state = 2 ;
185
- return ((PInt ) ex .getResult ()).intValue ();
186
- } else {
187
- throw hashCodeTypeError ();
188
- }
189
- }
190
- }
191
-
192
- private PException hashCodeTypeError () {
193
- if (raise == null ) {
194
- CompilerDirectives .transferToInterpreterAndInvalidate ();
195
- raise = insert (PRaiseNode .create ());
196
- }
197
- return raise .raise (PythonErrorType .TypeError , "__hash__ method should return an integer" );
147
+ long hash = library .hash (o );
148
+ // Use a sufficiently bit-mixing narrowing conversion...
149
+ return Long .hashCode (hash );
198
150
}
199
151
200
152
@ Override
0 commit comments