1
1
/*
2
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* The Universal Permissive License (UPL), Version 1.0
51
51
import com .oracle .graal .python .builtins .objects .ints .PInt ;
52
52
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
53
53
import com .oracle .graal .python .nodes .PGuards ;
54
+ import com .oracle .graal .python .nodes .SpecialMethodNames ;
54
55
import com .oracle .graal .python .nodes .call .special .LookupAndCallUnaryNode ;
55
56
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
57
+ import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
56
58
import com .oracle .graal .python .runtime .exception .PythonErrorType ;
59
+ import com .oracle .truffle .api .CompilerDirectives ;
60
+ import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
57
61
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
58
- import com .oracle .truffle .api .dsl .Cached ;
62
+ import com .oracle .truffle .api .dsl .Fallback ;
59
63
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
60
64
import com .oracle .truffle .api .dsl .NodeFactory ;
61
65
import com .oracle .truffle .api .dsl .Specialization ;
66
+ import com .oracle .truffle .api .dsl .TypeSystemReference ;
62
67
import com .oracle .truffle .api .nodes .UnexpectedResultException ;
63
68
64
69
@ CoreFunctions (extendClasses = PythonBuiltinClassType .PRandom )
@@ -70,6 +75,7 @@ protected List<? extends NodeFactory<? extends PythonBuiltinNode>> getNodeFactor
70
75
71
76
@ Builtin (name = "seed" , fixedNumOfPositionalArgs = 2 )
72
77
@ GenerateNodeFactory
78
+ @ TypeSystemReference (PythonArithmeticTypes .class )
73
79
public abstract static class SeedNode extends PythonBuiltinNode {
74
80
75
81
@ Specialization
@@ -80,7 +86,7 @@ public PNone seed(PRandom random, @SuppressWarnings("unused") PNone none) {
80
86
}
81
87
82
88
@ Specialization
83
- public PNone seed (PRandom random , int inputSeed ) {
89
+ public PNone seed (PRandom random , long inputSeed ) {
84
90
random .setSeed (inputSeed );
85
91
return PNone .NONE ;
86
92
}
@@ -97,26 +103,47 @@ public PNone seed(PRandom random, double inputSeed) {
97
103
return PNone .NONE ;
98
104
}
99
105
100
- @ Specialization (rewriteOn = UnexpectedResultException .class )
101
- public PNone seedObject (PRandom random , Object inputSeed ,
102
- @ Cached ("create(__HASH__)" ) LookupAndCallUnaryNode callHash ) throws UnexpectedResultException {
103
- long hash = callHash .executeLong (inputSeed );
104
- random .setSeed (hash );
105
- return PNone .NONE ;
106
- }
106
+ @ CompilationFinal boolean gotUnexpectedHashResult = false ;
107
+ @ Child LookupAndCallUnaryNode callHash ;
107
108
108
- @ Specialization (replaces = "seedObject" )
109
- public PNone seedNonLong (PRandom random , Object inputSeed ,
110
- @ Cached ("create(__HASH__)" ) LookupAndCallUnaryNode callHash ) {
111
- Object object = callHash .executeObject (inputSeed );
112
- if (PGuards .isInteger (object )) {
113
- random .setSeed (((Number ) object ).intValue ());
114
- } else if (PGuards .isPInt (object )) {
115
- random .setSeed (((PInt ) object ).intValue ());
109
+ @ Fallback
110
+ public PNone seedNonLong (Object random , Object inputSeed ) {
111
+ if (random instanceof PRandom ) {
112
+ if (callHash == null ) {
113
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
114
+ callHash = insert (LookupAndCallUnaryNode .create (SpecialMethodNames .__HASH__ ));
115
+ }
116
+ Object hashResult = null ;
117
+ if (!gotUnexpectedHashResult ) {
118
+ try {
119
+ long hash = callHash .executeLong (inputSeed );
120
+ ((PRandom ) random ).setSeed (hash );
121
+ return PNone .NONE ;
122
+ } catch (UnexpectedResultException e ) {
123
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
124
+ gotUnexpectedHashResult = true ;
125
+ hashResult = e .getResult ();
126
+ }
127
+ }
128
+ if (gotUnexpectedHashResult ) {
129
+ if (hashResult == null ) {
130
+ hashResult = callHash .executeObject (inputSeed );
131
+ }
132
+ if (PGuards .isInteger (hashResult )) {
133
+ ((PRandom ) random ).setSeed (((Number ) hashResult ).intValue ());
134
+ } else if (PGuards .isPInt (hashResult )) {
135
+ ((PRandom ) random ).setSeed (((PInt ) hashResult ).intValue ());
136
+ } else {
137
+ throw raise (PythonErrorType .TypeError , "__hash__ method should return an integer" );
138
+ }
139
+ return PNone .NONE ;
140
+ } else {
141
+ assert false : "cannot reach here" ;
142
+ return PNone .NONE ;
143
+ }
116
144
} else {
117
- throw raise (PythonErrorType .TypeError , "__hash__ method should return an integer" );
145
+ throw raise (PythonErrorType .TypeError , "descriptor 'seed' requires a '_random.Random' object but received a '%p'" , random );
118
146
}
119
- return PNone .NONE ;
120
147
}
121
148
}
122
149
0 commit comments