From 22f43e664634c817f169f4c9e3a0ee113d0f3435 Mon Sep 17 00:00:00 2001 From: squid233 <60126026+squid233@users.noreply.github.com> Date: Thu, 1 Feb 2024 14:07:11 +0800 Subject: [PATCH] Add MemoryStack::malloc(MemoryLayout); fix document in Skip --- README.md | 2 +- gradle.properties | 2 +- .../java/overrun/marshal/MemoryStack.java | 17 ++- src/main/java/overrun/marshal/gen/Skip.java | 4 +- .../marshal/test/DowncallSoutTest.java | 132 ++++++++++++++++++ .../overrun/marshal/test/DowncallTest.java | 101 +------------- 6 files changed, 153 insertions(+), 105 deletions(-) create mode 100644 src/test/java/overrun/marshal/test/DowncallSoutTest.java diff --git a/README.md b/README.md index cbb8e91..56ffcb5 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,6 @@ Import as a Gradle dependency: ```groovy dependencies { - implementation("io.github.over-run:marshal:0.1.0-alpha.12-jdk22") + implementation("io.github.over-run:marshal:0.1.0-alpha.13-jdk22") } ``` diff --git a/gradle.properties b/gradle.properties index 0a1ed51..e72fd75 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ projGroupId=io.github.over-run projArtifactId=marshal # The project name should only contain lowercase letters, numbers and hyphen. projName=marshal -projVersion=0.1.0-alpha.12-jdk22 +projVersion=0.1.0-alpha.13-jdk22 projDesc=Marshaler of native libraries # Uncomment them if you want to publish to maven repository. projUrl=https://github.com/Over-Run/marshal diff --git a/src/main/java/overrun/marshal/MemoryStack.java b/src/main/java/overrun/marshal/MemoryStack.java index 3a80290..710d68e 100644 --- a/src/main/java/overrun/marshal/MemoryStack.java +++ b/src/main/java/overrun/marshal/MemoryStack.java @@ -16,10 +16,7 @@ package overrun.marshal; -import java.lang.foreign.AddressLayout; -import java.lang.foreign.Arena; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.ValueLayout; +import java.lang.foreign.*; import java.util.Arrays; import java.util.Objects; @@ -242,6 +239,18 @@ public MemorySegment malloc(long byteSize, long byteAlignment) { return segment().asSlice(pointer, byteSize); } + /** + * Allocates a block of {@code size} bytes of memory on the stack. + * The content of the newly allocated block of memory is not initialized, remaining with + * indeterminate values. + * + * @param layout the layout of the memory segment + * @return the memory segment on the stack for the requested allocation + */ + public MemorySegment malloc(MemoryLayout layout) { + return malloc(layout.byteSize(), layout.byteAlignment()); + } + private MemorySegment malloc(long byteSize, ValueLayout valueLayout) { return malloc(byteSize, valueLayout.byteAlignment()); } diff --git a/src/main/java/overrun/marshal/gen/Skip.java b/src/main/java/overrun/marshal/gen/Skip.java index b145393..36204ff 100644 --- a/src/main/java/overrun/marshal/gen/Skip.java +++ b/src/main/java/overrun/marshal/gen/Skip.java @@ -19,11 +19,11 @@ import java.lang.annotation.*; /** - * Skips generating a marked field or method. + * Skips generating a marked method. *

Example

*
{@code
  * @Skip
- * int LAYOUT;
+ * default int myFunction() { return 1; }
  * }
* * @author squid233 diff --git a/src/test/java/overrun/marshal/test/DowncallSoutTest.java b/src/test/java/overrun/marshal/test/DowncallSoutTest.java new file mode 100644 index 0000000..483dc7a --- /dev/null +++ b/src/test/java/overrun/marshal/test/DowncallSoutTest.java @@ -0,0 +1,132 @@ +/* + * MIT License + * + * Copyright (c) 2024 Overrun Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +package overrun.marshal.test; + +import org.junit.jupiter.api.*; +import overrun.marshal.MemoryStack; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.lang.foreign.Arena; +import java.lang.foreign.SegmentAllocator; + +import static org.junit.jupiter.api.Assertions.*; +import static overrun.marshal.test.TestUtil.*; + +/** + * Test standard output + * + * @author squid233 + * @since 0.1.0 + */ +public final class DowncallSoutTest { + private static IDowncall d; + private static PrintStream stdout = null; + private static ByteArrayOutputStream outputStream = null; + + @BeforeAll + static void beforeAll() { + d = IDowncall.getInstance(false); + } + + @BeforeEach + void setUp() { + stdout = System.out; + outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + } + + @AfterEach + void tearDown() { + System.setOut(stdout); + outputStream.reset(); + } + + @AfterAll + static void afterAll() throws IOException { + if (outputStream != null) { + outputStream.close(); + } + } + + @Test + void test() { + d.test(); + assertEquals("test", outputStream.toString()); + } + + @Test + void testWithEntrypoint() { + d.testWithEntrypoint(); + assertEquals("test", outputStream.toString()); + } + + @Test + void testSkip() { + d.testSkip(); + assertEquals("testSkip", outputStream.toString()); + } + + @Test + void testInt() { + d.testInt(42); + assertEquals("42", outputStream.toString()); + } + + @Test + void testString() { + d.testString(TEST_STRING); + assertEquals(TEST_STRING, outputStream.toString()); + } + + @Test + void testUTF16String() { + d.testUTF16String(utf16Str(TEST_UTF16_STRING)); + assertEquals(TEST_UTF16_STRING, outputStream.toString()); + } + + @Test + void testCEnum() { + d.testCEnum(MyEnum.A); + d.testCEnum(MyEnum.B); + d.testCEnum(MyEnum.C); + assertEquals("024", outputStream.toString()); + } + + @Test + void testIntArray() { + d.testIntArray(new int[]{4, 2}); + try (Arena arena = Arena.ofConfined()) { + d.testIntArray((SegmentAllocator) arena, new int[]{4, 2}); + d.testIntArray(arena, new int[]{4, 2}); + } + try (MemoryStack stack = MemoryStack.stackPush()) { + d.testIntArray(stack, new int[]{4, 2}); + } + d.testVarArgsJava(2, 4, 2); + d.testVarArgsJava(0); + assertEquals("[4, 2][4, 2][4, 2][4, 2][4, 2][]", outputStream.toString()); + } + + @Test + void testSizedIntArray() { + assertThrowsExactly(IllegalArgumentException.class, () -> d.testSizedIntArray(new int[0])); + assertDoesNotThrow(() -> d.testSizedIntArray(new int[]{4, 2})); + assertEquals("[4, 2]", outputStream.toString()); + } +} diff --git a/src/test/java/overrun/marshal/test/DowncallTest.java b/src/test/java/overrun/marshal/test/DowncallTest.java index 4a71cae..fb180e0 100644 --- a/src/test/java/overrun/marshal/test/DowncallTest.java +++ b/src/test/java/overrun/marshal/test/DowncallTest.java @@ -16,19 +16,14 @@ package overrun.marshal.test; -import org.junit.jupiter.api.*; -import overrun.marshal.MemoryStack; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; import java.lang.foreign.ValueLayout; import static org.junit.jupiter.api.Assertions.*; -import static overrun.marshal.test.TestUtil.*; /** * Test downcall @@ -38,84 +33,18 @@ */ public final class DowncallTest { private static IDowncall d; - private static PrintStream stdout = null; - private static ByteArrayOutputStream outputStream = null; @BeforeAll static void beforeAll() { d = IDowncall.getInstance(false); } - @BeforeEach - void setUp() { - stdout = System.out; - outputStream = new ByteArrayOutputStream(); - System.setOut(new PrintStream(outputStream)); - } - - @AfterEach - void tearDown() { - System.setOut(stdout); - outputStream.reset(); - } - - @AfterAll - static void afterAll() throws IOException { - if (outputStream != null) { - outputStream.close(); - } - } - - @Test - void test() { - d.test(); - assertEquals("test", outputStream.toString()); - } - - @Test - void testWithEntrypoint() { - d.testWithEntrypoint(); - assertEquals("test", outputStream.toString()); - } - - @Test - void testSkip() { - d.testSkip(); - assertEquals("testSkip", outputStream.toString()); - } - @Test void testDefault() { assertEquals(42, IDowncall.getInstance(false).testDefault()); assertEquals(84, IDowncall.getInstance(true).testDefault()); } - @Test - void testInt() { - d.testInt(42); - assertEquals("42", outputStream.toString()); - } - - @Test - void testString() { - d.testString(TEST_STRING); - assertEquals(TEST_STRING, outputStream.toString()); - } - - @Test - void testUTF16String() { - d.testUTF16String(utf16Str(TEST_UTF16_STRING)); - assertEquals(TEST_UTF16_STRING, outputStream.toString()); - } - - @Test - void testCEnum() { - d.testCEnum(MyEnum.A); - d.testCEnum(MyEnum.B); - d.testCEnum(MyEnum.C); - assertEquals("024", outputStream.toString()); - } - @Test void testUpcall() { try (Arena arena = Arena.ofConfined()) { @@ -123,21 +52,6 @@ void testUpcall() { } } - @Test - void testIntArray() { - d.testIntArray(new int[]{4, 2}); - try (Arena arena = Arena.ofConfined()) { - d.testIntArray((SegmentAllocator) arena, new int[]{4, 2}); - d.testIntArray(arena, new int[]{4, 2}); - } - try (MemoryStack stack = MemoryStack.stackPush()) { - d.testIntArray(stack, new int[]{4, 2}); - } - d.testVarArgsJava(2, 4, 2); - d.testVarArgsJava(0); - assertEquals("[4, 2][4, 2][4, 2][4, 2][4, 2][]", outputStream.toString()); - } - @Test void testStruct() { try (Arena arena = Arena.ofConfined()) { @@ -156,8 +70,8 @@ void testReturnInt() { @Test void testReturnString() { - assertEquals(TEST_STRING, d.testReturnString()); - assertEquals(TEST_UTF16_STRING, d.testReturnUTF16String()); + assertEquals(TestUtil.TEST_STRING, d.testReturnString()); + assertEquals(TestUtil.TEST_UTF16_STRING, d.testReturnUTF16String()); } @Test @@ -207,13 +121,6 @@ void testReturnIntArray() { assertArrayEquals(new int[]{4, 2}, d.testReturnIntArray()); } - @Test - void testSizedIntArray() { - assertThrowsExactly(IllegalArgumentException.class, () -> d.testSizedIntArray(new int[0])); - assertDoesNotThrow(() -> d.testSizedIntArray(new int[]{4, 2})); - assertEquals("[4, 2]", outputStream.toString()); - } - @Test void testReturnSizedSeg() { final MemorySegment segment = d.testReturnSizedSeg();