58
58
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
59
59
import com .oracle .graal .python .builtins .PythonBuiltins ;
60
60
import com .oracle .graal .python .builtins .objects .PNone ;
61
- import com .oracle .graal .python .builtins .objects .bytes .BytesNodes ;
62
61
import com .oracle .graal .python .builtins .objects .bytes .PBytes ;
63
- import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
64
62
import com .oracle .graal .python .builtins .objects .exception .OSErrorEnum ;
65
63
import com .oracle .graal .python .builtins .objects .exception .OSErrorEnum .ErrorAndMessagePair ;
66
64
import com .oracle .graal .python .builtins .objects .function .PArguments ;
67
65
import com .oracle .graal .python .builtins .objects .list .PList ;
68
66
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
69
- import com .oracle .graal .python .builtins .objects .str .PString ;
70
67
import com .oracle .graal .python .nodes .ErrorMessages ;
71
68
import com .oracle .graal .python .nodes .PGuards ;
72
69
import com .oracle .graal .python .nodes .expression .CastToListExpressionNode .CastToListNode ;
86
83
import com .oracle .truffle .api .dsl .NodeFactory ;
87
84
import com .oracle .truffle .api .dsl .Specialization ;
88
85
import com .oracle .truffle .api .frame .VirtualFrame ;
86
+ import com .oracle .truffle .api .interop .UnsupportedMessageException ;
89
87
import com .oracle .truffle .api .library .CachedLibrary ;
90
88
91
89
@ CoreFunctions (defineModule = "_posixsubprocess" )
@@ -102,21 +100,18 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
102
100
abstract static class ForkExecNode extends PythonBuiltinNode {
103
101
private static final TruffleLogger LOGGER = PythonLanguage .getLogger (ForkExecNode .class );
104
102
105
- @ Child private BytesNodes .ToBytesNode toBytes = BytesNodes .ToBytesNode .create ();
106
-
107
103
@ Specialization
108
104
int forkExec (VirtualFrame frame , PList args , @ SuppressWarnings ("unused" ) PList execList , @ SuppressWarnings ("unused" ) boolean closeFds ,
109
105
@ SuppressWarnings ("unused" ) PList fdsToKeep , String cwd , PList env ,
110
106
int p2cread , int p2cwrite , int c2pread , int c2pwrite ,
111
107
int errread , int errwrite , @ SuppressWarnings ("unused" ) int errpipe_read , int errpipe_write ,
112
- @ SuppressWarnings ("unused" ) boolean restore_signals , @ SuppressWarnings ("unused" ) boolean call_setsid , @ SuppressWarnings ("unused" ) PNone preexec_fn ,
113
- @ Cached SequenceStorageNodes .CopyInternalArrayNode copy ) {
108
+ @ SuppressWarnings ("unused" ) boolean restore_signals , @ SuppressWarnings ("unused" ) boolean call_setsid , @ SuppressWarnings ("unused" ) PNone preexec_fn ) {
114
109
115
110
PythonContext context = getContext ();
116
111
Object state = IndirectCallContext .enter (frame , context , this );
117
112
try {
118
113
return forkExec (args , execList , closeFds , fdsToKeep , cwd , env , p2cread , p2cwrite , c2pread , c2pwrite , errread , errwrite , errpipe_read , errpipe_write , restore_signals , call_setsid ,
119
- preexec_fn , copy );
114
+ preexec_fn );
120
115
} finally {
121
116
IndirectCallContext .exit (frame , context , state );
122
117
}
@@ -127,22 +122,20 @@ private synchronized int forkExec(PList args, PList execList, @SuppressWarnings(
127
122
@ SuppressWarnings ("unused" ) PList fdsToKeep , String cwd , PList env ,
128
123
int p2cread , int p2cwrite , int c2pread , int c2pwrite ,
129
124
int errread , int errwrite , @ SuppressWarnings ("unused" ) int errpipe_read , int errpipe_write ,
130
- @ SuppressWarnings ("unused" ) boolean restore_signals , @ SuppressWarnings ("unused" ) boolean call_setsid , @ SuppressWarnings ("unused" ) PNone preexec_fn ,
131
- @ Cached SequenceStorageNodes .CopyInternalArrayNode copy ) {
125
+ @ SuppressWarnings ("unused" ) boolean restore_signals , @ SuppressWarnings ("unused" ) boolean call_setsid , @ SuppressWarnings ("unused" ) PNone preexec_fn ) {
132
126
PythonContext context = getContext ();
133
127
PosixResources resources = context .getResources ();
134
128
if (!context .isExecutableAccessAllowed ()) {
135
129
return -1 ;
136
130
}
137
131
138
- ArrayList <String > argStrings = new ArrayList <>();
139
- Object [] copyOfInternalArray = copy .execute (args .getSequenceStorage ());
140
- for (Object o : copyOfInternalArray ) {
141
- if (o instanceof String ) {
142
- argStrings .add ((String ) o );
143
- } else if (o instanceof PString ) {
144
- argStrings .add (((PString ) o ).getValue ());
145
- } else {
132
+ SequenceStorage argsStorage = args .getSequenceStorage ();
133
+ ArrayList <String > argStrings = new ArrayList <>(argsStorage .length ());
134
+ CastToJavaStringNode castToStringNode = CastToJavaStringNode .getUncached ();
135
+ for (int i = 0 ; i < argsStorage .length (); i ++) {
136
+ try {
137
+ argStrings .add (castToStringNode .execute (argsStorage .getItemNormalized (i )));
138
+ } catch (CannotCastException ex ) {
146
139
throw raise (PythonBuiltinClassType .OSError , ErrorMessages .ILLEGAL_ARG );
147
140
}
148
141
}
@@ -158,16 +151,19 @@ private synchronized int forkExec(PList args, PList execList, @SuppressWarnings(
158
151
throw raise (PythonBuiltinClassType .OSError , e );
159
152
}
160
153
161
- HashMap <String , String > envMap = new HashMap <>(env .getSequenceStorage ().length ());
162
- for (Object keyValue : env .getSequenceStorage ().getInternalArray ()) {
163
- if (keyValue instanceof PBytes ) {
164
- // NOTE: passing 'null' frame means we took care of the global state in the
165
- // callers
166
- String str = checkNullBytesAndEncode (toBytes .execute (null , keyValue ));
167
- String [] strings = str .split ("=" , 2 );
168
- if (strings .length == 2 ) {
169
- envMap .put (strings [0 ], strings [1 ]);
170
- }
154
+ SequenceStorage envStorage = env .getSequenceStorage ();
155
+ HashMap <String , String > envMap = new HashMap <>(envStorage .length ());
156
+ PythonObjectLibrary pyLib = PythonObjectLibrary .getUncached ();
157
+ for (int i = 0 ; i < envStorage .length (); i ++) {
158
+ Object keyValue = envStorage .getItemNormalized (i );
159
+ if (!(keyValue instanceof PBytes )) {
160
+ continue ;
161
+ }
162
+ // NOTE: passing 'null' frame means we took care of the global state in the callers
163
+ String str = checkNullBytesAndEncode (pyLib , (PBytes ) keyValue );
164
+ String [] strings = str .split ("=" , 2 );
165
+ if (strings .length == 2 ) {
166
+ envMap .put (strings [0 ], strings [1 ]);
171
167
}
172
168
}
173
169
@@ -198,7 +194,7 @@ private synchronized int forkExec(PList args, PList execList, @SuppressWarnings(
198
194
if (!(item instanceof PBytes )) {
199
195
throw raise (PythonBuiltinClassType .TypeError , ErrorMessages .EXPECTED_BYTES_P_FOUND , item );
200
196
}
201
- String path = checkNullBytesAndEncode (toBytes . execute ( null , item ) );
197
+ String path = checkNullBytesAndEncode (pyLib , ( PBytes ) item );
202
198
int executableListLen = 0 ;
203
199
if (path .equals (context .getOption (PythonOptions .Executable ))) {
204
200
// In case someone passed to us sys.executable that happens to be java command
@@ -289,7 +285,13 @@ private int exec(ArrayList<String> argStrings, File cwd, Map<String, String> env
289
285
return resources .registerChild (process );
290
286
}
291
287
292
- private String checkNullBytesAndEncode (byte [] bytes ) {
288
+ private String checkNullBytesAndEncode (PythonObjectLibrary pyLib , PBytes bytesObj ) {
289
+ byte [] bytes ;
290
+ try {
291
+ bytes = pyLib .getBufferBytes (bytesObj );
292
+ } catch (UnsupportedMessageException e ) {
293
+ throw new AssertionError (); // should not happen
294
+ }
293
295
for (byte b : bytes ) {
294
296
if (b == 0 ) {
295
297
throw raise (PythonBuiltinClassType .ValueError , ErrorMessages .EMBEDDED_NULL_BYTE );
@@ -329,7 +331,6 @@ int forkExecDefault(VirtualFrame frame, Object args, Object executable_list, Obj
329
331
@ Cached CastToListNode castFdsToKeep ,
330
332
@ Cached CastToJavaStringNode castCwd ,
331
333
@ Cached CastToListNode castEnv ,
332
- @ Cached SequenceStorageNodes .CopyInternalArrayNode copy ,
333
334
@ CachedLibrary (limit = "3" ) PythonObjectLibrary lib ) {
334
335
String actualCwd ;
335
336
if (cwd instanceof PNone ) {
@@ -367,7 +368,7 @@ int forkExecDefault(VirtualFrame frame, Object args, Object executable_list, Obj
367
368
lib .asSizeWithState (errpipe_read , PArguments .getThreadState (frame )),
368
369
lib .asSizeWithState (errpipe_write , PArguments .getThreadState (frame )),
369
370
lib .isTrueWithState (restore_signals , PArguments .getThreadState (frame )),
370
- lib .isTrueWithState (call_setsid , PArguments .getThreadState (frame )), PNone .NO_VALUE , copy );
371
+ lib .isTrueWithState (call_setsid , PArguments .getThreadState (frame )), PNone .NO_VALUE );
371
372
}
372
373
373
374
}
0 commit comments