Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
6 changes: 3 additions & 3 deletions pkgs/jni/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.8.0"
version: "0.9.3-wip"
js:
dependency: transitive
description:
Expand Down Expand Up @@ -490,10 +490,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: e7d5ecd604e499358c5fe35ee828c0298a320d54455e791e9dcf73486bc8d9f0
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
url: "https://pub.dev"
source: hosted
version: "14.1.0"
version: "14.2.1"
watcher:
dependency: transitive
description:
Expand Down
43 changes: 26 additions & 17 deletions pkgs/jni/java/src/main/java/com/github/dart_lang/jni/PortProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
import java.lang.reflect.*;

public class PortProxy implements InvocationHandler {
private static final PortCleaner cleaner = new PortCleaner();

static {
System.loadLibrary("dartjni");
}

private static final PortCleaner cleaner = new PortCleaner();
private final long port;
private final long isolateId;
private final long functionPtr;
Expand Down Expand Up @@ -73,22 +74,6 @@ public static Object newInstance(String binaryName, long port, long isolateId, l
return obj;
}

private static final class DartException extends Exception {
private DartException(String message) {
super(message);
}
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws DartException {
Object[] result = _invoke(port, isolateId, functionPtr, proxy, getDescriptor(method), args);
_cleanUp((Long) result[0]);
if (result[1] instanceof DartException) {
throw (DartException) result[1];
}
return result[1];
}

/// Returns an array with two objects:
/// [0]: The address of the result pointer used for the clean-up.
/// [1]: The result of the invocation.
Expand All @@ -101,4 +86,28 @@ private static native Object[] _invoke(
Object[] args);

private static native void _cleanUp(long resultPtr);

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object[] result = _invoke(port, isolateId, functionPtr, proxy, getDescriptor(method), args);
_cleanUp((Long) result[0]);
if (result[1] instanceof DartException) {
Throwable cause = ((DartException) result[1]).cause;
if (cause != null) {
throw cause;
} else {
throw (DartException) result[1];
}
}
return result[1];
}

private static final class DartException extends Exception {
Throwable cause;

private DartException(String message, Throwable cause) {
super(message);
this.cause = cause;
}
}
}
18 changes: 13 additions & 5 deletions pkgs/jni/lib/src/jni.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import 'dart:io';
import 'dart:isolate';

import 'package:ffi/ffi.dart';
import 'package:jni/jni.dart';
import 'package:path/path.dart';

import 'errors.dart';
import 'jreference.dart';
import 'third_party/generated_bindings.dart';
import 'accessors.dart';
import 'third_party/generated_bindings.dart';

String _getLibraryFileName(String base) {
if (Platform.isLinux || Platform.isAndroid) {
Expand Down Expand Up @@ -221,6 +220,8 @@ typedef _SetJniGettersDartType = void Function(Pointer<Void>, Pointer<Void>);

/// Extensions for use by `jnigen` generated code.
extension ProtectedJniExtensions on Jni {
static final _jThrowableClass = JClass.forName('java/lang/Throwable');

static Pointer<T> Function<T extends NativeType>(String) initGeneratedLibrary(
String name) {
var path = _getLibraryFileName(name);
Expand All @@ -237,9 +238,16 @@ extension ProtectedJniExtensions on Jni {
}

/// Returns a new DartException.
static Pointer<Void> newDartException(String message) {
static Pointer<Void> newDartException(Object exception) {
JObjectPtr? cause;
if (exception is JObject &&
Jni.env.IsInstanceOf(
exception.reference.pointer, _jThrowableClass.reference.pointer)) {
cause = exception.reference.pointer;
}
return Jni._bindings
.DartException__ctor(Jni.env.toJStringPtr(message))
.DartException__ctor(
Jni.env.toJStringPtr(exception.toString()), cause ?? nullptr)
.objectPointer;
}

Expand Down
2 changes: 1 addition & 1 deletion pkgs/jni/lib/src/jprimitives.dart
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ final class jdoubleType extends JType<jdouble>
}

abstract final class jvoid extends JPrimitive {
static const type = jdoubleType();
static const type = jvoidType();
}

final class jvoidType extends JType<jvoid> with JCallable<jvoid, void> {
Expand Down
92 changes: 71 additions & 21 deletions pkgs/jni/lib/src/third_party/jni_bindings_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,19 @@ class JniBindings {

JniResult DartException__ctor(
JStringPtr message,
JThrowablePtr cause,
) {
return _DartException__ctor(
message,
cause,
);
}

late final _DartException__ctorPtr =
_lookup<ffi.NativeFunction<JniResult Function(JStringPtr)>>(
'DartException__ctor');
late final _DartException__ctor =
_DartException__ctorPtr.asFunction<JniResult Function(JStringPtr)>();
late final _DartException__ctorPtr = _lookup<
ffi.NativeFunction<JniResult Function(JStringPtr, JThrowablePtr)>>(
'DartException__ctor');
late final _DartException__ctor = _DartException__ctorPtr.asFunction<
JniResult Function(JStringPtr, JThrowablePtr)>();

JniResult PortContinuation__ctor(
int j,
Expand Down Expand Up @@ -2081,30 +2083,78 @@ final class CallbackResult extends ffi.Struct {
external JObjectPtr object;
}

typedef MutexLock = pthread_mutex_t;
typedef pthread_mutex_t = __darwin_pthread_mutex_t;
typedef __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;
typedef MutexLock = CRITICAL_SECTION;
typedef CRITICAL_SECTION = RTL_CRITICAL_SECTION;
typedef RTL_CRITICAL_SECTION = _RTL_CRITICAL_SECTION;

final class _opaque_pthread_mutex_t extends ffi.Struct {
@ffi.Long()
external int __sig;
final class _RTL_CRITICAL_SECTION extends ffi.Struct {
external PRTL_CRITICAL_SECTION_DEBUG DebugInfo;

@ffi.Array.multi([56])
external ffi.Array<ffi.Char> __opaque;
@LONG()
external int LockCount;

@LONG()
external int RecursionCount;

external HANDLE OwningThread;

external HANDLE LockSemaphore;

@ULONG_PTR()
external int SpinCount;
}

typedef PRTL_CRITICAL_SECTION_DEBUG = ffi.Pointer<_RTL_CRITICAL_SECTION_DEBUG>;

final class _RTL_CRITICAL_SECTION_DEBUG extends ffi.Struct {
@WORD()
external int Type;

@WORD()
external int CreatorBackTraceIndex;

external ffi.Pointer<_RTL_CRITICAL_SECTION> CriticalSection;

external LIST_ENTRY ProcessLocksList;

@DWORD()
external int EntryCount;

@DWORD()
external int ContentionCount;

@DWORD()
external int Flags;

@WORD()
external int CreatorBackTraceIndexHigh;

@WORD()
external int Identifier;
}

typedef ConditionVariable = pthread_cond_t;
typedef pthread_cond_t = __darwin_pthread_cond_t;
typedef __darwin_pthread_cond_t = _opaque_pthread_cond_t;
typedef WORD = ffi.UnsignedShort;
typedef LIST_ENTRY = _LIST_ENTRY;

final class _LIST_ENTRY extends ffi.Struct {
external ffi.Pointer<_LIST_ENTRY> Flink;

external ffi.Pointer<_LIST_ENTRY> Blink;
}

final class _opaque_pthread_cond_t extends ffi.Struct {
@ffi.Long()
external int __sig;
typedef DWORD = ffi.UnsignedLong;
typedef LONG = ffi.Long;
typedef HANDLE = ffi.Pointer<ffi.Void>;
typedef ULONG_PTR = ffi.UnsignedLongLong;
typedef ConditionVariable = CONDITION_VARIABLE;
typedef CONDITION_VARIABLE = RTL_CONDITION_VARIABLE;
typedef RTL_CONDITION_VARIABLE = _RTL_CONDITION_VARIABLE;

@ffi.Array.multi([40])
external ffi.Array<ffi.Char> __opaque;
final class _RTL_CONDITION_VARIABLE extends ffi.Struct {
external PVOID Ptr;
}

typedef PVOID = ffi.Pointer<ffi.Void>;
typedef Dart_FinalizableHandle = ffi.Pointer<_Dart_FinalizableHandle>;

final class _Dart_FinalizableHandle extends ffi.Opaque {}
Expand Down
9 changes: 5 additions & 4 deletions pkgs/jni/src/dartjni.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,18 +683,19 @@ FFI_PLUGIN_EXPORT intptr_t InitDartApiDL(void* data) {
jclass _c_DartException = NULL;

jmethodID _m_DartException__ctor = NULL;
FFI_PLUGIN_EXPORT JniResult DartException__ctor(jstring message) {
FFI_PLUGIN_EXPORT JniResult DartException__ctor(jstring message,
jthrowable cause) {
attach_thread();
load_class_global_ref(&_c_DartException,
"com/github/dart_lang/jni/PortProxy$DartException");
if (_c_DartException == NULL)
return (JniResult){.value = {.j = 0}, .exception = check_exception()};
load_method(_c_DartException, &_m_DartException__ctor, "<init>",
"(Ljava/lang/String;)V");
"(Ljava/lang/String;Ljava/lang/Throwable;)V");
if (_m_DartException__ctor == NULL)
return (JniResult){.value = {.j = 0}, .exception = check_exception()};
jobject _result = (*jniEnv)->NewObject(jniEnv, _c_DartException,
_m_DartException__ctor, message);
jobject _result = (*jniEnv)->NewObject(
jniEnv, _c_DartException, _m_DartException__ctor, message, cause);
jthrowable exception = check_exception();
if (exception == NULL) {
_result = to_global_ref(_result);
Expand Down
2 changes: 1 addition & 1 deletion pkgs/jni/src/dartjni.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ static inline JniResult to_global_ref_result(jobject ref) {
FFI_PLUGIN_EXPORT intptr_t InitDartApiDL(void* data);

FFI_PLUGIN_EXPORT
JniResult DartException__ctor(jstring message);
JniResult DartException__ctor(jstring message, jthrowable cause);

FFI_PLUGIN_EXPORT
JniResult PortContinuation__ctor(int64_t j);
Expand Down
3 changes: 2 additions & 1 deletion pkgs/jnigen/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

- Fixed a bug where wrong argument types were generated for varargs.
- Fixed the macOS arm64 varargs issue caused by the previous release.

- Support throwing Java exceptions from Dart code.
([#1209](https://github.com/dart-lang/native/issues/1209))

## 0.9.2

Expand Down
2 changes: 1 addition & 1 deletion pkgs/jnigen/lib/src/bindings/dart_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ class $name$typeParamsDef extends $superName {
}
s.write('''
} catch (e) {
return $_protectedExtension.newDartException(e.toString());
return $_protectedExtension.newDartException(e);
}
return jni.nullptr;
}
Expand Down
Loading