Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Objects;
import java.util.Optional;
import jdk.internal.foreign.Utils;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.Stable;

abstract non-sealed class AbstractLayout implements MemoryLayout {
Expand Down Expand Up @@ -86,6 +87,7 @@ public final long bitAlignment() {
}

@Override
@ForceInline
public long byteSize() {
if (cachedSize == 0) {
cachedSize = Utils.bitsToBytesOrThrow(bitSize(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
Expand All @@ -51,6 +52,7 @@
import jdk.internal.access.foreign.UnmapperProxy;
import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.util.ArraysSupport;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.ForceInline;

import static java.lang.foreign.ValueLayout.JAVA_BYTE;
Expand All @@ -64,7 +66,7 @@
* are defined for each memory segment kind, see {@link NativeMemorySegmentImpl}, {@link HeapMemorySegmentImpl} and
* {@link MappedMemorySegmentImpl}.
*/
public abstract non-sealed class AbstractMemorySegmentImpl implements MemorySegment, SegmentAllocator, Scoped {
public abstract non-sealed class AbstractMemorySegmentImpl implements MemorySegment, SegmentAllocator, Scoped, BiFunction<String, List<Number>, RuntimeException> {

private static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();

Expand Down Expand Up @@ -394,13 +396,20 @@ private int checkArraySize(String typeName, int elemSize) {
@ForceInline
void checkBounds(long offset, long length) {
if (length > 0) {
Objects.checkIndex(offset, this.length - length + 1);
Preconditions.checkIndex(offset, this.length - length + 1, this);
} else if (length < 0 || offset < 0 ||
offset > this.length - length) {
throw outOfBoundException(offset, length);
}
}

@Override
public RuntimeException apply(String s, List<Number> numbers) {
long offset = numbers.get(0).longValue();
long length = byteSize() - numbers.get(1).longValue() + 1;
return outOfBoundException(offset, length);
}

@Override
@ForceInline
public MemorySessionImpl sessionImpl() {
Expand All @@ -413,7 +422,7 @@ public MemorySession session() {
}

private IndexOutOfBoundsException outOfBoundException(long offset, long length) {
return new IndexOutOfBoundsException(String.format("Out of bound access on segment %s; new offset = %d; new length = %d",
return new IndexOutOfBoundsException(String.format("Out of bound access on segment %s; offset = %d; length = %d",
this, offset, length));
}

Expand Down
12 changes: 12 additions & 0 deletions test/jdk/java/foreign/TestSegments.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ public void testSmallSegmentMin() {
memorySegment.get(JAVA_INT, offset);
}

@Test
public void testSegmentOOBMessage() {
try {
var segment = MemorySegment.allocateNative(10, MemorySession.global());
segment.getAtIndex(ValueLayout.JAVA_INT, 2);
} catch (IndexOutOfBoundsException ex) {
assertTrue(ex.getMessage().contains("Out of bound access"));
assertTrue(ex.getMessage().contains("offset = 8"));
assertTrue(ex.getMessage().contains("length = 4"));
}
}

@Test(dataProvider = "segmentFactories")
public void testAccessModesOfFactories(Supplier<MemorySegment> segmentSupplier) {
MemorySegment segment = segmentSupplier.get();
Expand Down