Skip to content

Commit 00a8cc5

Browse files
Flatout73Tatenda-k
authored andcommitted
JNI: fix non-compiling async thunks for protocol boxes and generic types (#905)
1 parent aa220df commit 00a8cc5

22 files changed

Lines changed: 1567 additions & 37 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2026 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
private let int32BufferStorage: [Int32] = [10, 20, 30, 40]
16+
private let emptyInt32BufferStorage: [Int32] = []
17+
private var mutableInt32BufferStorage: [Int32] = [5, 10, 15]
18+
19+
public func makeInt32Buffer() -> UnsafeBufferPointer<Int32> {
20+
int32BufferStorage.withUnsafeBufferPointer { $0 }
21+
}
22+
23+
public func makeEmptyInt32Buffer() -> UnsafeBufferPointer<Int32> {
24+
emptyInt32BufferStorage.withUnsafeBufferPointer { $0 }
25+
}
26+
27+
public func sumInt32Buffer(data: UnsafeBufferPointer<Int32>) -> Int64 {
28+
data.reduce(0) { $0 + Int64($1) }
29+
}
30+
31+
public func makeMutableInt32Buffer() -> UnsafeMutableBufferPointer<Int32> {
32+
mutableInt32BufferStorage.withUnsafeMutableBufferPointer { $0 }
33+
}
34+
35+
public func sumMutableInt32Buffer(data: UnsafeMutableBufferPointer<Int32>) -> Int64 {
36+
data.reduce(0) { $0 + Int64($1) }
37+
}
38+
39+
public func mutableInt32BufferElement(data: UnsafeMutableBufferPointer<Int32>, index: Int32) -> Int32 {
40+
data[Int(index)]
41+
}
42+
43+
public func incrementMutableInt32Buffer(data: UnsafeMutableBufferPointer<Int32>) {
44+
for index in data.indices {
45+
data[index] += 1
46+
}
47+
}

Samples/SwiftJavaExtractFFMSampleApp/Sources/MySwiftLibrary/UnsafeRawBufferPointer.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,19 @@ public func sumOfBytes(data: UnsafeRawBufferPointer) -> Int64 {
2929
public func bufferCount(data: UnsafeRawBufferPointer) -> Int64 {
3030
Int64(data.count)
3131
}
32+
33+
private let rawBufferStorage: [UInt8] = [10, 20, 30, 40]
34+
private let emptyRawBufferStorage: [UInt8] = []
35+
private var mutableRawBufferStorage: [UInt8] = [5, 10, 15]
36+
37+
public func makeRawBuffer() -> UnsafeRawBufferPointer {
38+
rawBufferStorage.withUnsafeBytes { $0 }
39+
}
40+
41+
public func makeEmptyRawBuffer() -> UnsafeRawBufferPointer {
42+
emptyRawBufferStorage.withUnsafeBytes { $0 }
43+
}
44+
45+
public func makeMutableRawBuffer() -> UnsafeMutableRawBufferPointer {
46+
mutableRawBufferStorage.withUnsafeMutableBytes { $0 }
47+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2026 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
package com.example.swift;
16+
17+
import org.junit.jupiter.api.Test;
18+
19+
import java.lang.foreign.Arena;
20+
import java.lang.foreign.MemorySegment;
21+
import java.lang.foreign.ValueLayout;
22+
23+
import static org.junit.jupiter.api.Assertions.assertEquals;
24+
25+
public class UnsafeBufferPointerTest {
26+
@Test
27+
void nullMemorySegment_isEmptyTypedBuffer() {
28+
assertEquals(0, MySwiftLibrary.sumInt32Buffer(MemorySegment.NULL));
29+
}
30+
31+
@Test
32+
void sumInt32Buffer() {
33+
try (Arena arena = Arena.ofConfined()) {
34+
MemorySegment input = arena.allocateFrom(ValueLayout.JAVA_INT, new int[] {10, 20, 30, 40});
35+
36+
assertEquals(100, MySwiftLibrary.sumInt32Buffer(input));
37+
}
38+
}
39+
40+
@Test
41+
void sumInt32Buffer_empty() {
42+
try (Arena arena = Arena.ofConfined()) {
43+
MemorySegment input = arena.allocate(0, ValueLayout.JAVA_INT.byteAlignment());
44+
45+
assertEquals(0, MySwiftLibrary.sumInt32Buffer(input));
46+
}
47+
}
48+
49+
@Test
50+
void returnInt32Buffer() {
51+
MemorySegment result = MySwiftLibrary.makeInt32Buffer();
52+
53+
assertEquals(16, result.byteSize());
54+
assertEquals(10, result.get(ValueLayout.JAVA_INT, 0));
55+
assertEquals(40, result.get(ValueLayout.JAVA_INT, 12));
56+
}
57+
58+
@Test
59+
void returnEmptyInt32Buffer() {
60+
assertEquals(0, MySwiftLibrary.makeEmptyInt32Buffer().byteSize());
61+
}
62+
63+
@Test
64+
void returnMutableInt32Buffer() {
65+
MemorySegment result = MySwiftLibrary.makeMutableInt32Buffer();
66+
67+
assertEquals(12, result.byteSize());
68+
assertEquals(5, result.get(ValueLayout.JAVA_INT, 0));
69+
assertEquals(15, result.get(ValueLayout.JAVA_INT, 8));
70+
}
71+
72+
@Test
73+
void mutableInt32Buffer_isInitialized() {
74+
MemorySegment buffer = MySwiftLibrary.makeMutableInt32Buffer();
75+
76+
assertEquals(5, buffer.get(ValueLayout.JAVA_INT, 0));
77+
assertEquals(10, buffer.get(ValueLayout.JAVA_INT, 4));
78+
assertEquals(15, buffer.get(ValueLayout.JAVA_INT, 8));
79+
}
80+
81+
@Test
82+
void incrementMutableInt32Buffer_modifiesElements() {
83+
try (Arena arena = Arena.ofConfined()) {
84+
MemorySegment buffer = arena.allocateFrom(ValueLayout.JAVA_INT, new int[] {5, 10, 15});
85+
86+
MySwiftLibrary.incrementMutableInt32Buffer(buffer);
87+
88+
assertEquals(6, buffer.get(ValueLayout.JAVA_INT, 0));
89+
assertEquals(11, buffer.get(ValueLayout.JAVA_INT, 4));
90+
assertEquals(16, buffer.get(ValueLayout.JAVA_INT, 8));
91+
}
92+
}
93+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2026 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
package com.example.swift;
16+
17+
import org.junit.jupiter.api.Test;
18+
19+
import java.lang.foreign.Arena;
20+
import java.lang.foreign.MemorySegment;
21+
import java.lang.foreign.ValueLayout;
22+
23+
import static org.junit.jupiter.api.Assertions.assertEquals;
24+
25+
public class UnsafeRawBufferPointerTest {
26+
@Test
27+
void sumOfBytes() {
28+
try (Arena arena = Arena.ofConfined()) {
29+
MemorySegment input = arena.allocateFrom(ValueLayout.JAVA_BYTE, new byte[] {1, 2, 3, 4, 5});
30+
31+
assertEquals(15, MySwiftLibrary.sumOfBytes(input));
32+
}
33+
}
34+
35+
@Test
36+
void sumOfBytes_empty() {
37+
try (Arena arena = Arena.ofConfined()) {
38+
MemorySegment input = arena.allocate(0, 1);
39+
40+
assertEquals(0, MySwiftLibrary.sumOfBytes(input));
41+
}
42+
}
43+
44+
@Test
45+
void bufferCount() {
46+
try (Arena arena = Arena.ofConfined()) {
47+
MemorySegment input = arena.allocateFrom(ValueLayout.JAVA_BYTE, new byte[] {10, 20, 30, 40});
48+
49+
assertEquals(4, MySwiftLibrary.bufferCount(input));
50+
}
51+
}
52+
53+
@Test
54+
void bufferCount_empty() {
55+
try (Arena arena = Arena.ofConfined()) {
56+
MemorySegment input = arena.allocate(0, 1);
57+
58+
assertEquals(0, MySwiftLibrary.bufferCount(input));
59+
}
60+
}
61+
62+
@Test
63+
void returnRawBuffer() {
64+
MemorySegment result = MySwiftLibrary.makeRawBuffer();
65+
66+
assertEquals(4, result.byteSize());
67+
assertEquals(10, result.get(ValueLayout.JAVA_BYTE, 0));
68+
assertEquals(40, result.get(ValueLayout.JAVA_BYTE, 3));
69+
}
70+
71+
@Test
72+
void returnEmptyRawBuffer() {
73+
assertEquals(0, MySwiftLibrary.makeEmptyRawBuffer().byteSize());
74+
}
75+
76+
@Test
77+
void returnMutableRawBuffer() {
78+
MemorySegment result = MySwiftLibrary.makeMutableRawBuffer();
79+
80+
assertEquals(3, result.byteSize());
81+
assertEquals(5, result.get(ValueLayout.JAVA_BYTE, 0));
82+
assertEquals(15, result.get(ValueLayout.JAVA_BYTE, 2));
83+
}
84+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2026 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import SwiftJava
16+
17+
private let int32BufferStorage: [Int32] = [10, 20, 30, 40]
18+
private let emptyInt32BufferStorage: [Int32] = []
19+
private var mutableInt32BufferStorage: [Int32] = [5, 10, 15]
20+
21+
public func makeInt32Buffer() -> UnsafeBufferPointer<Int32> {
22+
int32BufferStorage.withUnsafeBufferPointer { $0 }
23+
}
24+
25+
public func makeEmptyInt32Buffer() -> UnsafeBufferPointer<Int32> {
26+
emptyInt32BufferStorage.withUnsafeBufferPointer { $0 }
27+
}
28+
29+
public func sumInt32Buffer(data: UnsafeBufferPointer<Int32>) -> Int64 {
30+
data.reduce(0) { $0 + Int64($1) }
31+
}
32+
33+
public func makeMutableInt32Buffer() -> UnsafeMutableBufferPointer<Int32> {
34+
mutableInt32BufferStorage.withUnsafeMutableBufferPointer { $0 }
35+
}
36+
37+
public func sumMutableInt32Buffer(data: UnsafeMutableBufferPointer<Int32>) -> Int64 {
38+
data.reduce(0) { $0 + Int64($1) }
39+
}
40+
41+
public func mutableInt32BufferElement(data: UnsafeMutableBufferPointer<Int32>, index: Int32) -> Int32 {
42+
data[Int(index)]
43+
}
44+
45+
public func incrementMutableInt32Buffer(data: UnsafeMutableBufferPointer<Int32>) {
46+
for index in data.indices {
47+
data[index] += 1
48+
}
49+
}

Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/UnsafeRawBufferPointer.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,20 @@ public func sumOfBytes(data: UnsafeRawBufferPointer) -> Int64 {
2828
public func bufferCount(data: UnsafeRawBufferPointer) -> Int64 {
2929
Int64(data.count)
3030
}
31-
// snippet.end
31+
//snippet.end
32+
33+
private let rawBufferStorage: [UInt8] = [10, 20, 30, 40]
34+
private let emptyRawBufferStorage: [UInt8] = []
35+
private var mutableRawBufferStorage: [UInt8] = [5, 10, 15]
36+
37+
public func makeRawBuffer() -> UnsafeRawBufferPointer {
38+
rawBufferStorage.withUnsafeBytes { $0 }
39+
}
40+
41+
public func makeEmptyRawBuffer() -> UnsafeRawBufferPointer {
42+
emptyRawBufferStorage.withUnsafeBytes { $0 }
43+
}
44+
45+
public func makeMutableRawBuffer() -> UnsafeMutableRawBufferPointer {
46+
mutableRawBufferStorage.withUnsafeMutableBytes { $0 }
47+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2026 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
package com.example.swift;
16+
17+
import org.junit.jupiter.api.Test;
18+
import org.swift.swiftkit.core.SwiftUnsafeBufferPointer;
19+
import org.swift.swiftkit.core.SwiftUnsafeMutableBufferPointer;
20+
21+
import static org.junit.jupiter.api.Assertions.*;
22+
23+
public class UnsafeBufferPointerTest {
24+
@Test
25+
void returnInt32Buffer() {
26+
SwiftUnsafeBufferPointer buffer = MySwiftLibrary.makeInt32Buffer();
27+
28+
assertNotEquals(0, buffer.getBaseAddress());
29+
assertEquals(4, buffer.getCount());
30+
assertEquals(100, MySwiftLibrary.sumInt32Buffer(buffer));
31+
}
32+
33+
@Test
34+
void returnEmptyInt32Buffer() {
35+
SwiftUnsafeBufferPointer buffer = MySwiftLibrary.makeEmptyInt32Buffer();
36+
assertEquals(0, buffer.getBaseAddress());
37+
assertEquals(0, buffer.getCount());
38+
assertEquals(0, MySwiftLibrary.sumInt32Buffer(buffer));
39+
}
40+
41+
@Test
42+
void returnMutableInt32Buffer() {
43+
SwiftUnsafeMutableBufferPointer buffer = MySwiftLibrary.makeMutableInt32Buffer();
44+
45+
assertNotEquals(0, buffer.getBaseAddress());
46+
assertEquals(3, buffer.getCount());
47+
assertEquals(30, MySwiftLibrary.sumMutableInt32Buffer(buffer));
48+
}
49+
50+
51+
@Test
52+
void mutableInt32Buffer_isInitialized() {
53+
SwiftUnsafeMutableBufferPointer buffer = MySwiftLibrary.makeMutableInt32Buffer();
54+
55+
assertEquals(5, MySwiftLibrary.mutableInt32BufferElement(buffer, 0));
56+
assertEquals(10, MySwiftLibrary.mutableInt32BufferElement(buffer, 1));
57+
assertEquals(15, MySwiftLibrary.mutableInt32BufferElement(buffer, 2));
58+
}
59+
60+
@Test
61+
void incrementMutableInt32Buffer_modifiesElements() {
62+
SwiftUnsafeMutableBufferPointer buffer = MySwiftLibrary.makeMutableInt32Buffer();
63+
64+
MySwiftLibrary.incrementMutableInt32Buffer(buffer);
65+
66+
assertEquals(6, MySwiftLibrary.mutableInt32BufferElement(buffer, 0));
67+
assertEquals(11, MySwiftLibrary.mutableInt32BufferElement(buffer, 1));
68+
assertEquals(16, MySwiftLibrary.mutableInt32BufferElement(buffer, 2));
69+
}
70+
}

0 commit comments

Comments
 (0)