72
72
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___INSTANCECHECK__ ;
73
73
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___LEN__ ;
74
74
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___NEXT__ ;
75
+ import static com .oracle .graal .python .nodes .StringLiterals .T_COMMA_SPACE ;
76
+ import static com .oracle .graal .python .nodes .StringLiterals .T_ELLIPSIS_IN_BRACKETS ;
77
+ import static com .oracle .graal .python .nodes .StringLiterals .T_EMPTY_BRACKETS ;
78
+ import static com .oracle .graal .python .nodes .StringLiterals .T_LBRACKET ;
79
+ import static com .oracle .graal .python .nodes .StringLiterals .T_NONE ;
80
+ import static com .oracle .graal .python .nodes .StringLiterals .T_RBRACKET ;
75
81
import static com .oracle .graal .python .util .PythonUtils .TS_ENCODING ;
76
82
77
83
import java .math .BigInteger ;
90
96
import com .oracle .graal .python .builtins .objects .PythonAbstractObject ;
91
97
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
92
98
import com .oracle .graal .python .builtins .objects .ints .PInt ;
93
- import com .oracle .graal .python .builtins .objects .iterator .PForeignArrayIterator ;
94
99
import com .oracle .graal .python .builtins .objects .object .ObjectBuiltins ;
95
100
import com .oracle .graal .python .builtins .objects .object .ObjectNodes ;
96
101
import com .oracle .graal .python .builtins .objects .str .StringBuiltins ;
97
- import com .oracle .graal .python .builtins .objects .type .SpecialMethodSlot ;
98
102
import com .oracle .graal .python .builtins .objects .type .TpSlots ;
99
103
import com .oracle .graal .python .builtins .objects .type .slots .TpSlotBinaryFunc .MpSubscriptBuiltinNode ;
100
104
import com .oracle .graal .python .builtins .objects .type .slots .TpSlotGetAttr .GetAttrBuiltinNode ;
103
107
import com .oracle .graal .python .builtins .objects .type .slots .TpSlotSetAttr .SetAttrBuiltinNode ;
104
108
import com .oracle .graal .python .builtins .objects .type .slots .TpSlotSizeArgFun .SqItemBuiltinNode ;
105
109
import com .oracle .graal .python .lib .PyNumberAsSizeNode ;
110
+ import com .oracle .graal .python .lib .PyObjectReprAsTruffleStringNode ;
106
111
import com .oracle .graal .python .lib .PyObjectRichCompareBool ;
112
+ import com .oracle .graal .python .lib .PyObjectStrAsTruffleStringNode ;
107
113
import com .oracle .graal .python .nodes .ErrorMessages ;
108
114
import com .oracle .graal .python .nodes .PGuards ;
109
115
import com .oracle .graal .python .nodes .PRaiseNode ;
110
- import com .oracle .graal .python .nodes .call .special .LookupAndCallUnaryNode ;
111
116
import com .oracle .graal .python .nodes .expression .BinaryArithmetic ;
112
117
import com .oracle .graal .python .nodes .expression .BinaryArithmetic .BitAndNode ;
113
118
import com .oracle .graal .python .nodes .expression .BinaryArithmetic .BitOrNode ;
114
119
import com .oracle .graal .python .nodes .expression .BinaryArithmetic .BitXorNode ;
115
120
import com .oracle .graal .python .nodes .expression .BinaryComparisonNode ;
116
121
import com .oracle .graal .python .nodes .expression .BinaryOpNode ;
117
- import com .oracle .graal .python .nodes .expression .CastToListExpressionNode .CastToListNode ;
118
122
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
119
123
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
120
124
import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
162
166
import com .oracle .truffle .api .profiles .InlinedBranchProfile ;
163
167
import com .oracle .truffle .api .profiles .InlinedConditionProfile ;
164
168
import com .oracle .truffle .api .strings .TruffleString ;
169
+ import com .oracle .truffle .api .strings .TruffleStringBuilder ;
165
170
166
171
@ CoreFunctions (extendClasses = PythonBuiltinClassType .ForeignObject )
167
172
public final class ForeignObjectBuiltins extends PythonBuiltins {
@@ -1190,27 +1195,25 @@ protected static Object doIt(Object object,
1190
1195
@ Builtin (name = J___STR__ , minNumOfPositionalArgs = 1 )
1191
1196
@ GenerateNodeFactory
1192
1197
abstract static class StrNode extends PythonUnaryBuiltinNode {
1193
- @ Child private LookupAndCallUnaryNode callStrNode ;
1194
- @ Child private CastToListNode castToListNode ;
1195
1198
@ Child private TruffleString .SwitchEncodingNode switchEncodingNode ;
1196
1199
1197
1200
@ Specialization
1198
1201
Object str (VirtualFrame frame , Object object ,
1199
1202
@ Bind ("this" ) Node inliningTarget ,
1200
1203
@ CachedLibrary (limit = "3" ) InteropLibrary lib ,
1201
1204
@ Cached GilNode gil ,
1205
+ @ Cached PyObjectStrAsTruffleStringNode strNode ,
1206
+ @ Cached StrForeignArrayNode strForeignArrayNode ,
1202
1207
@ Cached InlinedBranchProfile isNull ,
1203
1208
@ Cached InlinedBranchProfile isBoolean ,
1204
1209
@ Cached InlinedBranchProfile isString ,
1205
1210
@ Cached InlinedBranchProfile isLong ,
1206
1211
@ Cached InlinedBranchProfile isDouble ,
1207
- @ Cached InlinedBranchProfile isArray ,
1208
- @ Cached InlinedBranchProfile defaultCase ,
1209
- @ Cached PythonObjectFactory .Lazy factory ) {
1212
+ @ Cached InlinedBranchProfile defaultCase ) {
1210
1213
try {
1211
1214
if (lib .isNull (object )) {
1212
1215
isNull .enter (inliningTarget );
1213
- return getCallStrNode (). executeObject ( frame , PNone . NONE ) ;
1216
+ return T_NONE ;
1214
1217
} else if (lib .isBoolean (object )) {
1215
1218
isBoolean .enter (inliningTarget );
1216
1219
boolean value ;
@@ -1220,7 +1223,7 @@ Object str(VirtualFrame frame, Object object,
1220
1223
} finally {
1221
1224
gil .acquire ();
1222
1225
}
1223
- return getCallStrNode (). executeObject (frame , value );
1226
+ return strNode . execute (frame , inliningTarget , value );
1224
1227
} else if (lib .isString (object )) {
1225
1228
isString .enter (inliningTarget );
1226
1229
TruffleString value ;
@@ -1230,7 +1233,7 @@ Object str(VirtualFrame frame, Object object,
1230
1233
} finally {
1231
1234
gil .acquire ();
1232
1235
}
1233
- return getCallStrNode (). executeObject (frame , getSwitchEncodingNode ().execute (value , TS_ENCODING ));
1236
+ return strNode . execute (frame , inliningTarget , getSwitchEncodingNode ().execute (value , TS_ENCODING ));
1234
1237
} else if (lib .fitsInLong (object )) {
1235
1238
isLong .enter (inliningTarget );
1236
1239
long value ;
@@ -1240,7 +1243,7 @@ Object str(VirtualFrame frame, Object object,
1240
1243
} finally {
1241
1244
gil .acquire ();
1242
1245
}
1243
- return getCallStrNode (). executeObject (frame , value );
1246
+ return strNode . execute (frame , inliningTarget , value );
1244
1247
} else if (lib .fitsInDouble (object )) {
1245
1248
isDouble .enter (inliningTarget );
1246
1249
double value ;
@@ -1250,20 +1253,9 @@ Object str(VirtualFrame frame, Object object,
1250
1253
} finally {
1251
1254
gil .acquire ();
1252
1255
}
1253
- return getCallStrNode (). executeObject (frame , value );
1256
+ return strNode . execute (frame , inliningTarget , value );
1254
1257
} else if (lib .hasArrayElements (object )) {
1255
- isArray .enter (inliningTarget );
1256
- long size ;
1257
- gil .release (true );
1258
- try {
1259
- size = lib .getArraySize (object );
1260
- } finally {
1261
- gil .acquire ();
1262
- }
1263
- if (size <= Integer .MAX_VALUE && size >= 0 ) {
1264
- PForeignArrayIterator iterable = factory .get (inliningTarget ).createForeignArrayIterator (object );
1265
- return getCallStrNode ().executeObject (frame , getCastToListNode ().execute (frame , iterable ));
1266
- }
1258
+ return strForeignArrayNode .execute (frame , object , lib );
1267
1259
}
1268
1260
} catch (UnsupportedMessageException e ) {
1269
1261
// Fall back to the generic impl
@@ -1272,22 +1264,6 @@ Object str(VirtualFrame frame, Object object,
1272
1264
return defaultConversion (frame , lib , object );
1273
1265
}
1274
1266
1275
- private LookupAndCallUnaryNode getCallStrNode () {
1276
- if (callStrNode == null ) {
1277
- CompilerDirectives .transferToInterpreterAndInvalidate ();
1278
- callStrNode = insert (LookupAndCallUnaryNode .create (SpecialMethodSlot .Str ));
1279
- }
1280
- return callStrNode ;
1281
- }
1282
-
1283
- private CastToListNode getCastToListNode () {
1284
- if (castToListNode == null ) {
1285
- CompilerDirectives .transferToInterpreterAndInvalidate ();
1286
- castToListNode = insert (CastToListNode .create ());
1287
- }
1288
- return castToListNode ;
1289
- }
1290
-
1291
1267
protected TruffleString .SwitchEncodingNode getSwitchEncodingNode () {
1292
1268
if (switchEncodingNode == null ) {
1293
1269
CompilerDirectives .transferToInterpreterAndInvalidate ();
@@ -1305,6 +1281,60 @@ protected TruffleString defaultConversion(@SuppressWarnings("unused") VirtualFra
1305
1281
}
1306
1282
}
1307
1283
1284
+ @ GenerateInline (false ) // Uncommon path
1285
+ abstract static class StrForeignArrayNode extends Node {
1286
+ abstract TruffleString execute (VirtualFrame frame , Object object , InteropLibrary lib ) throws UnsupportedMessageException ;
1287
+
1288
+ @ Specialization
1289
+ static TruffleString str (VirtualFrame frame , Object object , InteropLibrary lib ,
1290
+ @ Bind ("this" ) Node inliningTarget ,
1291
+ @ Cached GilNode gil ,
1292
+ @ Cached PyObjectReprAsTruffleStringNode reprNode ,
1293
+ @ Cached TruffleStringBuilder .AppendStringNode appendStringNode ,
1294
+ @ Cached TruffleStringBuilder .ToStringNode toStringNode ) throws UnsupportedMessageException {
1295
+ if (!PythonContext .get (inliningTarget ).reprEnter (object )) {
1296
+ return T_ELLIPSIS_IN_BRACKETS ;
1297
+ }
1298
+ try {
1299
+ long length ;
1300
+ gil .release (true );
1301
+ try {
1302
+ length = lib .getArraySize (object );
1303
+ } finally {
1304
+ gil .acquire ();
1305
+ }
1306
+ if (length == 0 ) {
1307
+ return T_EMPTY_BRACKETS ;
1308
+ }
1309
+ TruffleStringBuilder buf = TruffleStringBuilder .create (TS_ENCODING );
1310
+ appendStringNode .execute (buf , T_LBRACKET );
1311
+ boolean initial = true ;
1312
+ for (int index = 0 ; index < length ; index ++) {
1313
+ if (initial ) {
1314
+ initial = false ;
1315
+ } else {
1316
+ appendStringNode .execute (buf , T_COMMA_SPACE );
1317
+ }
1318
+ Object value ;
1319
+ gil .release (true );
1320
+ try {
1321
+ value = lib .readArrayElement (object , index );
1322
+ } catch (InvalidArrayIndexException e ) {
1323
+ // Concurrent modification?
1324
+ break ;
1325
+ } finally {
1326
+ gil .acquire ();
1327
+ }
1328
+ appendStringNode .execute (buf , reprNode .execute (frame , inliningTarget , value ));
1329
+ }
1330
+ appendStringNode .execute (buf , T_RBRACKET );
1331
+ return toStringNode .execute (buf );
1332
+ } finally {
1333
+ PythonContext .get (inliningTarget ).reprLeave (object );
1334
+ }
1335
+ }
1336
+ }
1337
+
1308
1338
@ Builtin (name = J___REPR__ , minNumOfPositionalArgs = 1 )
1309
1339
@ GenerateNodeFactory
1310
1340
abstract static class ReprNode extends StrNode {
0 commit comments