undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
462
test/jdk/java/foreign/TestMemoryAccess.java
Normal file
462
test/jdk/java/foreign/TestMemoryAccess.java
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false -Xverify:all TestMemoryAccess
|
||||
* @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestMemoryAccess
|
||||
* @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false -Xverify:all TestMemoryAccess
|
||||
* @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestMemoryAccess
|
||||
*/
|
||||
|
||||
import java.lang.foreign.*;
|
||||
import java.lang.foreign.MemoryLayout.PathElement;
|
||||
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.testng.annotations.*;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class TestMemoryAccess {
|
||||
|
||||
@Test(dataProvider = "elements")
|
||||
public void testAccess(Function<MemorySegment, MemorySegment> viewFactory, ValueLayout elemLayout, Checker checker) {
|
||||
ValueLayout layout = elemLayout.withName("elem");
|
||||
testAccessInternal(viewFactory, layout, layout.varHandle(), checker);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "elements")
|
||||
public void testPaddedAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Checker checker) {
|
||||
GroupLayout layout = MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem"));
|
||||
testAccessInternal(viewFactory, layout, layout.varHandle(PathElement.groupElement("elem")), checker);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "elements")
|
||||
public void testPaddedAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Checker checker) {
|
||||
SequenceLayout layout = MemoryLayout.sequenceLayout(2, elemLayout);
|
||||
testAccessInternal(viewFactory, layout, layout.varHandle(PathElement.sequenceElement(1)), checker);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "arrayElements")
|
||||
public void testArrayAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
|
||||
SequenceLayout seq = MemoryLayout.sequenceLayout(10, elemLayout.withName("elem"));
|
||||
testArrayAccessInternal(viewFactory, seq, seq.varHandle(PathElement.sequenceElement()), checker);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "arrayElements")
|
||||
public void testPaddedArrayAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
|
||||
SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem")));
|
||||
testArrayAccessInternal(viewFactory, seq, seq.varHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("elem")), checker);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "arrayElements")
|
||||
public void testPaddedArrayAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
|
||||
SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout));
|
||||
testArrayAccessInternal(viewFactory, seq, seq.varHandle(PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement(1)), checker);
|
||||
}
|
||||
|
||||
private void testAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout layout, VarHandle handle, Checker checker) {
|
||||
MemorySegment outer_segment;
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment segment = viewFactory.apply(arena.allocate(layout));
|
||||
boolean isRO = segment.isReadOnly();
|
||||
try {
|
||||
checker.check(handle, segment);
|
||||
if (isRO) {
|
||||
throw new AssertionError(); //not ok, memory should be immutable
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
if (!isRO) {
|
||||
throw new AssertionError(); //we should not have failed!
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
checker.check(handle, segment.asSlice(layout.byteSize()));
|
||||
throw new AssertionError(); //not ok, out of bounds
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
//ok, should fail (out of bounds)
|
||||
}
|
||||
outer_segment = segment; //leak!
|
||||
}
|
||||
try {
|
||||
checker.check(handle, outer_segment);
|
||||
throw new AssertionError(); //not ok, session is closed
|
||||
} catch (IllegalStateException ex) {
|
||||
//ok, should fail (session is closed)
|
||||
}
|
||||
}
|
||||
|
||||
private void testArrayAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, SequenceLayout seq, VarHandle handle, ArrayChecker checker) {
|
||||
MemorySegment outer_segment;
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment segment = viewFactory.apply(arena.allocate(seq));
|
||||
boolean isRO = segment.isReadOnly();
|
||||
try {
|
||||
for (int i = 0; i < seq.elementCount(); i++) {
|
||||
checker.check(handle, segment, i);
|
||||
}
|
||||
if (isRO) {
|
||||
throw new AssertionError(); //not ok, memory should be immutable
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
if (!isRO) {
|
||||
throw new AssertionError(); //we should not have failed!
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
checker.check(handle, segment, seq.elementCount());
|
||||
throw new AssertionError(); //not ok, out of bounds
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
//ok, should fail (out of bounds)
|
||||
}
|
||||
outer_segment = segment; //leak!
|
||||
}
|
||||
try {
|
||||
checker.check(handle, outer_segment, 0);
|
||||
throw new AssertionError(); //not ok, session is closed
|
||||
} catch (IllegalStateException ex) {
|
||||
//ok, should fail (session is closed)
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "matrixElements")
|
||||
public void testMatrixAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
|
||||
SequenceLayout seq = MemoryLayout.sequenceLayout(20,
|
||||
MemoryLayout.sequenceLayout(10, elemLayout.withName("elem")));
|
||||
testMatrixAccessInternal(viewFactory, seq, seq.varHandle(
|
||||
PathElement.sequenceElement(), PathElement.sequenceElement()), checker);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "matrixElements")
|
||||
public void testPaddedMatrixAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
|
||||
SequenceLayout seq = MemoryLayout.sequenceLayout(20,
|
||||
MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem"))));
|
||||
testMatrixAccessInternal(viewFactory, seq,
|
||||
seq.varHandle(
|
||||
PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.groupElement("elem")),
|
||||
checker);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "matrixElements")
|
||||
public void testPaddedMatrixAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
|
||||
SequenceLayout seq = MemoryLayout.sequenceLayout(20,
|
||||
MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout)));
|
||||
testMatrixAccessInternal(viewFactory, seq,
|
||||
seq.varHandle(
|
||||
PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.sequenceElement(1)),
|
||||
checker);
|
||||
}
|
||||
|
||||
private void testMatrixAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, SequenceLayout seq, VarHandle handle, MatrixChecker checker) {
|
||||
MemorySegment outer_segment;
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment segment = viewFactory.apply(arena.allocate(seq));
|
||||
boolean isRO = segment.isReadOnly();
|
||||
try {
|
||||
for (int i = 0; i < seq.elementCount(); i++) {
|
||||
for (int j = 0; j < ((SequenceLayout) seq.elementLayout()).elementCount(); j++) {
|
||||
checker.check(handle, segment, i, j);
|
||||
}
|
||||
}
|
||||
if (isRO) {
|
||||
throw new AssertionError(); //not ok, memory should be immutable
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
if (!isRO) {
|
||||
throw new AssertionError(); //we should not have failed!
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
checker.check(handle, segment, seq.elementCount(),
|
||||
((SequenceLayout)seq.elementLayout()).elementCount());
|
||||
throw new AssertionError(); //not ok, out of bounds
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
//ok, should fail (out of bounds)
|
||||
}
|
||||
outer_segment = segment; //leak!
|
||||
}
|
||||
try {
|
||||
checker.check(handle, outer_segment, 0, 0);
|
||||
throw new AssertionError(); //not ok, session is closed
|
||||
} catch (IllegalStateException ex) {
|
||||
//ok, should fail (session is closed)
|
||||
}
|
||||
}
|
||||
|
||||
static Function<MemorySegment, MemorySegment> ID = Function.identity();
|
||||
static Function<MemorySegment, MemorySegment> IMMUTABLE = MemorySegment::asReadOnly;
|
||||
|
||||
@DataProvider(name = "elements")
|
||||
public Object[][] createData() {
|
||||
return new Object[][] {
|
||||
//BE, RW
|
||||
{ ID, ValueLayout.JAVA_BYTE, Checker.BYTE },
|
||||
{ ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), Checker.SHORT },
|
||||
{ ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), Checker.CHAR },
|
||||
{ ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), Checker.INT },
|
||||
{ ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), Checker.LONG },
|
||||
{ ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), Checker.FLOAT },
|
||||
{ ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), Checker.DOUBLE },
|
||||
//BE, RO
|
||||
{ IMMUTABLE, ValueLayout.JAVA_BYTE, Checker.BYTE },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), Checker.SHORT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), Checker.CHAR },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), Checker.INT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), Checker.LONG },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), Checker.FLOAT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), Checker.DOUBLE },
|
||||
//LE, RW
|
||||
{ ID, ValueLayout.JAVA_BYTE, Checker.BYTE },
|
||||
{ ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.SHORT },
|
||||
{ ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.CHAR },
|
||||
{ ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.INT },
|
||||
{ ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.LONG },
|
||||
{ ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.FLOAT },
|
||||
{ ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.DOUBLE },
|
||||
//LE, RO
|
||||
{ IMMUTABLE, ValueLayout.JAVA_BYTE, Checker.BYTE },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.SHORT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.CHAR },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.INT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.LONG },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.FLOAT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.DOUBLE },
|
||||
};
|
||||
}
|
||||
|
||||
interface Checker {
|
||||
void check(VarHandle handle, MemorySegment segment);
|
||||
|
||||
Checker BYTE = (handle, segment) -> {
|
||||
handle.set(segment, 0L, (byte)42);
|
||||
assertEquals(42, (byte)handle.get(segment, 0L));
|
||||
};
|
||||
|
||||
Checker SHORT = (handle, segment) -> {
|
||||
handle.set(segment, 0L, (short)42);
|
||||
assertEquals(42, (short)handle.get(segment, 0L));
|
||||
};
|
||||
|
||||
Checker CHAR = (handle, segment) -> {
|
||||
handle.set(segment, 0L, (char)42);
|
||||
assertEquals(42, (char)handle.get(segment, 0L));
|
||||
};
|
||||
|
||||
Checker INT = (handle, segment) -> {
|
||||
handle.set(segment, 0L, 42);
|
||||
assertEquals(42, (int)handle.get(segment, 0L));
|
||||
};
|
||||
|
||||
Checker LONG = (handle, segment) -> {
|
||||
handle.set(segment, 0L, (long)42);
|
||||
assertEquals(42, (long)handle.get(segment, 0L));
|
||||
};
|
||||
|
||||
Checker FLOAT = (handle, segment) -> {
|
||||
handle.set(segment, 0L, (float)42);
|
||||
assertEquals((float)42, (float)handle.get(segment, 0L));
|
||||
};
|
||||
|
||||
Checker DOUBLE = (handle, segment) -> {
|
||||
handle.set(segment, 0L, (double)42);
|
||||
assertEquals((double)42, (double)handle.get(segment, 0L));
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "arrayElements")
|
||||
public Object[][] createArrayData() {
|
||||
return new Object[][] {
|
||||
//BE, RW
|
||||
{ ID, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
|
||||
{ ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.SHORT },
|
||||
{ ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.CHAR },
|
||||
{ ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.INT },
|
||||
{ ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.LONG },
|
||||
{ ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.FLOAT },
|
||||
{ ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.DOUBLE },
|
||||
//BE, RO
|
||||
{ IMMUTABLE, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.SHORT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.CHAR },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.INT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.LONG },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.FLOAT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.DOUBLE },
|
||||
//LE, RW
|
||||
{ ID, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
|
||||
{ ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.SHORT },
|
||||
{ ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.CHAR },
|
||||
{ ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.INT },
|
||||
{ ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.LONG },
|
||||
{ ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.FLOAT },
|
||||
{ ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.DOUBLE },
|
||||
//LE, RO
|
||||
{ IMMUTABLE, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.SHORT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.CHAR },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.INT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.LONG },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.FLOAT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.DOUBLE },
|
||||
};
|
||||
}
|
||||
|
||||
interface ArrayChecker {
|
||||
void check(VarHandle handle, MemorySegment segment, long index);
|
||||
|
||||
ArrayChecker BYTE = (handle, segment, i) -> {
|
||||
handle.set(segment, 0L, i, (byte)i);
|
||||
assertEquals(i, (byte)handle.get(segment, 0L, i));
|
||||
};
|
||||
|
||||
ArrayChecker SHORT = (handle, segment, i) -> {
|
||||
handle.set(segment, 0L, i, (short)i);
|
||||
assertEquals(i, (short)handle.get(segment, 0L, i));
|
||||
};
|
||||
|
||||
ArrayChecker CHAR = (handle, segment, i) -> {
|
||||
handle.set(segment, 0L, i, (char)i);
|
||||
assertEquals(i, (char)handle.get(segment, 0L, i));
|
||||
};
|
||||
|
||||
ArrayChecker INT = (handle, segment, i) -> {
|
||||
handle.set(segment, 0L, i, (int)i);
|
||||
assertEquals(i, (int)handle.get(segment, 0L, i));
|
||||
};
|
||||
|
||||
ArrayChecker LONG = (handle, segment, i) -> {
|
||||
handle.set(segment, 0L, i, (long)i);
|
||||
assertEquals(i, (long)handle.get(segment, 0L, i));
|
||||
};
|
||||
|
||||
ArrayChecker FLOAT = (handle, segment, i) -> {
|
||||
handle.set(segment, 0L, i, (float)i);
|
||||
assertEquals((float)i, (float)handle.get(segment, 0L, i));
|
||||
};
|
||||
|
||||
ArrayChecker DOUBLE = (handle, segment, i) -> {
|
||||
handle.set(segment, 0L, i, (double)i);
|
||||
assertEquals((double)i, (double)handle.get(segment, 0L, i));
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "matrixElements")
|
||||
public Object[][] createMatrixData() {
|
||||
return new Object[][] {
|
||||
//BE, RW
|
||||
{ ID, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
|
||||
{ ID, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
|
||||
{ ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.SHORT },
|
||||
{ ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.CHAR },
|
||||
{ ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.INT },
|
||||
{ ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.LONG },
|
||||
{ ID, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.ADDR },
|
||||
{ ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.FLOAT },
|
||||
{ ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.DOUBLE },
|
||||
//BE, RO
|
||||
{ IMMUTABLE, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.SHORT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.CHAR },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.INT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.LONG },
|
||||
{ IMMUTABLE, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.ADDR },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.FLOAT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.DOUBLE },
|
||||
//LE, RW
|
||||
{ ID, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
|
||||
{ ID, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
|
||||
{ ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.SHORT },
|
||||
{ ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.CHAR },
|
||||
{ ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.INT },
|
||||
{ ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.LONG },
|
||||
{ ID, ValueLayout.ADDRESS.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.ADDR },
|
||||
{ ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.FLOAT },
|
||||
{ ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.DOUBLE },
|
||||
//LE, RO
|
||||
{ IMMUTABLE, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.SHORT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.CHAR },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.INT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.LONG },
|
||||
{ IMMUTABLE, ValueLayout.ADDRESS.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.ADDR },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.FLOAT },
|
||||
{ IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.DOUBLE },
|
||||
};
|
||||
}
|
||||
|
||||
interface MatrixChecker {
|
||||
void check(VarHandle handle, MemorySegment segment, long row, long col);
|
||||
|
||||
MatrixChecker BYTE = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, (byte)(r + c));
|
||||
assertEquals(r + c, (byte)handle.get(segment, 0L, r, c));
|
||||
};
|
||||
|
||||
MatrixChecker BOOLEAN = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, (r + c) != 0);
|
||||
assertEquals((r + c) != 0, (boolean)handle.get(segment, 0L, r, c));
|
||||
};
|
||||
|
||||
MatrixChecker SHORT = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, (short)(r + c));
|
||||
assertEquals(r + c, (short)handle.get(segment, 0L, r, c));
|
||||
};
|
||||
|
||||
MatrixChecker CHAR = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, (char)(r + c));
|
||||
assertEquals(r + c, (char)handle.get(segment, 0L, r, c));
|
||||
};
|
||||
|
||||
MatrixChecker INT = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, (int)(r + c));
|
||||
assertEquals(r + c, (int)handle.get(segment, 0L, r, c));
|
||||
};
|
||||
|
||||
MatrixChecker LONG = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, r + c);
|
||||
assertEquals(r + c, (long)handle.get(segment, 0L, r, c));
|
||||
};
|
||||
|
||||
MatrixChecker ADDR = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, MemorySegment.ofAddress(r + c));
|
||||
assertEquals(MemorySegment.ofAddress(r + c), (MemorySegment) handle.get(segment, 0L, r, c));
|
||||
};
|
||||
|
||||
MatrixChecker FLOAT = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, (float)(r + c));
|
||||
assertEquals((float)(r + c), (float)handle.get(segment, 0L, r, c));
|
||||
};
|
||||
|
||||
MatrixChecker DOUBLE = (handle, segment, r, c) -> {
|
||||
handle.set(segment, 0L, r, c, (double)(r + c));
|
||||
assertEquals((double)(r + c), (double)handle.get(segment, 0L, r, c));
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue