Skip to content
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
2 changes: 1 addition & 1 deletion Sources/SwiftJavaJNICore/JavaDemanglingError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//

/// Describes an error that can occur when demangling a Java name.
enum JavaDemanglingError: Error {
public enum JavaDemanglingError: Error {
/// This does not match the form of a Java mangled type name.
case invalidMangledName(String)

Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftJavaJNICore/JavaEnvironment+Refs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extension UnsafeMutablePointer<JNIEnv?> {
/// pending exception — it prints the stack trace to stderr and does **not**
/// clear the exception.
@inline(__always)
internal func throwPushLocalFrameOOM(capacity: Int) throws -> Never {
internal func throwPushLocalFrameOOM(capacity: Int) throws(JNIError) -> Never {
if describeOOMException {
// Print the pending OutOfMemoryError stack trace to stderr.
// ExceptionDescribe does not clear the exception.
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftJavaJNICore/JavaType+JavaSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension JavaType {
/// Form a Java type based on the name that is produced by
/// java.lang.Class.getName(). This can be primitive types like "int",
/// class types like "java.lang.String", or arrays thereof.
public init(javaTypeName: String) throws {
public init(javaTypeName: String) throws(JavaDemanglingError) {
switch javaTypeName {
case "boolean": self = .boolean
case "byte": self = .byte
Expand Down
6 changes: 3 additions & 3 deletions Sources/SwiftJavaJNICore/Mangling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

extension JavaType {
/// Demangle a Java type name into a representation of the type.
public init(mangledName: String) throws {
public init(mangledName: String) throws(JavaDemanglingError) {
var mangledName = mangledName[...]
self = try JavaType.demangleNextType(from: &mangledName)
if !mangledName.isEmpty {
Expand Down Expand Up @@ -43,7 +43,7 @@ extension JavaType {

extension MethodSignature {
/// Demangle the given method Java signature.
public init(mangledName: String) throws {
public init(mangledName: String) throws(JavaDemanglingError) {
// Method signatures have the form "(parameter-types)result-type".
guard mangledName.starts(with: "(") else {
throw JavaDemanglingError.invalidMangledName(mangledName)
Expand Down Expand Up @@ -82,7 +82,7 @@ extension MethodSignature {
extension JavaType {
/// Demangle the next Java type from the given string, shrinking the input
/// string and producing demangled type.
static func demangleNextType(from string: inout Substring) throws -> JavaType {
static func demangleNextType(from string: inout Substring) throws(JavaDemanglingError) -> JavaType {
guard let firstChar = string.first else {
throw JavaDemanglingError.invalidMangledName(String(string))
}
Expand Down
24 changes: 12 additions & 12 deletions Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public final class JavaVirtualMachine: @unchecked Sendable {
classpath: [String] = [],
vmOptions: [String] = [],
ignoreUnrecognized: Bool = false
) throws {
) throws(VMError) {
self.classpath = classpath
var jvm: JavaVMPointer? = nil
var environment: JNIEnvPointer? = nil
Expand Down Expand Up @@ -141,7 +141,7 @@ public final class JavaVirtualMachine: @unchecked Sendable {
self.destroyOnDeinit = .init(initialState: true)
}

public func destroyJVM() throws {
public func destroyJVM() throws(VMError) {
try self.detachCurrentThread()
if let error = VMError(fromJNIError: jvm.pointee!.pointee.DestroyJavaVM(jvm)) {
throw error
Expand Down Expand Up @@ -177,7 +177,7 @@ extension JavaVirtualMachine {
/// - Parameter
/// - asDaemon: Whether this thread should be treated as a daemon
/// thread in the Java Virtual Machine.
public func environment(asDaemon: Bool = false) throws -> JNIEnvironment {
public func environment(asDaemon: Bool = false) throws(VMError) -> JNIEnvironment {
// Check whether this thread is already attached. If so, return the
// corresponding environment.
var environment: UnsafeMutableRawPointer? = nil
Expand Down Expand Up @@ -213,7 +213,7 @@ extension JavaVirtualMachine {

/// Detach the current thread from the Java Virtual Machine. All Java
/// threads waiting for this thread to die are notified.
func detachCurrentThread() throws {
func detachCurrentThread() throws(VMError) {
if let resultError = VMError(fromJNIError: jvm.pointee!.pointee.DetachCurrentThread(jvm)) {
throw resultError
}
Expand Down Expand Up @@ -260,13 +260,13 @@ extension JavaVirtualMachine {
vmOptions: [String] = [],
ignoreUnrecognized: Bool = false,
replace: Bool = false
) throws -> JavaVirtualMachine {
) throws(VMError) -> JavaVirtualMachine {
precondition(
!classpath.contains(where: { $0.contains(FileManager.pathSeparator) }),
"Classpath element must not contain `\(FileManager.pathSeparator)`! Split the path into elements! Was: \(classpath)"
)

return try sharedJVM.withLock { (sharedJVMPointer: inout JavaVirtualMachine?) in
return try sharedJVM.withLock { (sharedJVMPointer: inout JavaVirtualMachine?) throws(VMError) in
// If we already have a JavaVirtualMachine instance, return it.
if replace {
print("[swift-java] Replace JVM instance!")
Expand Down Expand Up @@ -318,6 +318,10 @@ extension JavaVirtualMachine {
// through the loop again to pick up the underlying JVM pointer.
wasExistingVM = true
continue
} catch let error as VMError {
throw error
} catch {
fatalError("Unexpected non-VMError from JavaVirtualMachine.init: \(error)")
}

sharedJVMPointer = javaVirtualMachine
Expand Down Expand Up @@ -347,7 +351,7 @@ extension JavaVirtualMachine {

extension JavaVirtualMachine {
/// Describes the kinds of errors that can occur when interacting with JNI.
enum VMError: Error {
public enum VMError: Error {
/// There is already a Java Virtual Machine.
case existingVM

Expand Down Expand Up @@ -393,10 +397,6 @@ extension JavaVirtualMachine {
}
}
}

enum JavaKitError: Error {
case classpathEntryNotFound(entry: String, classpath: [String])
}
}

// ==== ------------------------------------------------------------------------
Expand Down Expand Up @@ -459,7 +459,7 @@ func systemJavaHome() -> String? {
}

/// Located the shared library that includes the `JNI_GetCreatedJavaVMs` and `JNI_CreateJavaVM` entry points to the `JNINativeInterface` function table
private func loadLibJava() throws -> DylibType {
private func loadLibJava() throws(JavaVirtualMachine.VMError) -> DylibType {
#if os(Android)
for libname in ["libart.so", "libdvm.so", "libnativehelper.so"] {
if let lib = dlopen(libname, RTLD_NOW) {
Expand Down
34 changes: 16 additions & 18 deletions Sources/SwiftJavaJNICore/VirtualMachine/LockedState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,26 +111,24 @@ package struct LockedState<State> {
)
}

package func withLock<T>(_ body: @Sendable (inout State) throws -> T) rethrows -> T {
package func withLock<T, E: Error>(_ body: @Sendable (inout State) throws(E) -> T) throws(E) -> T {
try withLockUnchecked(body)
}

package func withLockUnchecked<T>(_ body: (inout State) throws -> T) rethrows -> T {
try _buffer.withUnsafeMutablePointers { state, lock in
_Lock.lock(lock)
defer { _Lock.unlock(lock) }
return try body(&state.pointee)
}
package func withLockUnchecked<T, E: Error>(_ body: (inout State) throws(E) -> T) throws(E) -> T {
_buffer.withUnsafeMutablePointerToElements { _Lock.lock($0) }
defer { _buffer.withUnsafeMutablePointerToElements { _Lock.unlock($0) } }
return try body(&_buffer.header)
}

// Ensures the managed state outlives the locked scope.
package func withLockExtendingLifetimeOfState<T>(_ body: @Sendable (inout State) throws -> T) rethrows -> T {
try _buffer.withUnsafeMutablePointers { state, lock in
_Lock.lock(lock)
return try withExtendedLifetime(state.pointee) {
defer { _Lock.unlock(lock) }
return try body(&state.pointee)
}
package func withLockExtendingLifetimeOfState<T, E: Error>(_ body: @Sendable (inout State) throws(E) -> T) throws(E) -> T {
_buffer.withUnsafeMutablePointerToElements { _Lock.lock($0) }
defer { _buffer.withUnsafeMutablePointerToElements { _Lock.unlock($0) } }
do {
return try body(&_buffer.header)
} catch {
throw error
}
}
}
Expand All @@ -140,10 +138,10 @@ extension LockedState where State == Void {
self.init(initialState: ())
}

package func withLock<R: Sendable>(_ body: @Sendable () throws -> R) rethrows -> R {
try withLock { _ in
try body()
}
package func withLock<R: Sendable, E: Error>(_ body: @Sendable () throws(E) -> R) throws(E) -> R {
_buffer.withUnsafeMutablePointerToElements { _Lock.lock($0) }
defer { _buffer.withUnsafeMutablePointerToElements { _Lock.unlock($0) } }
return try body()
}

package func lock() {
Expand Down
Loading