|
101 | 101 | import com.oracle.truffle.api.dsl.NodeFactory; |
102 | 102 | import com.oracle.truffle.api.dsl.Specialization; |
103 | 103 | import com.oracle.truffle.api.dsl.TypeSystemReference; |
| 104 | +import com.oracle.truffle.api.frame.VirtualFrame; |
104 | 105 | import com.oracle.truffle.api.profiles.ValueProfile; |
105 | 106 |
|
106 | 107 | @CoreFunctions(defineModule = "posix") |
@@ -802,38 +803,42 @@ public static WriteNode create() { |
802 | 803 | @GenerateNodeFactory |
803 | 804 | @TypeSystemReference(PythonArithmeticTypes.class) |
804 | 805 | public abstract static class ReadNode extends PythonFileNode { |
805 | | - @Specialization(guards = "readOpaque()") |
806 | | - @TruffleBoundary |
807 | | - Object readOpaque(int fd, @SuppressWarnings("unused") Object requestedSize) { |
| 806 | + @Specialization(guards = "readOpaque(frame)") |
| 807 | + Object readOpaque(@SuppressWarnings("unused") VirtualFrame frame, int fd, @SuppressWarnings("unused") Object requestedSize) { |
808 | 808 | SeekableByteChannel channel = getFileChannel(fd); |
809 | 809 | try { |
810 | | - long size = channel.size() - channel.position(); |
811 | | - ByteBuffer dst = ByteBuffer.allocate((int) size); |
812 | | - channel.read(dst); |
813 | | - return new OpaqueBytes(dst.array()); |
| 810 | + return new OpaqueBytes(doRead(channel, Integer.MAX_VALUE)); |
814 | 811 | } catch (IOException e) { |
815 | 812 | throw raise(OSError, e.getMessage()); |
816 | 813 | } |
817 | 814 | } |
818 | 815 |
|
819 | | - @Specialization(guards = "!readOpaque()") |
820 | | - @TruffleBoundary |
821 | | - Object read(int fd, long requestedSize) { |
| 816 | + @Specialization(guards = "!readOpaque(frame)") |
| 817 | + Object read(@SuppressWarnings("unused") VirtualFrame frame, int fd, long requestedSize) { |
822 | 818 | SeekableByteChannel channel = getFileChannel(fd); |
823 | 819 | try { |
824 | | - long size = Math.min(requestedSize, channel.size() - channel.position()); |
825 | | - // cast below will always succeed, since requestedSize was an int, |
826 | | - // and must thus will always be smaller than a long that cannot be |
827 | | - // downcast |
828 | | - ByteBuffer dst = ByteBuffer.allocate((int) size); |
829 | | - getFileChannel(fd).read(dst); |
830 | | - return factory().createBytes(dst.array()); |
| 820 | + byte[] array = doRead(channel, (int) requestedSize); |
| 821 | + return factory().createBytes(array); |
831 | 822 | } catch (IOException e) { |
832 | 823 | throw raise(OSError, e.getMessage()); |
833 | 824 | } |
834 | 825 | } |
835 | 826 |
|
836 | | - protected boolean readOpaque() { |
| 827 | + @TruffleBoundary |
| 828 | + private static byte[] doRead(SeekableByteChannel channel, int requestedSize) throws IOException { |
| 829 | + long size = Math.min(requestedSize, channel.size() - channel.position()); |
| 830 | + // cast below will always succeed, since requestedSize was an int, |
| 831 | + // and must thus will always be smaller than a long that cannot be |
| 832 | + // downcast |
| 833 | + ByteBuffer dst = ByteBuffer.allocate((int) size); |
| 834 | + channel.read(dst); |
| 835 | + return dst.array(); |
| 836 | + } |
| 837 | + |
| 838 | + /** |
| 839 | + * @param frame - only used so the DSL sees this as a dynamic check |
| 840 | + */ |
| 841 | + protected boolean readOpaque(VirtualFrame frame) { |
837 | 842 | return OpaqueBytes.isEnabled(getContext()); |
838 | 843 | } |
839 | 844 | } |
|
0 commit comments