44
44
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
45
45
import com .oracle .graal .python .runtime .exception .PException ;
46
46
import com .oracle .graal .python .runtime .sequence .PSequence ;
47
- import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
48
- import com .oracle .truffle .api .CompilerDirectives ;
49
47
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
50
48
import com .oracle .truffle .api .dsl .Cached ;
51
49
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
@@ -103,69 +101,110 @@ PArray arrayWithSequenceInitializer(PythonClass cls, String typeCode, String str
103
101
return factory ().createArray (cls , str .toCharArray ());
104
102
}
105
103
106
- /**
107
- * @param cls
108
- */
109
- @ Specialization
110
- PArray arrayWithSequenceInitializer (PythonClass cls , String typeCode , PSequence initializer ,
104
+ protected boolean isIntArray (String typeCode ) {
105
+ return typeCode .charAt (0 ) == 'i' ;
106
+ }
107
+
108
+ protected boolean isByteArray (String typeCode ) {
109
+ return typeCode .charAt (0 ) == 'b' ;
110
+ }
111
+
112
+ protected boolean isDoubleArray (String typeCode ) {
113
+ return typeCode .charAt (0 ) == 'd' ;
114
+ }
115
+
116
+ @ Specialization (guards = "isByteArray(typeCode)" )
117
+ PArray arrayByteInitializer (PythonClass cls , @ SuppressWarnings ("unused" ) String typeCode , PSequence initializer ,
111
118
@ Cached ("create()" ) GetIteratorNode getIterator ,
112
119
@ Cached ("create()" ) GetNextNode next ,
113
120
@ Cached ("createBinaryProfile()" ) ConditionProfile errorProfile ) {
114
- SequenceStorage store ;
115
- switch (typeCode .charAt (0 )) {
116
- case 'i' :
117
- Object iter = getIterator .executeWith (initializer );
118
- int [] intArray = new int [initializer .len ()];
119
- int i = 0 ;
120
-
121
- while (true ) {
122
- Object nextValue ;
123
- try {
124
- nextValue = next .execute (iter );
125
- } catch (PException e ) {
126
- e .expectStopIteration (getCore (), errorProfile );
127
- break ;
128
- }
129
- if (nextValue instanceof Integer ) {
130
- intArray [i ++] = (int ) nextValue ;
131
- } else {
132
- CompilerDirectives .transferToInterpreter ();
133
- operandTypeError ();
134
- }
121
+ Object iter = getIterator .executeWith (initializer );
122
+ int i = 0 ;
123
+ byte [] byteArray = new byte [initializer .len ()];
124
+
125
+ while (true ) {
126
+ Object nextValue ;
127
+ try {
128
+ nextValue = next .execute (iter );
129
+ } catch (PException e ) {
130
+ e .expectStopIteration (getCore (), errorProfile );
131
+ break ;
132
+ }
133
+
134
+ if (nextValue instanceof Byte ) {
135
+ byteArray [i ++] = (byte ) nextValue ;
136
+ }
137
+ if (nextValue instanceof Integer ) {
138
+ int intValue = (int ) nextValue ;
139
+ if (0 <= intValue && intValue <= 255 ) {
140
+ byteArray [i ++] = (byte ) intValue ;
141
+ } else {
142
+ throw raise (ValueError , "signed char is greater than maximum" );
135
143
}
144
+ } else {
145
+ throw raise (ValueError , "integer argument expected, got %p" , nextValue );
146
+ }
147
+ }
136
148
137
- return factory ().createArray (cls , intArray );
138
- case 'd' :
139
- store = initializer .getSequenceStorage ();
140
- double [] doubleArray = new double [store .length ()];
141
-
142
- for (i = 0 ; i < doubleArray .length ; i ++) {
143
- Object val = store .getItemNormalized (i );
144
- if (val instanceof Number ) {
145
- doubleArray [i ] = ((Number ) val ).doubleValue ();
146
- } else {
147
- throw raise (ValueError , "double value expected" );
148
- }
149
- }
149
+ return factory ().createArray (cls , byteArray );
150
+ }
150
151
151
- return factory ().createArray (cls , doubleArray );
152
- case 'b' :
153
- store = initializer .getSequenceStorage ();
154
- byte [] byteArray = new byte [store .length ()];
155
-
156
- for (i = 0 ; i < byteArray .length ; i ++) {
157
- Object val = store .getItemNormalized (i );
158
- if (val instanceof Number ) {
159
- byteArray [i ] = ((Number ) val ).byteValue ();
160
- } else {
161
- throw raise (ValueError , "byte value expected" );
162
- }
163
- }
152
+ @ Specialization (guards = "isIntArray(typeCode)" )
153
+ PArray arrayIntInitializer (PythonClass cls , @ SuppressWarnings ("unused" ) String typeCode , PSequence initializer ,
154
+ @ Cached ("create()" ) GetIteratorNode getIterator ,
155
+ @ Cached ("create()" ) GetNextNode next ,
156
+ @ Cached ("createBinaryProfile()" ) ConditionProfile errorProfile ) {
157
+ Object iter = getIterator .executeWith (initializer );
158
+ int i = 0 ;
159
+
160
+ int [] intArray = new int [initializer .len ()];
161
+
162
+ while (true ) {
163
+ Object nextValue ;
164
+ try {
165
+ nextValue = next .execute (iter );
166
+ } catch (PException e ) {
167
+ e .expectStopIteration (getCore (), errorProfile );
168
+ break ;
169
+ }
170
+ if (nextValue instanceof Integer ) {
171
+ intArray [i ++] = (int ) nextValue ;
172
+ } else {
173
+ throw raise (ValueError , "integer argument expected, got %p" , nextValue );
174
+ }
175
+ }
164
176
165
- return factory ().createArray (cls , byteArray );
166
- default :
167
- return null ;
177
+ return factory ().createArray (cls , intArray );
178
+ }
179
+
180
+ @ Specialization (guards = "isDoubleArray(typeCode)" )
181
+ PArray arrayDoubleInitializer (PythonClass cls , @ SuppressWarnings ("unused" ) String typeCode , PSequence initializer ,
182
+ @ Cached ("create()" ) GetIteratorNode getIterator ,
183
+ @ Cached ("create()" ) GetNextNode next ,
184
+ @ Cached ("createBinaryProfile()" ) ConditionProfile errorProfile ) {
185
+ Object iter = getIterator .executeWith (initializer );
186
+ int i = 0 ;
187
+
188
+ double [] doubleArray = new double [initializer .len ()];
189
+
190
+ while (true ) {
191
+ Object nextValue ;
192
+ try {
193
+ nextValue = next .execute (iter );
194
+ } catch (PException e ) {
195
+ e .expectStopIteration (getCore (), errorProfile );
196
+ break ;
197
+ }
198
+ if (nextValue instanceof Integer ) {
199
+ doubleArray [i ++] = ((Integer ) nextValue ).doubleValue ();
200
+ } else if (nextValue instanceof Double ) {
201
+ doubleArray [i ++] = (double ) nextValue ;
202
+ } else {
203
+ throw raise (ValueError , "double value expected" );
204
+ }
168
205
}
206
+
207
+ return factory ().createArray (cls , doubleArray );
169
208
}
170
209
171
210
@ Specialization
@@ -191,12 +230,7 @@ private PArray makeEmptyArray(PythonClass cls, char type) {
191
230
192
231
@ TruffleBoundary
193
232
private void typeError (String typeCode , Object initializer ) {
194
- throw raise (TypeError , "unsupported operand type: %s %s and 'array.array'" , typeCode , initializer );
195
- }
196
-
197
- @ TruffleBoundary
198
- private static void operandTypeError () {
199
- throw new RuntimeException ("Unexpected argument type for array() " );
233
+ throw raise (TypeError , "cannot use a %p to initialize an array with typecode '%s'" , initializer , typeCode );
200
234
}
201
235
}
202
236
}
0 commit comments