diff --git a/runtime/lib/ffi_native_type_patch.dart b/runtime/lib/ffi_native_type_patch.dart index 8378e07058da1..edc439509fd75 100644 --- a/runtime/lib/ffi_native_type_patch.dart +++ b/runtime/lib/ffi_native_type_patch.dart @@ -7,9 +7,12 @@ import "dart:_internal" show patch; import 'dart:typed_data' show TypedData; +// NativeType is not private, because it is used in type arguments. +// NativeType is abstract because it not used with const constructors in +// annotations directly, so it should never be instantiated at runtime. @patch @pragma("vm:entry-point") -class NativeType {} +abstract class NativeType {} @patch @pragma("vm:entry-point") diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc index b5362e880841c..22e9f07d3e223 100644 --- a/runtime/vm/compiler/runtime_api.cc +++ b/runtime/vm/compiler/runtime_api.cc @@ -330,6 +330,10 @@ static uword GetInstanceSizeImpl(const dart::Class& handle) { case kByteBufferCid: case kByteDataViewCid: case kFfiPointerCid: + case kFfiDynamicLibraryCid: +#define HANDLE_CASE(clazz) case kFfi##clazz##Cid: + CLASS_LIST_FFI_TYPE_MARKER(HANDLE_CASE) +#undef HANDLE_CASE #define HANDLE_CASE(clazz) \ case kTypedData##clazz##Cid: \ case kTypedData##clazz##ViewCid: \ diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc index 24a79f89a9a91..9e906cd8ef3b9 100644 --- a/runtime/vm/raw_object.cc +++ b/runtime/vm/raw_object.cc @@ -302,6 +302,13 @@ intptr_t RawObject::VisitPointersPredefined(ObjectPointerVisitor* visitor, size = RawDynamicLibrary::VisitDynamicLibraryPointers(raw_obj, visitor); break; } +#define RAW_VISITPOINTERS(clazz) case kFfi##clazz##Cid: + CLASS_LIST_FFI_TYPE_MARKER(RAW_VISITPOINTERS) { + // NativeType do not have any fields or type arguments. + size = HeapSize(); + break; + } +#undef RAW_VISITPOINTERS case kFreeListElement: { uword addr = RawObject::ToAddr(this); FreeListElement* element = reinterpret_cast(addr); diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart index 61f9cdeb29aef..bd88b282f3ac2 100644 --- a/sdk/lib/ffi/native_type.dart +++ b/sdk/lib/ffi/native_type.dart @@ -8,7 +8,7 @@ part of dart.ffi; /// /// [NativeType]'s subtypes are not constructible in the Dart code and serve /// purely as markers in type signatures. -class NativeType { +abstract class NativeType { const NativeType(); } diff --git a/tests/ffi/regress_37780_test.dart b/tests/ffi/regress_37780_test.dart new file mode 100644 index 0000000000000..a6b9f7e8e3076 --- /dev/null +++ b/tests/ffi/regress_37780_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// SharedObjects=ffi_test_functions + +import 'dart:ffi'; + +import 'dylib_utils.dart'; + +DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions"); + +final triggerGc = ffiTestFunctions + .lookupFunction("TriggerGC"); + +main(List args) { + final foo = [Float(), Double(), Uint8()]; + triggerGc(); + print(foo); +}