Skip to content

Commit 14d0c0e

Browse files
dcharkesCommit Queue
authored and
Commit Queue
committed
[cfe/ffi] Test _nativeEffect for @Natives
In a follow up, we will remove the transform from `@Native` to `_asFunctionInternal`. However, we need to ensure that we keep emitting `_nativeEffect` for struct return values classes if `@Native`s are the only place instances are created. The follow up CL will change the expect files. TEST=pkg/vm/test/transformations/ffi_test Bug: #47625 Change-Id: I1685683f48f1d16d6d10606f541f13e17d8583fe Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332800 Reviewed-by: Alexander Markov <[email protected]> Commit-Queue: Alexander Markov <[email protected]> Commit-Queue: Daco Harkes <[email protected]> Auto-Submit: Daco Harkes <[email protected]>
1 parent ea32a6a commit 14d0c0e

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// The Struct1ByteInt code should not be shaken out if the only place instances
6+
// of this class are created is FFI call return values.
7+
8+
import 'dart:ffi';
9+
10+
void main() {
11+
final result = returnStruct1ByteIntNative(-1);
12+
print("result = $result");
13+
}
14+
15+
// ignore: sdk_version_since
16+
@Native<Struct1ByteInt Function(Int8)>(symbol: 'ReturnStruct1ByteInt')
17+
external Struct1ByteInt returnStruct1ByteIntNative(int a0);
18+
19+
final class Struct1ByteInt extends Struct {
20+
@Int8()
21+
external int a0;
22+
23+
String toString() => "(${a0})";
24+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
library #lib;
2+
import self as self;
3+
import "dart:core" as core;
4+
import "dart:ffi" as ffi;
5+
import "dart:_internal" as _in;
6+
import "dart:typed_data" as typ;
7+
8+
import "dart:ffi";
9+
10+
@#C6
11+
final class Struct1ByteInt extends ffi::Struct {
12+
constructor #fromTypedDataBase([@vm.inferred-arg-type.metadata=dart.typed_data::_Uint8List] synthesized core::Object #typedDataBase) → self::Struct1ByteInt
13+
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
14+
;
15+
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] [@vm.unboxing-info.metadata=()->i] get a0() → core::int
16+
return [@vm.inferred-type.metadata=int] ffi::_loadInt8([@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] [@vm.inferred-type.metadata=dart.typed_data::_Uint8List] this.{ffi::_Compound::_typedDataBase}{core::Object}, #C8.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
17+
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3] method toString() → core::String
18+
return "(${[@vm.direct-call.metadata=#lib::Struct1ByteInt.a0] this.{self::Struct1ByteInt::a0}{core::int}})";
19+
}
20+
[@vm.inferred-type.metadata=dart.core::_Closure]static final field (core::int) → self::Struct1ByteInt _returnStruct1ByteIntNative$Method$FfiNative$Ptr = block {
21+
_in::_nativeEffect(new self::Struct1ByteInt::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C9)));
22+
} =>[@vm.inferred-type.metadata=dart.core::_Closure] ffi::_asFunctionInternal<(core::int) → self::Struct1ByteInt, (ffi::Int8) → self::Struct1ByteInt>([@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::_fromAddress<ffi::NativeFunction<(ffi::Int8) → self::Struct1ByteInt>*>(ffi::_ffi_resolver(#C10, #C11, #C9){(core::Object, core::Object, core::int) → core::int}), false)/*isLegacy*/;
23+
static method main() → void {
24+
final self::Struct1ByteInt result = self::returnStruct1ByteIntNative([@vm.direct-call.metadata=dart.core::_IntegerImplementation.unary-] [@vm.inferred-type.metadata=int (skip check)] 1.{core::int::unary-}(){() → core::int});
25+
core::print("result = ${result}");
26+
}
27+
[@vm.unboxing-info.metadata=(i)->b]static method returnStruct1ByteIntNative([@vm.inferred-arg-type.metadata=int] core::int a0) → self::Struct1ByteInt
28+
return self::_returnStruct1ByteIntNative$Method$FfiNative$Ptr(a0){(core::int) → self::Struct1ByteInt};
29+
constants {
30+
#C1 = "vm:ffi:struct-fields"
31+
#C2 = TypeLiteralConstant(ffi::Int8)
32+
#C3 = <core::Type>[#C2]
33+
#C4 = null
34+
#C5 = ffi::_FfiStructLayout {fieldTypes:#C3, packing:#C4}
35+
#C6 = core::pragma {name:#C1, options:#C5}
36+
#C7 = 0
37+
#C8 = <core::int*>[#C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7, #C7]
38+
#C9 = 1
39+
#C10 = "#lib"
40+
#C11 = "ReturnStruct1ByteInt"
41+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
library #lib;
2+
import self as self;
3+
import "dart:core" as core;
4+
import "dart:ffi" as ffi;
5+
import "dart:_internal" as _in;
6+
import "dart:typed_data" as typ;
7+
8+
import "dart:ffi";
9+
10+
@#C6
11+
final class Struct1ByteInt extends ffi::Struct {
12+
synthetic constructor •() → self::Struct1ByteInt
13+
: super ffi::Struct::•()
14+
;
15+
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase) → self::Struct1ByteInt
16+
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
17+
;
18+
@#C7
19+
get a0() → core::int
20+
return ffi::_loadInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C9.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
21+
@#C7
22+
set a0(core::int #externalFieldValue) → void
23+
return ffi::_storeInt8(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C9.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue);
24+
method toString() → core::String
25+
return "(${this.{self::Struct1ByteInt::a0}{core::int}})";
26+
@#C11
27+
static get #sizeOf() → core::int*
28+
return #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*};
29+
}
30+
static final field (core::int) → self::Struct1ByteInt _returnStruct1ByteIntNative$Method$FfiNative$Ptr = block {
31+
_in::_nativeEffect(new self::Struct1ByteInt::#fromTypedDataBase(typ::Uint8List::•(#C12)));
32+
} =>ffi::_asFunctionInternal<(core::int) → self::Struct1ByteInt, (ffi::Int8) → self::Struct1ByteInt>(ffi::_fromAddress<ffi::NativeFunction<(ffi::Int8) → self::Struct1ByteInt>*>(ffi::_ffi_resolver(#C14, #C15, #C12){(core::Object, core::Object, core::int) → core::int}), false)/*isLegacy*/;
33+
static method main() → void {
34+
final self::Struct1ByteInt result = self::returnStruct1ByteIntNative(1.{core::int::unary-}(){() → core::int});
35+
core::print("result = ${result}");
36+
}
37+
static method returnStruct1ByteIntNative(core::int a0) → self::Struct1ByteInt
38+
return self::_returnStruct1ByteIntNative$Method$FfiNative$Ptr(a0){(core::int) → self::Struct1ByteInt};
39+
constants {
40+
#C1 = "vm:ffi:struct-fields"
41+
#C2 = TypeLiteralConstant(ffi::Int8)
42+
#C3 = <core::Type>[#C2]
43+
#C4 = null
44+
#C5 = ffi::_FfiStructLayout {fieldTypes:#C3, packing:#C4}
45+
#C6 = core::pragma {name:#C1, options:#C5}
46+
#C7 = ffi::Int8 {}
47+
#C8 = 0
48+
#C9 = <core::int*>[#C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8, #C8]
49+
#C10 = "vm:prefer-inline"
50+
#C11 = core::pragma {name:#C10, options:#C4}
51+
#C12 = 1
52+
#C13 = <core::int*>[#C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12, #C12]
53+
#C14 = "#lib"
54+
#C15 = "ReturnStruct1ByteInt"
55+
}

0 commit comments

Comments
 (0)