Skip to content

Commit 2fe5c03

Browse files
committed
Map all of the documented JNI errors to cases in the Swift VMError
This also cleans up various error-handling code paths that were doing narrow checks.
1 parent 7ec7f89 commit 2fe5c03

File tree

1 file changed

+39
-19
lines changed

1 file changed

+39
-19
lines changed

Sources/JavaKitVM/JavaVirtualMachine.swift

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,8 @@ public final class JavaVirtualMachine: @unchecked Sendable {
8484
vmArgs.nOptions = jint(optionsBuffer.count)
8585

8686
// Create the JVM instance.
87-
let createResult = JNI_CreateJavaVM(&jvm, &environment, &vmArgs)
88-
if createResult != JNI_OK {
89-
if createResult == JNI_EEXIST {
90-
throw VMError.existingVM
91-
}
92-
93-
throw VMError.failedToCreateVM
87+
if let createError = VMError(fromJNIError: JNI_CreateJavaVM(&jvm, &environment, &vmArgs)) {
88+
throw createError
9489
}
9590

9691
self.jvm = jvm!
@@ -100,8 +95,8 @@ public final class JavaVirtualMachine: @unchecked Sendable {
10095
deinit {
10196
if destroyOnDeinit {
10297
// Destroy the JVM.
103-
if jvm.pointee!.pointee.DestroyJavaVM(jvm) != JNI_OK {
104-
fatalError("Failed to destroy the JVM.")
98+
if let resultError = VMError(fromJNIError: jvm.pointee!.pointee.DestroyJavaVM(jvm)) {
99+
fatalError("Failed to destroy the JVM: \(resultError)")
105100
}
106101
}
107102
}
@@ -136,19 +131,19 @@ extension JavaVirtualMachine {
136131
attachResult = jvm.pointee!.pointee.AttachCurrentThread(jvm, &environment, nil)
137132
}
138133

139-
if attachResult == JNI_OK, let environment {
140-
return environment.assumingMemoryBound(to: JNIEnv?.self)
134+
// If we failed to attach, report that.
135+
if let attachError = VMError(fromJNIError: attachResult) {
136+
throw attachError
141137
}
142138

143-
throw VMError.failedToAttachThread
139+
return environment!.assumingMemoryBound(to: JNIEnv?.self)
144140
}
145141

146142
/// Detach the current thread from the Java Virtual Machine. All Java
147143
/// threads waiting for this thread to die are notified.
148144
public func detachCurrentThread() throws {
149-
let result = jvm.pointee!.pointee.DetachCurrentThread(jvm)
150-
if result != JNI_OK {
151-
throw VMError.failedToDetachThread
145+
if let resultError = VMError(fromJNIError: jvm.pointee!.pointee.DetachCurrentThread(jvm)) {
146+
throw resultError
152147
}
153148
}
154149
}
@@ -234,11 +229,36 @@ extension JavaVirtualMachine {
234229
}
235230

236231
extension JavaVirtualMachine {
232+
/// Describes the kinds of errors that can occur when interacting with JNI.
237233
enum VMError: Error {
238-
case failedToCreateVM
239-
case failedToAttachThread
240-
case failedToDetachThread
241-
case failedToQueryVM
234+
/// There is already a Java Virtual Machine.
242235
case existingVM
236+
237+
/// JNI version mismatch error.
238+
case jniVersion
239+
240+
/// Thread is detached from the VM.
241+
case threadDetached
242+
243+
/// Out of memory.
244+
case outOfMemory
245+
246+
/// Invalid arguments.
247+
case invalidArguments
248+
249+
/// Unknown JNI error.
250+
case unknown(jint)
251+
252+
init?(fromJNIError error: jint) {
253+
switch error {
254+
case JNI_OK: return nil
255+
case JNI_EDETACHED: self = .threadDetached
256+
case JNI_EVERSION: self = .jniVersion
257+
case JNI_ENOMEM: self = .outOfMemory
258+
case JNI_EEXIST: self = .existingVM
259+
case JNI_EINVAL: self = .invalidArguments
260+
default: self = .unknown(error)
261+
}
262+
}
243263
}
244264
}

0 commit comments

Comments
 (0)