|
98 | 98 | import com.oracle.graal.python.builtins.objects.PNone;
|
99 | 99 | import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
|
100 | 100 | import com.oracle.graal.python.builtins.objects.bytes.PBytes;
|
101 |
| -import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; |
102 | 101 | import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
|
103 | 102 | import com.oracle.graal.python.builtins.objects.common.SequenceNodes.LenNode;
|
104 |
| -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; |
105 | 103 | import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemDynamicNode;
|
106 | 104 | import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
|
107 |
| -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.ToByteArrayNodeGen; |
108 | 105 | import com.oracle.graal.python.builtins.objects.dict.PDict;
|
109 | 106 | import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
|
110 | 107 | import com.oracle.graal.python.builtins.objects.floats.PFloat;
|
|
143 | 140 | import com.oracle.graal.python.runtime.exception.PythonExitException;
|
144 | 141 | import com.oracle.graal.python.runtime.sequence.PSequence;
|
145 | 142 | import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage;
|
146 |
| -import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; |
147 | 143 | import com.oracle.graal.python.util.FileDeleteShutdownHook;
|
148 | 144 | import com.oracle.graal.python.util.OverflowException;
|
149 | 145 | import com.oracle.truffle.api.CompilerDirectives;
|
|
161 | 157 | import com.oracle.truffle.api.dsl.Specialization;
|
162 | 158 | import com.oracle.truffle.api.dsl.TypeSystemReference;
|
163 | 159 | import com.oracle.truffle.api.frame.VirtualFrame;
|
164 |
| -import com.oracle.truffle.api.interop.UnsupportedMessageException; |
165 | 160 | import com.oracle.truffle.api.library.CachedLibrary;
|
166 | 161 | import com.oracle.truffle.api.profiles.BranchProfile;
|
167 | 162 | import com.oracle.truffle.api.profiles.ConditionProfile;
|
@@ -1146,95 +1141,37 @@ Object mkdirMode(VirtualFrame frame, Object pathArg, @SuppressWarnings("unused")
|
1146 | 1141 | }
|
1147 | 1142 | }
|
1148 | 1143 |
|
1149 |
| - @Builtin(name = "write", minNumOfPositionalArgs = 2) |
| 1144 | + @Builtin(name = "write", minNumOfPositionalArgs = 2, parameterNames = {"fd", "str"}) |
| 1145 | + @ArgumentClinic(name = "fd", conversion = ClinicConversion.Int, defaultValue = "-1") |
| 1146 | + @ArgumentClinic(name = "str", conversion = ClinicConversion.Buffer) |
1150 | 1147 | @GenerateNodeFactory
|
1151 |
| - @TypeSystemReference(PythonArithmeticTypes.class) |
1152 |
| - public abstract static class WriteNode extends PythonFileNode { |
1153 |
| - @Child private SequenceStorageNodes.ToByteArrayNode toByteArrayNode; |
1154 |
| - private final BranchProfile gotException = BranchProfile.create(); |
1155 |
| - private final BranchProfile notWritable = BranchProfile.create(); |
1156 |
| - |
1157 |
| - public abstract Object executeWith(VirtualFrame frame, Object fd, Object data); |
| 1148 | + public abstract static class WriteNode extends PythonBinaryClinicBuiltinNode { |
| 1149 | + @Override |
| 1150 | + protected ArgumentClinicProvider getArgumentClinic() { |
| 1151 | + return PosixModuleBuiltinsClinicProviders.WriteNodeClinicProviderGen.INSTANCE; |
| 1152 | + } |
1158 | 1153 |
|
1159 | 1154 | @TruffleBoundary(allowInlining = true, transferToInterpreterOnException = false)
|
1160 |
| - private static Object writableOp(byte[] data, Object channel) throws IOException { |
1161 |
| - if (channel instanceof WritableByteChannel) { |
1162 |
| - return doWriteOp(data, channel); |
1163 |
| - } |
1164 |
| - return null; |
| 1155 | + private static int doWriteOp(byte[] data, WritableByteChannel channel) throws IOException { |
| 1156 | + return channel.write(ByteBuffer.wrap(data)); |
1165 | 1157 | }
|
1166 | 1158 |
|
1167 | 1159 | @Specialization
|
1168 | 1160 | Object write(VirtualFrame frame, int fd, byte[] data,
|
1169 |
| - @Cached("createClassProfile()") ValueProfile channelClassProfile) { |
1170 |
| - Channel channel = getResources().getFileChannel(fd, channelClassProfile); |
| 1161 | + @Cached("createClassProfile()") ValueProfile channelClassProfile, |
| 1162 | + @Cached BranchProfile gotExceptionProfile, |
| 1163 | + @Cached BranchProfile nonWritableChannelProfile) { |
| 1164 | + Channel channel = getContext().getResources().getFileChannel(fd, channelClassProfile); |
| 1165 | + if (!(channel instanceof WritableByteChannel)) { |
| 1166 | + nonWritableChannelProfile.enter(); |
| 1167 | + throw raiseOSError(frame, OSErrorEnum.EBADF); |
| 1168 | + } |
1171 | 1169 | try {
|
1172 |
| - Object ret = writableOp(data, channel); |
1173 |
| - if (ret != null) { |
1174 |
| - return ret; |
1175 |
| - } |
| 1170 | + return doWriteOp(data, (WritableByteChannel) channel); |
1176 | 1171 | } catch (Exception e) {
|
1177 |
| - gotException.enter(); |
| 1172 | + gotExceptionProfile.enter(); |
1178 | 1173 | throw raiseOSError(frame, e);
|
1179 | 1174 | }
|
1180 |
| - notWritable.enter(); |
1181 |
| - throw raiseOSError(frame, OSErrorEnum.EBADF); |
1182 |
| - } |
1183 |
| - |
1184 |
| - @TruffleBoundary(allowInlining = true, transferToInterpreterOnException = false) |
1185 |
| - private static int doWriteOp(byte[] data, Object channel) throws IOException { |
1186 |
| - return ((WritableByteChannel) channel).write(ByteBuffer.wrap(data)); |
1187 |
| - } |
1188 |
| - |
1189 |
| - @Specialization |
1190 |
| - Object write(VirtualFrame frame, int fd, String data, |
1191 |
| - @Cached("createClassProfile()") ValueProfile channelClassProfile) { |
1192 |
| - return write(frame, fd, stringToBytes(data), channelClassProfile); |
1193 |
| - } |
1194 |
| - |
1195 |
| - @TruffleBoundary |
1196 |
| - private static byte[] stringToBytes(String data) { |
1197 |
| - return data.getBytes(); |
1198 |
| - } |
1199 |
| - |
1200 |
| - @Specialization |
1201 |
| - Object write(VirtualFrame frame, int fd, PBytesLike data, |
1202 |
| - @Cached("createClassProfile()") ValueProfile channelClassProfile) { |
1203 |
| - return write(frame, fd, getByteArray(data.getSequenceStorage()), channelClassProfile); |
1204 |
| - } |
1205 |
| - |
1206 |
| - @Specialization(limit = "getCallSiteInlineCacheMaxDepth()") |
1207 |
| - Object write(VirtualFrame frame, int fd, Object data, |
1208 |
| - @CachedLibrary("data") PythonObjectLibrary lib, |
1209 |
| - @Cached("createClassProfile()") ValueProfile channelClassProfile) { |
1210 |
| - if (lib.isBuffer(data)) { |
1211 |
| - try { |
1212 |
| - byte[] b = lib.getBufferBytes(data); |
1213 |
| - return write(frame, fd, b, channelClassProfile); |
1214 |
| - } catch (UnsupportedMessageException e) { |
1215 |
| - throw CompilerDirectives.shouldNotReachHere("Buffer-like object does not support getBufferBytes()"); |
1216 |
| - } |
1217 |
| - } |
1218 |
| - throw raise(TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, data); |
1219 |
| - } |
1220 |
| - |
1221 |
| - @Specialization(limit = "getCallSiteInlineCacheMaxDepth()") |
1222 |
| - static Object writePInt(VirtualFrame frame, Object fd, Object data, |
1223 |
| - @CachedLibrary("fd") PythonObjectLibrary lib, |
1224 |
| - @Cached("create()") WriteNode recursive) { |
1225 |
| - return recursive.executeWith(frame, lib.asSizeWithState(fd, PArguments.getThreadState(frame)), data); |
1226 |
| - } |
1227 |
| - |
1228 |
| - private byte[] getByteArray(SequenceStorage storage) { |
1229 |
| - if (toByteArrayNode == null) { |
1230 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
1231 |
| - toByteArrayNode = insert(ToByteArrayNodeGen.create()); |
1232 |
| - } |
1233 |
| - return toByteArrayNode.execute(storage); |
1234 |
| - } |
1235 |
| - |
1236 |
| - public static WriteNode create() { |
1237 |
| - return PosixModuleBuiltinsFactory.WriteNodeFactory.create(null); |
1238 | 1175 | }
|
1239 | 1176 | }
|
1240 | 1177 |
|
|
0 commit comments