[vm] Class modifiers for NativeFieldWrapper subtypes

Split off https://dart-review.googlesource.com/c/sdk/+/291761.
Landing separately, so that the breaking change itself is a smaller
CL.

TEST=ci build (see touched _test files)

bug: https://github.com/dart-lang/sdk/issues/51896
Change-Id: Ic8d218845ccb6a277689e911b2c34c44639e13cf
Cq-Include-Trybots: luci.dart.try:flutter-linux-try,vm-aot-linux-debug-x64c-try,vm-ffi-android-debug-arm-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292000
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
Daco Harkes 2023-03-31 13:20:19 +00:00 committed by Commit Queue
parent 452dcdf517
commit 3de5d25429
20 changed files with 48 additions and 41 deletions

View file

@ -50,14 +50,14 @@ doThings() {
await assertErrorsInCode(r''' await assertErrorsInCode(r'''
import 'dart:ffi'; import 'dart:ffi';
class NativeFieldWrapperClass1 {} base class NativeFieldWrapperClass1 {}
class A extends NativeFieldWrapperClass1 { base class A extends NativeFieldWrapperClass1 {
@FfiNative<Handle Function(Pointer<Void>)>('foo', isLeaf:true) @FfiNative<Handle Function(Pointer<Void>)>('foo', isLeaf:true)
external Object get foo; external Object get foo;
} }
''', [ ''', [
error(FfiCode.LEAF_CALL_MUST_NOT_RETURN_HANDLE, 100, 89), error(FfiCode.LEAF_CALL_MUST_NOT_RETURN_HANDLE, 110, 89),
]); ]);
} }

View file

@ -21,9 +21,9 @@ class FfiNativeTest extends PubPackageResolutionTest {
await assertErrorsInCode(r''' await assertErrorsInCode(r'''
import 'dart:ffi'; import 'dart:ffi';
class NativeFieldWrapperClass1 {} base class NativeFieldWrapperClass1 {}
class Paragraph extends NativeFieldWrapperClass1 { base class Paragraph extends NativeFieldWrapperClass1 {
@FfiNative<Double Function(Pointer<Void>)>('Paragraph::ideographicBaseline', isLeaf: true) @FfiNative<Double Function(Pointer<Void>)>('Paragraph::ideographicBaseline', isLeaf: true)
external double get ideographicBaseline; external double get ideographicBaseline;
@ -190,9 +190,9 @@ class NativeTest extends PubPackageResolutionTest {
await assertNoErrorsInCode(r''' await assertNoErrorsInCode(r'''
import 'dart:ffi'; import 'dart:ffi';
class NativeFieldWrapperClass1 {} base class NativeFieldWrapperClass1 {}
class Paragraph extends NativeFieldWrapperClass1 { base class Paragraph extends NativeFieldWrapperClass1 {
@Native<Double Function(Pointer<Void>)>(isLeaf: true) @Native<Double Function(Pointer<Void>)>(isLeaf: true)
external double get ideographicBaseline; external double get ideographicBaseline;

View file

@ -26,7 +26,7 @@ import 'dart:typed_data';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
class ClassWithNativeFields extends NativeFieldWrapperClass1 { base class ClassWithNativeFields extends NativeFieldWrapperClass1 {
void m() {} void m() {}
} }

View file

@ -20,7 +20,7 @@ class Bar {
Foo foo = Foo(); Foo foo = Foo();
} }
class NativeClass extends NativeFieldWrapperClass1 {} base class NativeClass extends NativeFieldWrapperClass1 {}
class Baz { class Baz {
@pragma('vm:entry-point') // prevent tree-shaking of the field. @pragma('vm:entry-point') // prevent tree-shaking of the field.

View file

@ -26,7 +26,7 @@ spawnWorker(worker, data) async {
return await completer.future; return await completer.future;
} }
class NativeWrapperClass extends NativeFieldWrapperClass1 {} base class NativeWrapperClass extends NativeFieldWrapperClass1 {}
verifyCantSendNative() async { verifyCantSendNative() async {
final receivePort = ReceivePort(); final receivePort = ReceivePort();

View file

@ -168,7 +168,7 @@ BENCHMARK(UseDartApi) {
const char* kScriptChars = R"( const char* kScriptChars = R"(
import 'dart:nativewrappers'; import 'dart:nativewrappers';
class Class extends NativeFieldWrapperClass1 { base class Class extends NativeFieldWrapperClass1 {
@pragma("vm:external-name", "init") @pragma("vm:external-name", "init")
external void init(); external void init();
@pragma("vm:external-name", "method") @pragma("vm:external-name", "method")

View file

@ -4601,7 +4601,7 @@ void FUNCTION_NAME(ExampleResource_Dispose)(Dart_NativeArguments native_args) {
TEST_CASE(DartAPI_WeakPersistentHandleUpdateSize) { TEST_CASE(DartAPI_WeakPersistentHandleUpdateSize) {
const char* kScriptChars = R"( const char* kScriptChars = R"(
import "dart:nativewrappers"; import "dart:nativewrappers";
class ExampleResource extends NativeFieldWrapperClass1 { base class ExampleResource extends NativeFieldWrapperClass1 {
ExampleResource() { _allocate(); } ExampleResource() { _allocate(); }
@pragma("vm:external-name", "ExampleResource_Allocate") @pragma("vm:external-name", "ExampleResource_Allocate")
external void _allocate(); external void _allocate();
@ -4660,7 +4660,7 @@ TEST_CASE(DartAPI_NativeFieldAccess) {
const char* kScriptChars = R"( const char* kScriptChars = R"(
import 'dart:ffi'; import 'dart:ffi';
import 'dart:nativewrappers'; import 'dart:nativewrappers';
class SecretKeeper extends NativeFieldWrapperClass1 { base class SecretKeeper extends NativeFieldWrapperClass1 {
SecretKeeper(int secret) { _keepSecret(secret); } SecretKeeper(int secret) { _keepSecret(secret); }
@pragma("vm:external-name", "SecretKeeper_KeepSecret") @pragma("vm:external-name", "SecretKeeper_KeepSecret")
external void _keepSecret(int secret); external void _keepSecret(int secret);
@ -4694,7 +4694,7 @@ TEST_CASE(DartAPI_NativeFieldAccess_Throws) {
const char* kScriptChars = R"( const char* kScriptChars = R"(
import 'dart:ffi'; import 'dart:ffi';
import 'dart:nativewrappers'; import 'dart:nativewrappers';
class ForgetfulSecretKeeper extends NativeFieldWrapperClass1 { base class ForgetfulSecretKeeper extends NativeFieldWrapperClass1 {
ForgetfulSecretKeeper(int secret) { /* Forget to init. native field. */ } ForgetfulSecretKeeper(int secret) { /* Forget to init. native field. */ }
} }
// Argument auto-conversion will wrap `o` in `_getNativeField()`. // Argument auto-conversion will wrap `o` in `_getNativeField()`.
@ -5699,7 +5699,8 @@ TEST_CASE(DartAPI_InjectNativeFields3) {
auto kScriptChars = Utils::CStringUniquePtr( auto kScriptChars = Utils::CStringUniquePtr(
OS::SCreate(nullptr, OS::SCreate(nullptr,
"import 'dart:nativewrappers';" "import 'dart:nativewrappers';"
"class NativeFields extends NativeFieldWrapperClass2 {\n" "final class NativeFields "
"extends NativeFieldWrapperClass2 {\n"
" NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
" int fld1;\n" " int fld1;\n"
" final int fld2;\n" " final int fld2;\n"
@ -5843,7 +5844,7 @@ TEST_CASE(DartAPI_TestNativeFieldsAccess) {
OS::SCreate( OS::SCreate(
nullptr, R"( nullptr, R"(
import 'dart:nativewrappers'; import 'dart:nativewrappers';
class NativeFields extends NativeFieldWrapperClass2 { base class NativeFields extends NativeFieldWrapperClass2 {
NativeFields(int i, int j) : fld1 = i, fld2 = j {} NativeFields(int i, int j) : fld1 = i, fld2 = j {}
int fld1; int fld1;
final int fld2; final int fld2;
@ -5883,11 +5884,11 @@ TEST_CASE(DartAPI_TestNativeFieldsAccess) {
TEST_CASE(DartAPI_InjectNativeFieldsSuperClass) { TEST_CASE(DartAPI_InjectNativeFieldsSuperClass) {
const char* kScriptChars = const char* kScriptChars =
"import 'dart:nativewrappers';" "import 'dart:nativewrappers';"
"class NativeFieldsSuper extends NativeFieldWrapperClass1 {\n" "base class NativeFieldsSuper extends NativeFieldWrapperClass1 {\n"
" NativeFieldsSuper() : fld1 = 42 {}\n" " NativeFieldsSuper() : fld1 = 42 {}\n"
" int fld1;\n" " int fld1;\n"
"}\n" "}\n"
"class NativeFields extends NativeFieldsSuper {\n" "base class NativeFields extends NativeFieldsSuper {\n"
" fld() => fld1;\n" " fld() => fld1;\n"
"}\n" "}\n"
"int testMain() {\n" "int testMain() {\n"
@ -5990,7 +5991,8 @@ TEST_CASE(DartAPI_ImplicitNativeFieldAccess) {
auto kScriptChars = Utils::CStringUniquePtr( auto kScriptChars = Utils::CStringUniquePtr(
OS::SCreate(nullptr, OS::SCreate(nullptr,
"import 'dart:nativewrappers';" "import 'dart:nativewrappers';"
"class NativeFields extends NativeFieldWrapperClass4 {\n" "final class NativeFields extends "
"NativeFieldWrapperClass4 {\n"
" NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
" int%s fld0;\n" " int%s fld0;\n"
" int fld1;\n" " int fld1;\n"
@ -7424,7 +7426,7 @@ static Dart_NativeFunction native_args_lookup(Dart_Handle name,
TEST_CASE(DartAPI_GetNativeArguments) { TEST_CASE(DartAPI_GetNativeArguments) {
const char* kScriptChars = R"( const char* kScriptChars = R"(
import 'dart:nativewrappers'; import 'dart:nativewrappers';
class MyObject extends NativeFieldWrapperClass2 { base class MyObject extends NativeFieldWrapperClass2 {
@pragma("vm:external-name", "NativeArgument_Create") @pragma("vm:external-name", "NativeArgument_Create")
external static MyObject createObject(); external static MyObject createObject();
@pragma("vm:external-name", "NativeArgument_Access") @pragma("vm:external-name", "NativeArgument_Access")

View file

@ -49,7 +49,7 @@ class _AsyncDirectoryListerOps {
new _AsyncDirectoryListerOpsImpl(pointer); new _AsyncDirectoryListerOpsImpl(pointer);
} }
class _AsyncDirectoryListerOpsImpl extends NativeFieldWrapperClass1 base class _AsyncDirectoryListerOpsImpl extends NativeFieldWrapperClass1
implements _AsyncDirectoryListerOps { implements _AsyncDirectoryListerOps {
_AsyncDirectoryListerOpsImpl._(); _AsyncDirectoryListerOpsImpl._();

View file

@ -74,7 +74,7 @@ class _RandomAccessFileOps {
} }
@pragma("vm:entry-point") @pragma("vm:entry-point")
class _RandomAccessFileOpsImpl extends NativeFieldWrapperClass1 base class _RandomAccessFileOpsImpl extends NativeFieldWrapperClass1
implements _RandomAccessFileOps { implements _RandomAccessFileOps {
_RandomAccessFileOpsImpl._(); _RandomAccessFileOpsImpl._();

View file

@ -4,7 +4,8 @@
part of "common_patch.dart"; part of "common_patch.dart";
class _FilterImpl extends NativeFieldWrapperClass1 implements RawZLibFilter { base class _FilterImpl extends NativeFieldWrapperClass1
implements RawZLibFilter {
@pragma("vm:external-name", "Filter_Process") @pragma("vm:external-name", "Filter_Process")
external void process(List<int> data, int start, int end); external void process(List<int> data, int start, int end);
@ -12,7 +13,7 @@ class _FilterImpl extends NativeFieldWrapperClass1 implements RawZLibFilter {
external List<int>? processed({bool flush = true, bool end = false}); external List<int>? processed({bool flush = true, bool end = false});
} }
class _ZLibInflateFilter extends _FilterImpl { base class _ZLibInflateFilter extends _FilterImpl {
_ZLibInflateFilter(int windowBits, List<int>? dictionary, bool raw) { _ZLibInflateFilter(int windowBits, List<int>? dictionary, bool raw) {
_init(windowBits, dictionary, raw); _init(windowBits, dictionary, raw);
} }
@ -20,7 +21,7 @@ class _ZLibInflateFilter extends _FilterImpl {
external void _init(int windowBits, List<int>? dictionary, bool raw); external void _init(int windowBits, List<int>? dictionary, bool raw);
} }
class _ZLibDeflateFilter extends _FilterImpl { base class _ZLibDeflateFilter extends _FilterImpl {
_ZLibDeflateFilter(bool gzip, int level, int windowBits, int memLevel, _ZLibDeflateFilter(bool gzip, int level, int windowBits, int memLevel,
int strategy, List<int>? dictionary, bool raw) { int strategy, List<int>? dictionary, bool raw) {
_init(gzip, level, windowBits, memLevel, strategy, dictionary, raw); _init(gzip, level, windowBits, memLevel, strategy, dictionary, raw);

View file

@ -5,7 +5,8 @@
part of 'common_patch.dart'; part of 'common_patch.dart';
@pragma("vm:entry-point") @pragma("vm:entry-point")
class _NamespaceImpl extends NativeFieldWrapperClass1 implements _Namespace { base class _NamespaceImpl extends NativeFieldWrapperClass1
implements _Namespace {
_NamespaceImpl._(); _NamespaceImpl._();
@pragma("vm:external-name", "Namespace_Create") @pragma("vm:external-name", "Namespace_Create")

View file

@ -213,9 +213,9 @@ class _ProcessStartStatus {
// The NativeFieldWrapperClass1 can not be used with a mixin, due to missing // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing
// implicit constructor. // implicit constructor.
class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {} base class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {}
class _ProcessImpl extends _ProcessImplNativeWrapper implements _Process { base class _ProcessImpl extends _ProcessImplNativeWrapper implements _Process {
static bool connectedResourceHandler = false; static bool connectedResourceHandler = false;
_ProcessImpl( _ProcessImpl(

View file

@ -60,7 +60,7 @@ class _SecureSocket extends _Socket implements SecureSocket {
* native code can access the same data. * native code can access the same data.
*/ */
@pragma("vm:entry-point") @pragma("vm:entry-point")
class _SecureFilterImpl extends NativeFieldWrapperClass1 base class _SecureFilterImpl extends NativeFieldWrapperClass1
implements _SecureFilter { implements _SecureFilter {
// Performance is improved if a full buffer of plaintext fits // Performance is improved if a full buffer of plaintext fits
// in the encrypted buffer, when encrypted. // in the encrypted buffer, when encrypted.
@ -208,7 +208,7 @@ class SecurityContext {
static bool get alpnSupported => true; static bool get alpnSupported => true;
} }
class _SecurityContext extends NativeFieldWrapperClass1 base class _SecurityContext extends NativeFieldWrapperClass1
implements SecurityContext { implements SecurityContext {
bool _allowLegacyUnsafeRenegotiation = false; bool _allowLegacyUnsafeRenegotiation = false;
@ -284,7 +284,7 @@ class _SecurityContext extends NativeFieldWrapperClass1
* _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL * _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL
* library. It exposes the fields of the certificate object. * library. It exposes the fields of the certificate object.
*/ */
class _X509CertificateImpl extends NativeFieldWrapperClass1 base class _X509CertificateImpl extends NativeFieldWrapperClass1
implements X509Certificate { implements X509Certificate {
// The native field must be set manually on a new object, in native code. // The native field must be set manually on a new object, in native code.
// This is done by WrappedX509Certificate in security_context.cc. // This is done by WrappedX509Certificate in security_context.cc.

View file

@ -370,14 +370,15 @@ class _NetworkInterface implements NetworkInterface {
// The NativeFieldWrapperClass1 cannot be used with a mixin, due to missing // The NativeFieldWrapperClass1 cannot be used with a mixin, due to missing
// implicit constructor. // implicit constructor.
class _NativeSocketNativeWrapper extends NativeFieldWrapperClass1 {} base class _NativeSocketNativeWrapper extends NativeFieldWrapperClass1 {}
/// Returns error code that corresponds to EINPROGRESS OS error. /// Returns error code that corresponds to EINPROGRESS OS error.
@pragma("vm:external-name", "OSError_inProgressErrorCode") @pragma("vm:external-name", "OSError_inProgressErrorCode")
external int get _inProgressErrorCode; external int get _inProgressErrorCode;
// The _NativeSocket class encapsulates an OS socket. // The _NativeSocket class encapsulates an OS socket.
class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { base class _NativeSocket extends _NativeSocketNativeWrapper
with _ServiceObject {
// Bit flags used when communicating between the eventhandler and // Bit flags used when communicating between the eventhandler and
// dart code. The EVENT flags are used to indicate events of // dart code. The EVENT flags are used to indicate events of
// interest when sending a message from dart code to the // interest when sending a message from dart code to the

View file

@ -45,10 +45,12 @@ class _RawSynchronousSocket implements RawSynchronousSocket {
// The NativeFieldWrapperClass1 can not be used with a mixin, due to missing // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing
// implicit constructor. // implicit constructor.
class _NativeSynchronousSocketNativeWrapper extends NativeFieldWrapperClass1 {} base class _NativeSynchronousSocketNativeWrapper
extends NativeFieldWrapperClass1 {}
// The _NativeSynchronousSocket class encapsulates a synchronous OS socket. // The _NativeSynchronousSocket class encapsulates a synchronous OS socket.
class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { base class _NativeSynchronousSocket
extends _NativeSynchronousSocketNativeWrapper {
// Socket close state. // Socket close state.
bool isClosed = false; bool isClosed = false;
bool isClosedRead = false; bool isClosedRead = false;

View file

@ -16,7 +16,7 @@ class Classy {
external void goodHasReceiverHandle(int v); external void goodHasReceiverHandle(int v);
} }
class NativeClassy extends NativeFieldWrapperClass1 { base class NativeClassy extends NativeFieldWrapperClass1 {
@FfiNative<IntPtr Function(IntPtr)>('ReturnIntPtr') @FfiNative<IntPtr Function(IntPtr)>('ReturnIntPtr')
external static int returnIntPtrStatic(int x); external static int returnIntPtrStatic(int x);

View file

@ -48,7 +48,7 @@ class Classy {
// For automatic transform of NativeFieldWrapperClass1 to Pointer. // For automatic transform of NativeFieldWrapperClass1 to Pointer.
class ClassWithNativeField extends NativeFieldWrapperClass1 { base class ClassWithNativeField extends NativeFieldWrapperClass1 {
ClassWithNativeField(int value) { ClassWithNativeField(int value) {
setNativeInstanceField(this, 0, value); setNativeInstanceField(this, 0, value);
} }
@ -105,7 +105,7 @@ int setState(int value) {
return 0; return 0;
} }
class StateSetter extends NativeFieldWrapperClass1 { base class StateSetter extends NativeFieldWrapperClass1 {
StateSetter(int value) { StateSetter(int value) {
setNativeInstanceField(this, 0, 0); setNativeInstanceField(this, 0, 0);
state = value; state = value;

View file

@ -33,7 +33,7 @@ class Classy {
external void badHasReceiverPointer(int v); //# 04: compile-time error external void badHasReceiverPointer(int v); //# 04: compile-time error
} }
class NativeClassy extends NativeFieldWrapperClass1 { base class NativeClassy extends NativeFieldWrapperClass1 {
// Error: Missing receiver in FfiNative annotation. // Error: Missing receiver in FfiNative annotation.
@FfiNative<Void Function(IntPtr)>('doesntmatter') //# 05: compile-time error @FfiNative<Void Function(IntPtr)>('doesntmatter') //# 05: compile-time error
external void badMissingReceiver(int v); //# 05: compile-time error external void badMissingReceiver(int v); //# 05: compile-time error

View file

@ -13,7 +13,7 @@ echo(msg) {
reply.send('echoing ${data(1)}}'); reply.send('echoing ${data(1)}}');
} }
class Test extends NativeFieldWrapperClass2 { base class Test extends NativeFieldWrapperClass2 {
Test(this.i, this.j); Test(this.i, this.j);
int i, j; int i, j;
} }

View file

@ -93,7 +93,7 @@ external int incrementSize(int a);
@Native<WChar Function(WChar)>() @Native<WChar Function(WChar)>()
external int incrementWchar(int a); external int incrementWchar(int a);
final class MyStruct extends Struct implements NativeFieldWrapperClass1 { final class MyStruct extends Struct {
@Double() @Double()
external double x; external double x;