From bf4aad5ac2709dc73a0564f40d1a77612968d8a8 Mon Sep 17 00:00:00 2001 From: Eric Prokop Date: Sun, 4 Jul 2021 22:49:29 +0200 Subject: [PATCH] Fixed errors related to unexpected `runtimeType` names due to minifying in release builds --- CHANGELOG.md | 3 + example/example_flutter/assets/index.html | 13 --- lib/src/ffi/types.dart | 16 +-- lib/src/internal/marshaller.dart | 114 ++++++++-------------- lib/src/internal/type_utils.dart | 62 ++++++++++++ pubspec.yaml | 2 +- test/type_utils_test.dart | 9 ++ 7 files changed, 120 insertions(+), 99 deletions(-) delete mode 100644 example/example_flutter/assets/index.html create mode 100644 lib/src/internal/type_utils.dart create mode 100644 test/type_utils_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 73103c8..ac377aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [0.7.2] +* Fixed errors related to unexpected `runtimeType` names due to minifying in release builds + ## [0.7.1] * Fixing dead links diff --git a/example/example_flutter/assets/index.html b/example/example_flutter/assets/index.html deleted file mode 100644 index 77867f5..0000000 --- a/example/example_flutter/assets/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - web_ffi Test Page - - - - - - diff --git a/lib/src/ffi/types.dart b/lib/src/ffi/types.dart index bc4f896..6429725 100644 --- a/lib/src/ffi/types.dart +++ b/lib/src/ffi/types.dart @@ -5,6 +5,8 @@ import '../modules/module.dart'; import '../modules/memory.dart'; import '../modules/null_memory.dart'; +import '../internal/type_utils.dart'; + import '../../web_ffi_meta.dart'; /// Represents a pointer into the native C memory corresponding to "NULL", @@ -23,7 +25,7 @@ final Pointer nullptr = new Pointer._null(); /// before [Memory.init()] was called or else an exception will be thrown. int sizeOf() { int? size; - if (_isPointerType()) { + if (isPointerType()) { size = sizeMap[IntPtr]; } else { size = sizeMap[T]; @@ -35,16 +37,8 @@ int sizeOf() { } } -bool _isPointerType() => - T.toString().startsWith('Pointer<'); - -bool _isNativeFunctionType() => - T.toString().startsWith('NativeFunction<'); - -bool _isVoidType() => T.toString() == 'Void'; - bool _isUnsizedType() { - return _isNativeFunctionType() || _isVoidType(); + return isNativeFunctionType() || isVoidType(); } /// [NativeType]'s subtypes represent a native type in C. @@ -307,7 +301,7 @@ class DynamicLibrary { /// the return type and parameters of `T` match the wasm function. Pointer lookup(String name) { WasmSymbol symbol = symbolByName(boundMemory, name); - if (_isNativeFunctionType()) { + if (isNativeFunctionType()) { if (symbol is FunctionDescription) { return new Pointer.fromAddress(symbol.tableIndex, boundMemory); } else { diff --git a/lib/src/internal/marshaller.dart b/lib/src/internal/marshaller.dart index 7d262df..3697eec 100644 --- a/lib/src/internal/marshaller.dart +++ b/lib/src/internal/marshaller.dart @@ -4,10 +4,11 @@ import '../ffi/types.dart'; import '../modules/exceptions.dart'; import '../modules/memory.dart'; import 'invoker_generated.dart'; +import 'type_utils.dart'; // Called from the invokers T execute(Function base, List args, Memory memory) { - if (T == _void) { + if (T == DartVoidType) { Function.apply(base, args.map(_toJsType).toList()); return null as T; } else { @@ -34,7 +35,7 @@ Object _toJsType(Object dartObject) { InvokeHelper _inferFromSignature(String signature) { String returnType = signature.split('=>').last.trim(); - if (returnType.startsWith('Pointer> but not Pointer>>, ...'); @@ -43,7 +44,7 @@ InvokeHelper _inferFromSignature(String signature) { if (h != null) { return h; } else { - if (returnType.startsWith('Pointer> is allowed!'); @@ -59,25 +60,22 @@ List listKnownTypes() => new List.of(_knownTypes.keys, growable: false); final Map _knownTypes = { - _typeString(): new InvokeHelper(null, null), - _typeString(): new InvokeHelper(null, null), - _typeString(): new InvokeHelper(null, null), - _typeString(): new InvokeHelper(null, null) + typeString(): new InvokeHelper(null, null), + typeString(): new InvokeHelper(null, null), + typeString(): new InvokeHelper(null, null), + typeString(): new InvokeHelper(null, null) }; -String _typeString() => T.toString(); - void registerNativeMarshallerType() { - String t = _typeString(); - _knownTypes['Pointer<$t>'] = new InvokeHelper>(null, null); - _knownTypes['Pointer>'] = + _knownTypes[typeString>()] = + new InvokeHelper>(null, null); + _knownTypes[typeString>>()] = new InvokeHelper>>(null, null); } void registerNativeMarshallerOpaque() { - String t = _typeString(); - _knownTypes['Pointer<$t>'] = new OpaqueInvokeHelper(null, null); - _knownTypes['Pointer>'] = + _knownTypes[typeString>()] = new OpaqueInvokeHelper(null, null); + _knownTypes[typeString>>()] = new OpaqueInvokeHelperSquare(null, null); } @@ -101,164 +99,164 @@ T _toDartType(Object o, Memory bind) { throw new MarshallingException.typeMissmatch(T, o); } } else { - if (T == _Pointer_Void) { + if (T == Pointer_Void) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_IntPtr) { + } else if (T == Pointer_IntPtr) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Int8) { + } else if (T == Pointer_Int8) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Int16) { + } else if (T == Pointer_Int16) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Int32) { + } else if (T == Pointer_Int32) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Int64) { + } else if (T == Pointer_Int64) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Double) { + } else if (T == Pointer_Double) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Uint8) { + } else if (T == Pointer_Uint8) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Uint16) { + } else if (T == Pointer_Uint16) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Uint32) { + } else if (T == Pointer_Uint32) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Uint64) { + } else if (T == Pointer_Uint64) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Float) { + } else if (T == Pointer_Float) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Opaque) { + } else if (T == Pointer_Opaque) { if (o is int) { return new Pointer.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_NativeFunction_dynamic) { + } else if (T == Pointer_NativeFunction_dynamic) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } } else { - if (T == _Pointer_Pointer_Void) { + if (T == Pointer_Pointer_Void) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_IntPtr) { + } else if (T == Pointer_Pointer_IntPtr) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Int8) { + } else if (T == Pointer_Pointer_Int8) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Int16) { + } else if (T == Pointer_Pointer_Int16) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Int32) { + } else if (T == Pointer_Pointer_Int32) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Int64) { + } else if (T == Pointer_Pointer_Int64) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Double) { + } else if (T == Pointer_Pointer_Double) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Uint8) { + } else if (T == Pointer_Pointer_Uint8) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Uint16) { + } else if (T == Pointer_Pointer_Uint16) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Uint32) { + } else if (T == Pointer_Pointer_Uint32) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Uint64) { + } else if (T == Pointer_Pointer_Uint64) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Float) { + } else if (T == Pointer_Pointer_Float) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { throw new MarshallingException.noAddress(o); } - } else if (T == _Pointer_Pointer_Opaque) { + } else if (T == Pointer_Pointer_Opaque) { if (o is int) { return new Pointer>.fromAddress(o, bind) as T; } else { @@ -271,35 +269,3 @@ T _toDartType(Object o, Memory bind) { } } } - -/// Hacky workadround, see https://github.com/dart-lang/language/issues/123 -Type _extractType() => T; -final Type _Pointer_IntPtr = _extractType>(); -final Type _Pointer_Void = _extractType>(); -final Type _Pointer_Int8 = _extractType>(); -final Type _Pointer_Int16 = _extractType>(); -final Type _Pointer_Int32 = _extractType>(); -final Type _Pointer_Int64 = _extractType>(); -final Type _Pointer_Double = _extractType>(); -final Type _Pointer_Uint8 = _extractType>(); -final Type _Pointer_Uint16 = _extractType>(); -final Type _Pointer_Uint32 = _extractType>(); -final Type _Pointer_Uint64 = _extractType>(); -final Type _Pointer_Float = _extractType>(); -final Type _Pointer_Opaque = _extractType>(); -final Type _Pointer_Pointer_IntPtr = _extractType>>(); -final Type _Pointer_Pointer_Void = _extractType>>(); -final Type _Pointer_Pointer_Int8 = _extractType>>(); -final Type _Pointer_Pointer_Int16 = _extractType>>(); -final Type _Pointer_Pointer_Int32 = _extractType>>(); -final Type _Pointer_Pointer_Int64 = _extractType>>(); -final Type _Pointer_Pointer_Double = _extractType>>(); -final Type _Pointer_Pointer_Uint8 = _extractType>>(); -final Type _Pointer_Pointer_Uint16 = _extractType>>(); -final Type _Pointer_Pointer_Uint32 = _extractType>>(); -final Type _Pointer_Pointer_Uint64 = _extractType>>(); -final Type _Pointer_Pointer_Float = _extractType>>(); -final Type _Pointer_Pointer_Opaque = _extractType>>(); -final Type _Pointer_NativeFunction_dynamic = - _extractType>>(); -final Type _void = _extractType(); diff --git a/lib/src/internal/type_utils.dart b/lib/src/internal/type_utils.dart new file mode 100644 index 0000000..7f42c6c --- /dev/null +++ b/lib/src/internal/type_utils.dart @@ -0,0 +1,62 @@ +import '../ffi/types.dart'; + +/// Hacky workadround, see https://github.com/dart-lang/language/issues/123 +Type _extractType() => T; +String typeString() => _extractType().toString(); + +// Variable names begin with a capital letter on purpose (opposing dart conventions) to hilight that +// they are treated like types (which are written with a captial letter in dart). +final Type Pointer_IntPtr = _extractType>(); +final Type Pointer_Void = _extractType>(); +final Type Pointer_Int8 = _extractType>(); +final Type Pointer_Int16 = _extractType>(); +final Type Pointer_Int32 = _extractType>(); +final Type Pointer_Int64 = _extractType>(); +final Type Pointer_Double = _extractType>(); +final Type Pointer_Uint8 = _extractType>(); +final Type Pointer_Uint16 = _extractType>(); +final Type Pointer_Uint32 = _extractType>(); +final Type Pointer_Uint64 = _extractType>(); +final Type Pointer_Float = _extractType>(); +final Type Pointer_Opaque = _extractType>(); +final Type Pointer_Pointer_IntPtr = _extractType>>(); +final Type Pointer_Pointer_Void = _extractType>>(); +final Type Pointer_Pointer_Int8 = _extractType>>(); +final Type Pointer_Pointer_Int16 = _extractType>>(); +final Type Pointer_Pointer_Int32 = _extractType>>(); +final Type Pointer_Pointer_Int64 = _extractType>>(); +final Type Pointer_Pointer_Double = _extractType>>(); +final Type Pointer_Pointer_Uint8 = _extractType>>(); +final Type Pointer_Pointer_Uint16 = _extractType>>(); +final Type Pointer_Pointer_Uint32 = _extractType>>(); +final Type Pointer_Pointer_Uint64 = _extractType>>(); +final Type Pointer_Pointer_Float = _extractType>>(); +final Type Pointer_Pointer_Opaque = _extractType>>(); +final Type Pointer_NativeFunction_dynamic = + _extractType>>(); +final Type DartVoidType = _extractType(); +final Type FfiVoidType = _extractType(); + +final String _dynamicTypeString = typeString(); + +final String pointerPointerPointerPrefix = + typeString>>>() + .split(_dynamicTypeString) + .first; + +final String pointerNativeFunctionPrefix = + typeString>>() + .split(_dynamicTypeString) + .first; + +final String _nativeFunctionPrefix = + typeString>().split(_dynamicTypeString).first; +bool isNativeFunctionType() => + typeString().startsWith(_nativeFunctionPrefix); + +final String _pointerPrefix = + typeString>().split(_dynamicTypeString).first; +bool isPointerType() => + typeString().startsWith(_pointerPrefix); + +bool isVoidType() => _extractType() == FfiVoidType; diff --git a/pubspec.yaml b/pubspec.yaml index 233c8af..d153d39 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: web_ffi -version: 0.7.1 +version: 0.7.2 repository: https://github.com/EPNW/web_ffi/ description: Translates dart:ffi calls on the web to WebAssembly using dart:js diff --git a/test/type_utils_test.dart b/test/type_utils_test.dart new file mode 100644 index 0000000..dd08ad3 --- /dev/null +++ b/test/type_utils_test.dart @@ -0,0 +1,9 @@ +import '../lib/src/internal/type_utils.dart'; +import '../lib/web_ffi.dart'; + +void main() { + print(pointerPointerPointerPrefix); + print(pointerNativeFunctionPrefix); + print(isVoidType()); + print(isVoidType()); +}