37
37
import static com .oracle .graal .python .nodes .SpecialMethodNames .__LEN__ ;
38
38
import static com .oracle .graal .python .nodes .SpecialMethodNames .__LT__ ;
39
39
import static com .oracle .graal .python .nodes .SpecialMethodNames .__MUL__ ;
40
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__IMUL__ ;
40
41
import static com .oracle .graal .python .nodes .SpecialMethodNames .__NE__ ;
41
42
import static com .oracle .graal .python .nodes .SpecialMethodNames .__REPR__ ;
42
43
import static com .oracle .graal .python .nodes .SpecialMethodNames .__RMUL__ ;
@@ -1162,6 +1163,8 @@ protected boolean isNotSameStorage(PList left, PList right) {
1162
1163
@ Builtin (name = __MUL__ , fixedNumOfArguments = 2 )
1163
1164
@ GenerateNodeFactory
1164
1165
abstract static class MulNode extends PythonBuiltinNode {
1166
+ public static String CANNOT_FIT_MESSAGE = "cannot fit 'int' into an index-sized integer" ;
1167
+
1165
1168
@ Specialization
1166
1169
PList doPListInt (PList left , boolean right ,
1167
1170
@ Cached ("createClassProfile()" ) ValueProfile profile ) {
@@ -1184,7 +1187,7 @@ PList doPListBigInt(PList left, long right,
1184
1187
try {
1185
1188
return doPListInt (left , PInt .intValueExact (right ), profile );
1186
1189
} catch (ArithmeticException e ) {
1187
- throw raise (OverflowError , "cannot fit 'int' into an index-sized integer" );
1190
+ throw raise (OverflowError , CANNOT_FIT_MESSAGE );
1188
1191
}
1189
1192
}
1190
1193
@@ -1194,7 +1197,7 @@ PList doPListBigInt(PList left, PInt right,
1194
1197
try {
1195
1198
return doPListInt (left , right .intValueExact (), profile );
1196
1199
} catch (ArithmeticException | OutOfMemoryError e ) {
1197
- throw raise (OverflowError , "cannot fit 'int' into an index-sized integer" );
1200
+ throw raise (OverflowError , CANNOT_FIT_MESSAGE );
1198
1201
}
1199
1202
}
1200
1203
@@ -1205,6 +1208,257 @@ Object doGeneric(Object left, Object right) {
1205
1208
}
1206
1209
}
1207
1210
1211
+ @ Builtin (name = __IMUL__ , fixedNumOfArguments = 2 )
1212
+ @ GenerateNodeFactory
1213
+ abstract static class IMulNode extends PythonBuiltinNode {
1214
+
1215
+ public abstract PList execute (PList list , Object value );
1216
+
1217
+ @ Specialization (guards = "isEmptyStorage(list)" )
1218
+ PList doEmptyBoolean (PList list , @ SuppressWarnings ("unused" ) boolean right ) {
1219
+ return list ;
1220
+ }
1221
+
1222
+ @ Specialization (guards = "isEmptyStorage(list)" )
1223
+ PList doEmptyInt (PList list , @ SuppressWarnings ("unused" ) int right ) {
1224
+ return list ;
1225
+ }
1226
+
1227
+ @ Specialization (guards = "isEmptyStorage(list)" )
1228
+ PList doEmptyLong (PList list , long right ) {
1229
+ try {
1230
+ PInt .intValueExact (right );
1231
+ return list ;
1232
+ } catch (ArithmeticException e ) {
1233
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1234
+ }
1235
+ }
1236
+
1237
+ @ Specialization (guards = "isEmptyStorage(list)" )
1238
+ PList doEmptyPInt (PList list , PInt right ) {
1239
+ try {
1240
+ right .intValueExact ();
1241
+ return list ;
1242
+ } catch (ArithmeticException e ) {
1243
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1244
+ }
1245
+ }
1246
+
1247
+ @ Specialization (guards = "isIntStorage(list)" )
1248
+ PList doIntBoolean (PList list , boolean right ) {
1249
+ return doIntInt (list , right ? 1 : 0 );
1250
+ }
1251
+
1252
+ @ Specialization (guards = "isIntStorage(list)" )
1253
+ PList doIntInt (PList list , int right ) {
1254
+ IntSequenceStorage store = (IntSequenceStorage ) list .getSequenceStorage ();
1255
+ if (right < 1 ) {
1256
+ store .clear ();
1257
+ return list ;
1258
+ }
1259
+ try {
1260
+ IntSequenceStorage copy = (IntSequenceStorage ) store .copy ();
1261
+ for (int i = 1 ; i < right ; i ++) {
1262
+ store .extendWithIntStorage (copy );
1263
+ }
1264
+ return list ;
1265
+ } catch (OutOfMemoryError e ) {
1266
+ throw raise (MemoryError );
1267
+ } catch (ArithmeticException e ) {
1268
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1269
+ }
1270
+ }
1271
+
1272
+ @ Specialization (guards = "isIntStorage(list)" )
1273
+ PList doIntLong (PList list , long right ) {
1274
+ try {
1275
+ return doIntInt (list , PInt .intValueExact (right ));
1276
+ } catch (ArithmeticException e ) {
1277
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1278
+ }
1279
+ }
1280
+
1281
+ @ Specialization (guards = "isIntStorage(list)" )
1282
+ PList doIntPInt (PList list , PInt right ) {
1283
+ try {
1284
+ return doIntInt (list , right .intValueExact ());
1285
+ } catch (ArithmeticException e ) {
1286
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1287
+ }
1288
+ }
1289
+
1290
+ @ Specialization (guards = "isLongStorage(list)" )
1291
+ PList doLongBoolean (PList list , boolean right ) {
1292
+ return doLongInt (list , right ? 1 : 0 );
1293
+ }
1294
+
1295
+ @ Specialization (guards = "isLongStorage(list)" )
1296
+ PList doLongInt (PList list , int right ) {
1297
+ LongSequenceStorage store = (LongSequenceStorage ) list .getSequenceStorage ();
1298
+ if (right < 1 ) {
1299
+ store .clear ();
1300
+ return list ;
1301
+ }
1302
+ try {
1303
+ LongSequenceStorage copy = (LongSequenceStorage ) store .copy ();
1304
+ for (int i = 1 ; i < right ; i ++) {
1305
+ store .extendWithLongStorage (copy );
1306
+ }
1307
+ return list ;
1308
+ } catch (OutOfMemoryError e ) {
1309
+ throw raise (MemoryError );
1310
+ } catch (ArithmeticException e ) {
1311
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1312
+ }
1313
+ }
1314
+
1315
+ @ Specialization (guards = "isLongStorage(list)" )
1316
+ PList doLongLong (PList list , long right ) {
1317
+ try {
1318
+ return doLongInt (list , PInt .intValueExact (right ));
1319
+ } catch (ArithmeticException e ) {
1320
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1321
+ }
1322
+ }
1323
+
1324
+ @ Specialization (guards = "isLongStorage(list)" )
1325
+ PList doLongPInt (PList list , PInt right ) {
1326
+ try {
1327
+ return doLongInt (list , right .intValueExact ());
1328
+ } catch (ArithmeticException e ) {
1329
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1330
+ }
1331
+ }
1332
+
1333
+ @ Specialization (guards = "isDoubleStorage(list)" )
1334
+ PList doDoubleBoolean (PList list , boolean right ) {
1335
+ return doDoubleInt (list , right ? 1 : 0 );
1336
+ }
1337
+
1338
+ @ Specialization (guards = "isDoubleStorage(list)" )
1339
+ PList doDoubleInt (PList list , int right ) {
1340
+ DoubleSequenceStorage store = (DoubleSequenceStorage ) list .getSequenceStorage ();
1341
+ if (right < 1 ) {
1342
+ store .clear ();
1343
+ return list ;
1344
+ }
1345
+ try {
1346
+ DoubleSequenceStorage copy = (DoubleSequenceStorage ) store .copy ();
1347
+ for (int i = 1 ; i < right ; i ++) {
1348
+ store .extendWithDoubleStorage (copy );
1349
+ }
1350
+ return list ;
1351
+ } catch (OutOfMemoryError e ) {
1352
+ throw raise (MemoryError );
1353
+ } catch (ArithmeticException e ) {
1354
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1355
+ }
1356
+ }
1357
+
1358
+ @ Specialization (guards = "isDoubleStorage(list)" )
1359
+ PList doDoubleLong (PList list , long right ) {
1360
+ try {
1361
+ return doDoubleInt (list , PInt .intValueExact (right ));
1362
+ } catch (ArithmeticException e ) {
1363
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1364
+ }
1365
+ }
1366
+
1367
+ @ Specialization (guards = "isDoubleStorage(list)" )
1368
+ PList doDoublePInt (PList list , PInt right ) {
1369
+ try {
1370
+ return doLongInt (list , right .intValueExact ());
1371
+ } catch (ArithmeticException e ) {
1372
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1373
+ }
1374
+ }
1375
+
1376
+ @ Specialization (guards = "isObjectStorage(list)" )
1377
+ PList doObjectBoolean (PList list , boolean right ) {
1378
+ return doDoubleInt (list , right ? 1 : 0 );
1379
+ }
1380
+
1381
+ @ Specialization (guards = "isObjectStorage(list)" )
1382
+ PList doObjectInt (PList list , int right ) {
1383
+ ObjectSequenceStorage store = (ObjectSequenceStorage ) list .getSequenceStorage ();
1384
+ if (right < 1 ) {
1385
+ store .clear ();
1386
+ return list ;
1387
+ }
1388
+ try {
1389
+ ObjectSequenceStorage copy = (ObjectSequenceStorage ) store .copy ();
1390
+ for (int i = 1 ; i < right ; i ++) {
1391
+ store .extend (copy );
1392
+ }
1393
+ return list ;
1394
+ } catch (OutOfMemoryError e ) {
1395
+ throw raise (MemoryError );
1396
+ } catch (ArithmeticException e ) {
1397
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1398
+ }
1399
+ }
1400
+
1401
+ @ Specialization (guards = "isObjectStorage(list)" )
1402
+ PList doObjectLong (PList list , long right ) {
1403
+ try {
1404
+ return doObjectInt (list , PInt .intValueExact (right ));
1405
+ } catch (ArithmeticException e ) {
1406
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1407
+ }
1408
+ }
1409
+
1410
+ @ Specialization (guards = "isObjectStorage(list)" )
1411
+ PList doObjectPInt (PList list , PInt right ) {
1412
+ try {
1413
+ return doObjectInt (list , right .intValueExact ());
1414
+ } catch (ArithmeticException e ) {
1415
+ throw raise (OverflowError , MulNode .CANNOT_FIT_MESSAGE );
1416
+ }
1417
+ }
1418
+
1419
+ @ Specialization (guards = {"!isInt(right)" })
1420
+ Object doGeneric (PList list , Object right ,
1421
+ @ Cached ("create(__INDEX__)" ) LookupAndCallUnaryNode dispatchIndex ,
1422
+ @ Cached ("createIMulNode()" ) IMulNode imulNode ) {
1423
+ Object index = dispatchIndex .executeObject (right );
1424
+ if (index != PNone .NO_VALUE ) {
1425
+ int iIndex ;
1426
+ try {
1427
+ iIndex = convertToInt (index );
1428
+ } catch (ArithmeticException e ) {
1429
+ throw raise (OverflowError , "cannot fit '%p' into an index-sized integer" , index );
1430
+ }
1431
+
1432
+ return imulNode .execute (list , iIndex );
1433
+ }
1434
+ throw raise (TypeError , "can't multiply sequence by non-int of type '%p'" , right );
1435
+ }
1436
+
1437
+ private int convertToInt (Object value ) throws ArithmeticException {
1438
+ if (value instanceof Integer ) {
1439
+ return (Integer ) value ;
1440
+ }
1441
+ if (value instanceof Boolean ) {
1442
+ return (Boolean ) value ? 0 : 1 ;
1443
+ }
1444
+ if (value instanceof Long ) {
1445
+ return PInt .intValueExact ((Long ) value );
1446
+ }
1447
+ if (value instanceof PInt ) {
1448
+ return ((PInt ) value ).intValueExact ();
1449
+ }
1450
+ throw raise (TypeError , "can't multiply sequence by non-int of type '%p'" , value );
1451
+ }
1452
+
1453
+ protected IMulNode createIMulNode () {
1454
+ return ListBuiltinsFactory .IMulNodeFactory .create (new PNode [0 ]);
1455
+ }
1456
+
1457
+ protected boolean isInt (Object value ) {
1458
+ return value instanceof Boolean || value instanceof Integer || value instanceof Long || value instanceof PInt ;
1459
+ }
1460
+ }
1461
+
1208
1462
@ Builtin (name = __RMUL__ , fixedNumOfArguments = 2 )
1209
1463
@ GenerateNodeFactory
1210
1464
abstract static class RMulNode extends MulNode {
0 commit comments