Skip to content

wrap-java: translate Java byte[] as [UInt8] - #939

Open
rayman-zhao wants to merge 2 commits into
swiftlang:mainfrom
rayman-zhao:wrap-java-byte-array-uint8
Open

rayman-zhao wants to merge 2 commits into
swiftlang:mainfrom
rayman-zhao:wrap-java-byte-array-uint8

Conversation

@rayman-zhao

Copy link
Copy Markdown
Contributor

Motivation

A Java byte[] is a byte buffer, and Swift code that produces or consumes byte buffers (image codecs, crypto, IO) works in [UInt8]. Importing byte[] as [Int8] forces a redundant type-only conversion at every boundary — e.g. implementations of Java native methods that fetch encoded images as [UInt8] must copy into [Int8] (one allocation + memcpy per call) purely to satisfy the type system.

The runtime already has a fast path bridging [UInt8] and byte[] directly via SetByteArrayRegion (JavaValue+Array.swift), and the export direction already maps UInt8 to byte (see JavaType+SwiftNames.swift). This makes the import direction symmetric for arrays.

Scalar byte stays Int8, matching Java's signed byte — only arrays change, since byte[] is buffer-shaped while a scalar byte is numeric.

Modification

  • JavaTranslator.getSwiftTypeName now maps .array(.byte) to [UInt8] instead of composing the scalar mapping.
  • Removed the "byte[]": [UInt8] entry from translatedClasses — it was unreachable (reflected array classes are named [B and parsed as JavaType, never hitting the string-keyed table); the new special case implements what that entry intended.
  • Regenerated the affected wrappers (39 signatures across ByteBuffer, JavaString, InputStream, OutputStream, JavaClassLoader, BufferedInputStream, BitSet, ZipEntry, JarInputStream flip [Int8] → [UInt8]).
  • Updated testCovariantInJavaNotInSwiftOverride3; added testByteArrayTranslatesToUInt8AndScalarByteStaysInt8 covering both the array and the scalar mapping.

Source compatibility

⚠️ Source-breaking for wrap-java consumers: Swift signatures involving byte[] change from [Int8] to [UInt8] (both JavaKit call sites and implementations of Java native methods). The JNI bridge accepts both element types unchanged, so only the Swift-level types move. I judged this acceptable pre-1.0; happy to rework if a different policy is preferred (e.g. keeping [Int8] and doing the flip at a major boundary).

Verified locally by regenerating all stdlib wrappers (baseline before the change reproduced committed files byte-for-byte on JDK 25) and by wrapping java.lang.String / java.lang.reflect.Array in struct mode to match the new test expectations. Full swift test could not run on Windows locally (the package-benchmark plugin target and repo symlink layout do not build there); relying on CI.

A Java byte[] is a byte buffer, and Swift's idiomatic buffer element type
is UInt8; the export direction already maps UInt8 to byte and the JNI
bridge has a fast path for both element types. Mapping byte[] to [Int8]
forced every wrap-java consumer to convert buffers element-type-only,
adding an allocation and memcpy per boundary call.

Scalar byte stays Int8, matching Java's signed byte.

Source-breaking: Swift signatures involving byte[] change from [Int8]
to [UInt8]. Regenerated affected wrappers.
@rayman-zhao
rayman-zhao requested a review from ktoso as a code owner October 24, 2026 13:44
JavaClassTranslator read .class bytes via the generated
InputStream.readAllBytes() wrapper, which now returns [UInt8];
drop the now-unnecessary bitPattern conversion shim. Update the
JavaKitSampleApp array tests to the new [UInt8] signatures and a
format nit in JavaTranslator.
@rayman-zhao

Copy link
Copy Markdown
Contributor Author

Fixed the CI fallout in 025fec8 — apologies for the noise:

  • JavaClassTranslator reads .class bytes through the generated InputStream.readAllBytes() wrapper, so the signature flip broke the toolchain's own build (UInt8(bitPattern:) only accepts Int8). The bitPattern shim existed purely because of the old [Int8] mapping and is now gone.
  • Updated the JavaKitSampleApp array tests to [UInt8].
  • Rebuilt the full toolchain against the flipped wrappers, verified regeneration is stable (byte-identical after the fix), and linted.

The sample apps and linkage/benchmark checks were cascade failures of the toolchain build error; they should be green now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant