25
25
*/
26
26
package com .oracle .graal .python .builtins .modules ;
27
27
28
+ import static com .oracle .graal .python .runtime .exception .PythonErrorType .MemoryError ;
28
29
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
29
30
import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
30
31
60
61
import com .oracle .graal .python .runtime .exception .PException ;
61
62
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
62
63
import com .oracle .graal .python .util .BufferFormat ;
64
+ import com .oracle .graal .python .util .OverflowException ;
65
+ import com .oracle .graal .python .util .PythonUtils ;
63
66
import com .oracle .truffle .api .CompilerDirectives ;
67
+ import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
64
68
import com .oracle .truffle .api .dsl .Cached ;
65
69
import com .oracle .truffle .api .dsl .Fallback ;
66
70
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
70
74
import com .oracle .truffle .api .frame .VirtualFrame ;
71
75
import com .oracle .truffle .api .library .CachedLibrary ;
72
76
import com .oracle .truffle .api .nodes .Node ;
77
+ import com .oracle .truffle .api .profiles .ValueProfile ;
73
78
74
79
@ CoreFunctions (defineModule = "array" )
75
80
public final class ArrayModuleBuiltins extends PythonBuiltins {
@@ -142,6 +147,7 @@ public final Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused"
142
147
abstract static class ArrayNodeInternal extends Node {
143
148
@ Child private PRaiseNode raiseNode ;
144
149
@ Child private PythonObjectFactory factory ;
150
+ @ CompilationFinal private ValueProfile formatProfile = ValueProfile .createIdentityProfile ();
145
151
146
152
public abstract PArray execute (VirtualFrame frame , Object cls , String typeCode , Object initializer );
147
153
@@ -155,7 +161,13 @@ PArray array(Object cls, String typeCode, @SuppressWarnings("unused") PNone init
155
161
PArray arrayWithRangeInitializer (Object cls , String typeCode , PIntRange range ,
156
162
@ Cached ArrayNodes .PutValueNode putValueNode ) {
157
163
BufferFormat format = getFormatChecked (typeCode );
158
- PArray array = getFactory ().createArray (cls , typeCode , format , range .getIntLength ());
164
+ PArray array ;
165
+ try {
166
+ array = getFactory ().createArray (cls , typeCode , format , range .getIntLength ());
167
+ } catch (OverflowException e ) {
168
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
169
+ throw raise (MemoryError );
170
+ }
159
171
160
172
int start = range .getIntStart ();
161
173
int stop = range .getIntStop ();
@@ -178,7 +190,7 @@ PArray arrayWithBytesInitializer(VirtualFrame frame, Object cls, String typeCode
178
190
179
191
// TODO impl for PSequence and PArray or use lenght_hint
180
192
181
- @ Specialization (limit = "3" )
193
+ @ Specialization (guards = "!isBytes(initializer)" , limit = "3" )
182
194
PArray arrayIteratorInitializer (VirtualFrame frame , Object cls , String typeCode , Object initializer ,
183
195
@ CachedLibrary ("initializer" ) PythonObjectLibrary lib ,
184
196
@ Cached ArrayNodes .PutValueNode putValueNode ,
@@ -189,7 +201,7 @@ PArray arrayIteratorInitializer(VirtualFrame frame, Object cls, String typeCode,
189
201
BufferFormat format = getFormatChecked (typeCode );
190
202
PArray array = getFactory ().createArray (cls , typeCode , format );
191
203
192
- int lenght = 0 ;
204
+ int length = 0 ;
193
205
while (true ) {
194
206
Object nextValue ;
195
207
try {
@@ -198,11 +210,17 @@ PArray arrayIteratorInitializer(VirtualFrame frame, Object cls, String typeCode,
198
210
e .expectStopIteration (errorProfile );
199
211
break ;
200
212
}
201
- array .ensureCapacity (++lenght );
202
- putValueNode .execute (frame , array , lenght - 1 , nextValue );
213
+ try {
214
+ length = PythonUtils .addExact (length , 1 );
215
+ array .ensureCapacity (length );
216
+ } catch (OverflowException e ) {
217
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
218
+ throw raise (MemoryError );
219
+ }
220
+ putValueNode .execute (frame , array , length - 1 , nextValue );
203
221
}
204
222
205
- array .setLenght (lenght );
223
+ array .setLenght (length );
206
224
return array ;
207
225
}
208
226
@@ -214,7 +232,7 @@ private BufferFormat getFormatChecked(String typeCode) {
214
232
if (format == null ) {
215
233
throw raise (ValueError , "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)" );
216
234
}
217
- return format ;
235
+ return formatProfile . profile ( format ) ;
218
236
}
219
237
220
238
private PException raise (PythonBuiltinClassType type , String message , Object ... args ) {
@@ -225,6 +243,14 @@ private PException raise(PythonBuiltinClassType type, String message, Object...
225
243
throw raiseNode .raise (type , message , args );
226
244
}
227
245
246
+ private PException raise (PythonBuiltinClassType type ) {
247
+ if (raiseNode == null ) {
248
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
249
+ raiseNode = insert (PRaiseNode .create ());
250
+ }
251
+ throw raiseNode .raise (type );
252
+ }
253
+
228
254
private PythonObjectFactory getFactory () {
229
255
if (factory == null ) {
230
256
CompilerDirectives .transferToInterpreterAndInvalidate ();
0 commit comments