4444import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
4545import com .oracle .graal .python .runtime .exception .PException ;
4646import com .oracle .graal .python .runtime .sequence .PSequence ;
47- import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
48- import com .oracle .truffle .api .CompilerDirectives ;
4947import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
5048import com .oracle .truffle .api .dsl .Cached ;
5149import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
@@ -103,69 +101,110 @@ PArray arrayWithSequenceInitializer(PythonClass cls, String typeCode, String str
103101 return factory ().createArray (cls , str .toCharArray ());
104102 }
105103
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 ,
111118 @ Cached ("create()" ) GetIteratorNode getIterator ,
112119 @ Cached ("create()" ) GetNextNode next ,
113120 @ 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" );
135143 }
144+ } else {
145+ throw raise (ValueError , "integer argument expected, got %p" , nextValue );
146+ }
147+ }
136148
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+ }
150151
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+ }
164176
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+ }
168205 }
206+
207+ return factory ().createArray (cls , doubleArray );
169208 }
170209
171210 @ Specialization
@@ -191,12 +230,7 @@ private PArray makeEmptyArray(PythonClass cls, char type) {
191230
192231 @ TruffleBoundary
193232 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 );
200234 }
201235 }
202236}
0 commit comments