31
31
import com .oracle .graal .python .builtins .objects .ints .PInt ;
32
32
import com .oracle .graal .python .builtins .objects .slice .PSlice ;
33
33
import com .oracle .graal .python .nodes .PNode ;
34
+ import com .oracle .graal .python .nodes .PNodeWithContext ;
34
35
import com .oracle .graal .python .nodes .expression .ExpressionNode ;
36
+ import com .oracle .graal .python .nodes .subscript .SliceLiteralNodeGen .CastToSliceComponentNodeGen ;
35
37
import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
38
+ import com .oracle .truffle .api .CompilerDirectives ;
39
+ import com .oracle .truffle .api .dsl .Fallback ;
36
40
import com .oracle .truffle .api .dsl .NodeChild ;
37
41
import com .oracle .truffle .api .dsl .NodeChildren ;
38
42
import com .oracle .truffle .api .dsl .Specialization ;
39
43
import com .oracle .truffle .api .dsl .TypeSystemReference ;
44
+ import com .oracle .truffle .api .profiles .BranchProfile ;
40
45
41
46
@ NodeChildren ({@ NodeChild (value = "first" , type = ExpressionNode .class ), @ NodeChild (value = "second" , type = ExpressionNode .class ), @ NodeChild (value = "third" , type = ExpressionNode .class )})
42
47
@ TypeSystemReference (PythonArithmeticTypes .class ) // because bool -> int works here
43
48
public abstract class SliceLiteralNode extends ExpressionNode {
44
49
50
+ @ Child private CastToSliceComponentNode castStartNode ;
51
+ @ Child private CastToSliceComponentNode castStopNode ;
52
+ @ Child private CastToSliceComponentNode castStepNode ;
53
+
45
54
public abstract PSlice execute (Object start , Object stop , Object step );
46
55
47
56
@ Specialization
@@ -50,127 +59,105 @@ public PSlice doInt(int start, int stop, int step) {
50
59
}
51
60
52
61
@ Specialization
53
- public PSlice doInt (@ SuppressWarnings ("unused" ) PNone start , int stop , int step ) {
54
- return factory ().createSlice (MISSING_INDEX , stop , step );
55
- }
56
-
57
- @ Specialization
58
- public PSlice doInt (int start , int stop , @ SuppressWarnings ("unused" ) PNone step ) {
59
- return factory ().createSlice (start , stop , 1 );
62
+ public PSlice doInt (int start , int stop , PNone step ) {
63
+ return factory ().createSlice (start , stop , castStep (step ));
60
64
}
61
65
62
- @ Specialization ( rewriteOn = ArithmeticException . class )
63
- public PSlice doLongExact ( long start , long stop , @ SuppressWarnings ( "unused" ) PNone step ) {
64
- return factory ().createSlice (PInt . intValueExact (start ), PInt . intValueExact (stop ), 1 );
66
+ @ Fallback
67
+ public PSlice doGeneric ( Object start , Object stop , Object step ) {
68
+ return factory ().createSlice (castStart (start ), castStop (stop ), castStep ( step ) );
65
69
}
66
70
67
- @ Specialization
68
- public PSlice doLongGeneric (long start , long stop , @ SuppressWarnings ("unused" ) PNone step ) {
69
- try {
70
- return factory ().createSlice (PInt .intValueExact (start ), PInt .intValueExact (stop ), 1 );
71
- } catch (ArithmeticException e ) {
72
- throw raiseIndexError ();
71
+ private int castStart (Object o ) {
72
+ if (castStartNode == null ) {
73
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
74
+ castStartNode = insert (CastToSliceComponentNode .create (MISSING_INDEX ));
73
75
}
76
+ return castStartNode .execute (o );
74
77
}
75
78
76
- @ Specialization (rewriteOn = ArithmeticException .class )
77
- public PSlice doPIntExact (PInt start , PInt stop , @ SuppressWarnings ("unused" ) PNone step ) {
78
- return factory ().createSlice (start .intValueExact (), stop .intValueExact (), 1 );
79
+ private int castStop (Object o ) {
80
+ if (castStopNode == null ) {
81
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
82
+ castStopNode = insert (CastToSliceComponentNode .create (MISSING_INDEX ));
83
+ }
84
+ return castStopNode .execute (o );
79
85
}
80
86
81
- @ Specialization
82
- public PSlice doPIntGeneric (PInt start , PInt stop , @ SuppressWarnings ("unused" ) PNone step ) {
83
- try {
84
- return factory ().createSlice (start .intValueExact (), stop .intValueExact (), 1 );
85
- } catch (ArithmeticException e ) {
86
- throw raiseIndexError ();
87
+ private int castStep (Object o ) {
88
+ if (castStepNode == null ) {
89
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
90
+ castStepNode = insert (CastToSliceComponentNode .create (1 ));
87
91
}
92
+ return castStepNode .execute (o );
88
93
}
89
94
90
- @ Specialization (rewriteOn = ArithmeticException .class )
91
- public PSlice doPIntLongExact (PInt start , long stop , @ SuppressWarnings ("unused" ) PNone step ) {
92
- return factory ().createSlice (start .intValueExact (), PInt .intValueExact (stop ), 1 );
93
- }
95
+ public abstract PNode getFirst ();
94
96
95
- @ Specialization
96
- public PSlice doPIntLongGeneric (PInt start , long stop , @ SuppressWarnings ("unused" ) PNone step ) {
97
- try {
98
- return factory ().createSlice (start .intValueExact (), PInt .intValueExact (stop ), 1 );
99
- } catch (ArithmeticException e ) {
100
- throw raiseIndexError ();
101
- }
102
- }
97
+ public abstract PNode getSecond ();
103
98
104
- @ Specialization (rewriteOn = ArithmeticException .class )
105
- public PSlice doLongPIntExact (long start , PInt stop , @ SuppressWarnings ("unused" ) PNone step ) {
106
- return factory ().createSlice (PInt .intValueExact (start ), stop .intValueExact (), 1 );
107
- }
99
+ public abstract PNode getThird ();
108
100
109
- @ Specialization
110
- public PSlice doLongPIntGeneric (long start , PInt stop , @ SuppressWarnings ("unused" ) PNone step ) {
111
- try {
112
- return factory ().createSlice (PInt .intValueExact (start ), stop .intValueExact (), 1 );
113
- } catch (ArithmeticException e ) {
114
- throw raiseIndexError ();
115
- }
101
+ public static SliceLiteralNode create (ExpressionNode lower , ExpressionNode upper , ExpressionNode step ) {
102
+ return SliceLiteralNodeGen .create (lower , upper , step );
116
103
}
117
104
118
- @ Specialization
119
- public PSlice doSlice (int start , @ SuppressWarnings ("unused" ) PNone stop , @ SuppressWarnings ("unused" ) PNone step ) {
120
- return factory ().createSlice (start , MISSING_INDEX , MISSING_INDEX );
105
+ public static SliceLiteralNode create () {
106
+ return SliceLiteralNodeGen .create (null , null , null );
121
107
}
122
108
123
- @ Specialization
124
- public PSlice doPSlice (long start , @ SuppressWarnings ("unused" ) PNone stop , @ SuppressWarnings ("unused" ) PNone step ) {
125
- try {
126
- return factory ().createSlice (PInt .intValueExact (start ), MISSING_INDEX , 1 );
127
- } catch (ArithmeticException e ) {
128
- throw raiseIndexError ();
129
- }
130
- }
109
+ abstract static class CastToSliceComponentNode extends PNodeWithContext {
131
110
132
- @ Specialization
133
- public PSlice doSlice (int start , @ SuppressWarnings ("unused" ) PNone stop , int step ) {
134
- return factory ().createSlice (start , MISSING_INDEX , step );
135
- }
111
+ private final int defaultValue ;
112
+ private final BranchProfile indexErrorProfile = BranchProfile .create ();
136
113
137
- @ Specialization
138
- public PSlice doSlice (@ SuppressWarnings ("unused" ) PNone start , int stop , @ SuppressWarnings ("unused" ) PNone step ) {
139
- return factory ().createSlice (MISSING_INDEX , stop , MISSING_INDEX );
140
- }
114
+ public CastToSliceComponentNode (int defaultValue ) {
115
+ this .defaultValue = defaultValue ;
116
+ }
141
117
142
- @ Specialization
143
- public PSlice doSlice (@ SuppressWarnings ("unused" ) PNone start , long stop , @ SuppressWarnings ("unused" ) PNone step ) {
144
- return factory ().createSlice (MISSING_INDEX , (int ) stop , MISSING_INDEX );
145
- }
118
+ public abstract int execute (int i );
146
119
147
- @ Specialization
148
- public PSlice doSlice (@ SuppressWarnings ("unused" ) PNone start , @ SuppressWarnings ("unused" ) PNone stop , int step ) {
149
- return factory ().createSlice (MISSING_INDEX , MISSING_INDEX , step );
150
- }
120
+ public abstract int execute (long i );
151
121
152
- @ Specialization
153
- public PSlice doSlice (@ SuppressWarnings ("unused" ) PNone start , @ SuppressWarnings ("unused" ) PNone stop , PInt step ) {
154
- return factory ().createSlice (MISSING_INDEX , MISSING_INDEX , step .intValueExact ());
155
- }
122
+ public abstract int execute (Object i );
156
123
157
- @ Specialization
158
- @ SuppressWarnings ("unused" )
159
- public PSlice doSlice (PNone start , PNone stop , PNone step ) {
160
- return factory ().createSlice (MISSING_INDEX , MISSING_INDEX , 1 );
161
- }
124
+ @ Specialization
125
+ int doNone (@ SuppressWarnings ("unused" ) PNone i ) {
126
+ return defaultValue ;
127
+ }
162
128
163
- public abstract PNode getFirst ();
129
+ @ Specialization
130
+ int doBoolean (boolean i ) {
131
+ return PInt .intValue (i );
132
+ }
164
133
165
- public abstract PNode getSecond ();
134
+ @ Specialization
135
+ int doInt (int i ) {
136
+ return i ;
137
+ }
166
138
167
- public abstract PNode getThird ();
139
+ @ Specialization
140
+ int doLong (long i ) {
141
+ try {
142
+ return PInt .intValueExact (i );
143
+ } catch (ArithmeticException e ) {
144
+ indexErrorProfile .enter ();
145
+ throw raiseIndexError ();
146
+ }
147
+ }
168
148
169
- public static SliceLiteralNode create (ExpressionNode lower , ExpressionNode upper , ExpressionNode step ) {
170
- return SliceLiteralNodeGen .create (lower , upper , step );
171
- }
149
+ @ Specialization
150
+ int doPInt (PInt i ) {
151
+ try {
152
+ return i .intValueExact ();
153
+ } catch (ArithmeticException e ) {
154
+ indexErrorProfile .enter ();
155
+ throw raiseIndexError ();
156
+ }
157
+ }
172
158
173
- public static SliceLiteralNode create () {
174
- return SliceLiteralNodeGen .create (null , null , null );
159
+ public static CastToSliceComponentNode create (int defaultValue ) {
160
+ return CastToSliceComponentNodeGen .create (defaultValue );
161
+ }
175
162
}
176
163
}
0 commit comments