|
60 | 60 | import com.oracle.truffle.api.dsl.ImportStatic; |
61 | 61 | import com.oracle.truffle.api.dsl.Specialization; |
62 | 62 | import com.oracle.truffle.api.interop.InteropLibrary; |
| 63 | +import com.oracle.truffle.api.interop.InvalidBufferOffsetException; |
| 64 | +import com.oracle.truffle.api.interop.UnsupportedMessageException; |
| 65 | +import com.oracle.truffle.api.library.CachedLibrary; |
63 | 66 | import com.oracle.truffle.api.nodes.Node; |
64 | 67 | import com.oracle.truffle.api.profiles.InlinedBranchProfile; |
65 | 68 | import com.oracle.truffle.api.profiles.InlinedConditionProfile; |
@@ -687,7 +690,8 @@ static void copyBytewise(Node node, JSArrayBufferObject targetBuffer, JSArrayBuf |
687 | 690 | @Cached @Shared GetBufferElementTypeDispatchNode getBufferElementNode, |
688 | 691 | @Cached @Shared SetBufferElementTypeDispatchNode setBufferElementNode, |
689 | 692 | @Cached @Shared InlinedConditionProfile bothArraysBranch, |
690 | | - @Cached @Shared InlinedBranchProfile sameArrayBranch) { |
| 693 | + @Cached @Shared InlinedBranchProfile sameArrayBranch, |
| 694 | + @Cached @Shared CopyTypedArrayElementsFromInteropBufferNode copyTypedArrayElementsFromInteropBufferNode) { |
691 | 695 | int sourceByteLength = sourceLength * sourceElementSize; |
692 | 696 | if (bothArraysBranch.profile(node, targetType.isArray() && sourceType.isArray())) { |
693 | 697 | byte[] sourceByteArray = JSArrayBuffer.getByteArray(sourceBuffer); |
@@ -719,12 +723,18 @@ static void copyBytewise(Node node, JSArrayBufferObject targetBuffer, JSArrayBuf |
719 | 723 | targetByteBuffer = Boundaries.byteBufferWrap(JSArrayBuffer.getByteArray(targetBuffer)); |
720 | 724 | } |
721 | 725 | // if buffers are distinct, try to perform a bulk copy |
722 | | - if (distinctBuffers && (sourceByteBuffer != null && targetByteBuffer != null)) { |
723 | | - Boundaries.byteBufferPutSlice( |
724 | | - targetByteBuffer, targetByteIndex, |
725 | | - sourceByteBuffer, sourceByteIndex, |
726 | | - sourceByteIndex + sourceByteLength); |
727 | | - return; |
| 726 | + if (distinctBuffers) { |
| 727 | + if (sourceByteBuffer != null && targetByteBuffer != null) { |
| 728 | + Boundaries.byteBufferPutSlice( |
| 729 | + targetByteBuffer, targetByteIndex, |
| 730 | + sourceByteBuffer, sourceByteIndex, |
| 731 | + sourceByteIndex + sourceByteLength); |
| 732 | + return; |
| 733 | + } |
| 734 | + if (sourceType.isInterop() && targetByteBuffer != null && targetByteBuffer.hasArray()) { |
| 735 | + copyTypedArrayElementsFromInteropBufferNode.execute(node, sourceBuffer, sourceByteIndex, targetByteBuffer, targetByteIndex, sourceByteLength); |
| 736 | + return; |
| 737 | + } |
728 | 738 | } |
729 | 739 |
|
730 | 740 | // if we could not do a bulk copy, perform a bytewise copy |
@@ -768,6 +778,27 @@ static void copyElementwise(Node node, JSArrayBufferObject targetBuffer, JSArray |
768 | 778 | } |
769 | 779 | } |
770 | 780 |
|
| 781 | + @GenerateCached(false) |
| 782 | + @GenerateInline |
| 783 | + @ImportStatic(JSConfig.class) |
| 784 | + abstract static class CopyTypedArrayElementsFromInteropBufferNode extends JavaScriptBaseNode { |
| 785 | + |
| 786 | + abstract void execute(Node node, JSArrayBufferObject sourceBuffer, int sourceByteIndex, ByteBuffer targetByteBuffer, int targetByteIndex, int byteLength); |
| 787 | + |
| 788 | + @Specialization |
| 789 | + static void doReadBuffer(JSArrayBufferObject sourceBuffer, int sourceByteIndex, |
| 790 | + ByteBuffer targetByteBuffer, int targetByteIndex, |
| 791 | + int byteLength, |
| 792 | + @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interopLibrary) { |
| 793 | + assert targetByteBuffer.hasArray(); |
| 794 | + try { |
| 795 | + interopLibrary.readBuffer(sourceBuffer, sourceByteIndex, targetByteBuffer.array(), targetByteBuffer.arrayOffset() + targetByteIndex, byteLength); |
| 796 | + } catch (InvalidBufferOffsetException | UnsupportedMessageException e) { |
| 797 | + throw CompilerDirectives.shouldNotReachHere(e); |
| 798 | + } |
| 799 | + } |
| 800 | + } |
| 801 | + |
771 | 802 | /** |
772 | 803 | * Wrapper around {@link GetBufferElementNode}, dispatching on the typed array element type. |
773 | 804 | */ |
|
0 commit comments