1
1
/*
2
- * Copyright (c) 2017, 2018 , Oracle and/or its affiliates.
2
+ * Copyright (c) 2017, 2019 , Oracle and/or its affiliates.
3
3
* Copyright (c) 2014, Regents of the University of California
4
4
*
5
5
* All rights reserved.
25
25
*/
26
26
package com .oracle .graal .python .builtins .objects .tuple ;
27
27
28
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__ADD__ ;
29
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__BOOL__ ;
30
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__CONTAINS__ ;
31
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__EQ__ ;
32
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__GETITEM__ ;
33
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__GE__ ;
34
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__GT__ ;
35
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__HASH__ ;
36
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__ITER__ ;
37
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__LEN__ ;
38
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__LE__ ;
39
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__LT__ ;
40
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__MUL__ ;
41
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__NE__ ;
28
42
import static com .oracle .graal .python .nodes .SpecialMethodNames .__REPR__ ;
43
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__RMUL__ ;
29
44
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
30
45
31
46
import java .math .BigInteger ;
47
62
import com .oracle .graal .python .builtins .objects .slice .PSlice ;
48
63
import com .oracle .graal .python .builtins .objects .str .PString ;
49
64
import com .oracle .graal .python .builtins .objects .tuple .TupleBuiltinsFactory .IndexNodeFactory ;
50
- import com .oracle .graal .python .nodes .SpecialMethodNames ;
51
65
import com .oracle .graal .python .nodes .argument .ReadArgumentNode ;
52
66
import com .oracle .graal .python .nodes .call .special .LookupAndCallUnaryNode ;
53
67
import com .oracle .graal .python .nodes .expression .BinaryComparisonNode ;
56
70
import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
57
71
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
58
72
import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
73
+ import com .oracle .graal .python .nodes .util .CastToJavaLongNode ;
59
74
import com .oracle .graal .python .runtime .exception .PythonErrorType ;
60
75
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
61
76
import com .oracle .truffle .api .CompilerDirectives ;
@@ -263,7 +278,7 @@ long count(PTuple self, Object value,
263
278
}
264
279
}
265
280
266
- @ Builtin (name = SpecialMethodNames . __LEN__ , fixedNumOfPositionalArgs = 1 )
281
+ @ Builtin (name = __LEN__ , fixedNumOfPositionalArgs = 1 )
267
282
@ GenerateNodeFactory
268
283
public abstract static class LenNode extends PythonUnaryBuiltinNode {
269
284
@ Specialization
@@ -294,10 +309,11 @@ public String toString(Object item, BuiltinFunctions.ReprNode reprNode) {
294
309
@ Specialization
295
310
@ TruffleBoundary
296
311
public String repr (PTuple self ,
312
+ @ Cached ("create()" ) SequenceStorageNodes .LenNode getLen ,
297
313
@ Cached ("createNotNormalized()" ) SequenceStorageNodes .GetItemNode getItemNode ,
298
314
@ Cached ("createRepr()" ) BuiltinFunctions .ReprNode reprNode ) {
299
315
SequenceStorage tupleStore = self .getSequenceStorage ();
300
- int len = tupleStore . length ( );
316
+ int len = getLen . execute ( tupleStore );
301
317
StringBuilder buf = new StringBuilder ();
302
318
append (buf , "(" );
303
319
for (int i = 0 ; i < len - 1 ; i ++) {
@@ -332,7 +348,7 @@ protected static BuiltinFunctions.ReprNode createRepr() {
332
348
}
333
349
}
334
350
335
- @ Builtin (name = SpecialMethodNames . __GETITEM__ , fixedNumOfPositionalArgs = 2 )
351
+ @ Builtin (name = __GETITEM__ , fixedNumOfPositionalArgs = 2 )
336
352
@ ImportStatic (MathGuards .class )
337
353
@ TypeSystemReference (PythonArithmeticTypes .class )
338
354
@ GenerateNodeFactory
@@ -363,7 +379,7 @@ protected boolean isPSlice(Object object) {
363
379
}
364
380
}
365
381
366
- @ Builtin (name = SpecialMethodNames . __EQ__ , fixedNumOfPositionalArgs = 2 )
382
+ @ Builtin (name = __EQ__ , fixedNumOfPositionalArgs = 2 )
367
383
@ GenerateNodeFactory
368
384
abstract static class EqNode extends PythonBinaryBuiltinNode {
369
385
@@ -380,7 +396,7 @@ Object doOther(Object left, Object right) {
380
396
}
381
397
}
382
398
383
- @ Builtin (name = SpecialMethodNames . __NE__ , fixedNumOfPositionalArgs = 2 )
399
+ @ Builtin (name = __NE__ , fixedNumOfPositionalArgs = 2 )
384
400
@ GenerateNodeFactory
385
401
abstract static class NeNode extends PythonBinaryBuiltinNode {
386
402
@@ -397,7 +413,7 @@ boolean doOther(Object left, Object right) {
397
413
}
398
414
}
399
415
400
- @ Builtin (name = SpecialMethodNames . __GE__ , fixedNumOfPositionalArgs = 2 )
416
+ @ Builtin (name = __GE__ , fixedNumOfPositionalArgs = 2 )
401
417
@ GenerateNodeFactory
402
418
abstract static class GeNode extends PythonBinaryBuiltinNode {
403
419
@@ -415,7 +431,7 @@ PNotImplemented doOther(Object left, Object right) {
415
431
416
432
}
417
433
418
- @ Builtin (name = SpecialMethodNames . __LE__ , fixedNumOfPositionalArgs = 2 )
434
+ @ Builtin (name = __LE__ , fixedNumOfPositionalArgs = 2 )
419
435
@ GenerateNodeFactory
420
436
abstract static class LeNode extends PythonBinaryBuiltinNode {
421
437
@@ -433,7 +449,7 @@ PNotImplemented doOther(Object left, Object right) {
433
449
434
450
}
435
451
436
- @ Builtin (name = SpecialMethodNames . __GT__ , fixedNumOfPositionalArgs = 2 )
452
+ @ Builtin (name = __GT__ , fixedNumOfPositionalArgs = 2 )
437
453
@ GenerateNodeFactory
438
454
abstract static class GtNode extends PythonBinaryBuiltinNode {
439
455
@@ -449,7 +465,7 @@ PNotImplemented doOther(@SuppressWarnings("unused") Object left, @SuppressWarnin
449
465
}
450
466
}
451
467
452
- @ Builtin (name = SpecialMethodNames . __LT__ , fixedNumOfPositionalArgs = 2 )
468
+ @ Builtin (name = __LT__ , fixedNumOfPositionalArgs = 2 )
453
469
@ GenerateNodeFactory
454
470
abstract static class LtNode extends PythonBinaryBuiltinNode {
455
471
@ Specialization
@@ -464,7 +480,7 @@ PNotImplemented contains(@SuppressWarnings("unused") Object self, @SuppressWarni
464
480
}
465
481
}
466
482
467
- @ Builtin (name = SpecialMethodNames . __ADD__ , fixedNumOfPositionalArgs = 2 )
483
+ @ Builtin (name = __ADD__ , fixedNumOfPositionalArgs = 2 )
468
484
@ GenerateNodeFactory
469
485
abstract static class AddNode extends PythonBuiltinNode {
470
486
@ Specialization
@@ -480,7 +496,7 @@ Object doGeneric(@SuppressWarnings("unused") Object left, Object right) {
480
496
}
481
497
}
482
498
483
- @ Builtin (name = SpecialMethodNames . __MUL__ , fixedNumOfPositionalArgs = 2 )
499
+ @ Builtin (name = __MUL__ , fixedNumOfPositionalArgs = 2 )
484
500
@ GenerateNodeFactory
485
501
abstract static class MulNode extends PythonBuiltinNode {
486
502
@ Specialization
@@ -490,12 +506,12 @@ PTuple mul(PTuple left, Object right,
490
506
}
491
507
}
492
508
493
- @ Builtin (name = SpecialMethodNames . __RMUL__ , fixedNumOfPositionalArgs = 2 )
509
+ @ Builtin (name = __RMUL__ , fixedNumOfPositionalArgs = 2 )
494
510
@ GenerateNodeFactory
495
511
abstract static class RMulNode extends MulNode {
496
512
}
497
513
498
- @ Builtin (name = SpecialMethodNames . __CONTAINS__ , fixedNumOfPositionalArgs = 2 )
514
+ @ Builtin (name = __CONTAINS__ , fixedNumOfPositionalArgs = 2 )
499
515
@ GenerateNodeFactory
500
516
abstract static class ContainsNode extends PythonBinaryBuiltinNode {
501
517
@ Specialization
@@ -506,7 +522,7 @@ boolean contains(PTuple self, Object other,
506
522
507
523
}
508
524
509
- @ Builtin (name = SpecialMethodNames . __BOOL__ , fixedNumOfPositionalArgs = 1 )
525
+ @ Builtin (name = __BOOL__ , fixedNumOfPositionalArgs = 1 )
510
526
@ GenerateNodeFactory
511
527
public abstract static class BoolNode extends PythonUnaryBuiltinNode {
512
528
@ Specialization
@@ -521,7 +537,7 @@ Object toBoolean(@SuppressWarnings("unused") Object self) {
521
537
}
522
538
}
523
539
524
- @ Builtin (name = SpecialMethodNames . __ITER__ , fixedNumOfPositionalArgs = 1 )
540
+ @ Builtin (name = __ITER__ , fixedNumOfPositionalArgs = 1 )
525
541
@ GenerateNodeFactory
526
542
public abstract static class IterNode extends PythonUnaryBuiltinNode {
527
543
@ Specialization
@@ -534,4 +550,50 @@ Object doGeneric(@SuppressWarnings("unused") Object self) {
534
550
return PNotImplemented .NOT_IMPLEMENTED ;
535
551
}
536
552
}
553
+
554
+ @ Builtin (name = __HASH__ , fixedNumOfPositionalArgs = 1 )
555
+ @ GenerateNodeFactory
556
+ public abstract static class HashNode extends PythonUnaryBuiltinNode {
557
+ @ Specialization
558
+ public long tupleHash (PTuple self ,
559
+ @ Cached ("create()" ) SequenceStorageNodes .LenNode getLen ,
560
+ @ Cached ("createNotNormalized()" ) SequenceStorageNodes .GetItemNode getItemNode ,
561
+ @ Cached ("create(__HASH__)" ) LookupAndCallUnaryNode lookupHashAttributeNode ,
562
+ @ Cached ("create()" ) BuiltinFunctions .IsInstanceNode isInstanceNode ,
563
+ @ Cached ("createLossy()" ) CastToJavaLongNode castToLongNode ) {
564
+ // adapted from https://github.com/python/cpython/blob/v3.6.5/Objects/tupleobject.c#L345
565
+ SequenceStorage tupleStore = self .getSequenceStorage ();
566
+ int len = getLen .execute (tupleStore );
567
+ long multiplier = 0xf4243 ;
568
+ long x = 0x345678 ;
569
+ long y ;
570
+ for (int i = 0 ; i < len ; i ++) {
571
+ Object item = getItemNode .execute (tupleStore , i );
572
+ Object hashValue = lookupHashAttributeNode .executeObject (item );
573
+ if (!isInstanceNode .executeWith (hashValue , getBuiltinPythonClass (PythonBuiltinClassType .PInt ))) {
574
+ throw raise (PythonErrorType .TypeError , "__hash__ method should return an integer" );
575
+ }
576
+ y = castToLongNode .execute (hashValue );
577
+ if (y == -1 ) {
578
+ return -1 ;
579
+ }
580
+
581
+ x = (x ^ y ) * multiplier ;
582
+ multiplier += 82520 + len + len ;
583
+ }
584
+
585
+ x += 97531 ;
586
+
587
+ if (x == Long .MAX_VALUE ) {
588
+ x = -2 ;
589
+ }
590
+
591
+ return x ;
592
+ }
593
+
594
+ @ Fallback
595
+ Object genericHash (@ SuppressWarnings ("unused" ) Object self ) {
596
+ return PNotImplemented .NOT_IMPLEMENTED ;
597
+ }
598
+ }
537
599
}
0 commit comments