[cfe/ffi] Fix deeply nested structs in separate files

TEST=pkg/front_end/testcases/incremental/issue_46666.yaml

Closes: https://github.com/dart-lang/sdk/issues/46666

Change-Id: I56134394695f8b93096b03922336d499ccb1372a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207761
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
diff --git a/pkg/front_end/testcases/incremental/issue_46666.yaml b/pkg/front_end/testcases/incremental/issue_46666.yaml
new file mode 100644
index 0000000..0ac3970
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/issue_46666.yaml
@@ -0,0 +1,54 @@
+# Copyright (c) 2021, 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.md file.
+
+# Reproduces https://dartbug.com/46666.
+
+type: newworld
+worlds:
+  - entry: b.dart
+    experiments: non-nullable
+    sources:
+      a.dart: |
+        import 'dart:ffi';
+
+        class StructA extends Struct {
+          external Pointer<Void> a1;
+          external Pointer<Void> a2;
+          external Pointer<Void> a3;
+          external NestedStruct blah;
+        }
+
+        class NestedStruct extends Struct {
+          external Pointer<Void> n1;
+          external Pointer<Void> n2;
+          external Pointer<Void> n3;
+        }
+      b.dart: |
+        import 'dart:ffi';
+        import 'dart:isolate';
+        import 'dart:async';
+
+        import 'a.dart';
+
+        class StructB extends Struct {
+          external StructA b1;
+        }
+
+        void periodic() {
+          print(sizeOf<StructB>());
+        }
+
+        void main() {
+          Timer.periodic(const Duration(seconds: 1), (_) => periodic());
+        }
+    expectedLibraryCount: 2
+
+  - entry: b.dart
+    experiments: non-nullable
+    worldType: updated
+    expectInitializeFromDill: false
+    invalidate:
+      - b.dart
+    expectedLibraryCount: 2
+    expectsRebuildBodiesOnly: false
diff --git a/pkg/front_end/testcases/incremental/issue_46666.yaml.world.1.expect b/pkg/front_end/testcases/incremental/issue_46666.yaml.world.1.expect
new file mode 100644
index 0000000..516a77e
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/issue_46666.yaml.world.1.expect
@@ -0,0 +1,126 @@
+main = b::main;
+library from "org-dartlang-test:///a.dart" as a {
+
+  import "dart:ffi";
+
+  @#C7
+  class StructA extends dart.ffi::Struct {
+    synthetic constructor •() → a::StructA
+      : super dart.ffi::Struct::•()
+      ;
+    constructor #fromTypedDataBase(dart.core::Object #typedDataBase) → a::StructA
+      : super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
+      ;
+    get a1() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set a1(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get a2() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set a2(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get a3() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set a3(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get blah() → a::NestedStruct
+      return new a::NestedStruct::#fromTypedDataBase( block {
+        dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
+        dart.core::int #offset = (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+      } =>#typedDataBase is dart.ffi::Pointer<dynamic> ?{dart.core::Object} dart.ffi::_fromAddress<a::NestedStruct>(#typedDataBase.{dart.ffi::Pointer::address}{dart.core::int}.{dart.core::num::+}(#offset){(dart.core::num) → dart.core::num}) : let dart.typed_data::TypedData #typedData = dart._internal::unsafeCast<dart.typed_data::TypedData>(#typedDataBase) in #typedData.{dart.typed_data::TypedData::buffer}{dart.typed_data::ByteBuffer}.{dart.typed_data::ByteBuffer::asUint8List}(#typedData.{dart.typed_data::TypedData::offsetInBytes}{dart.core::int}.{dart.core::num::+}(#offset){(dart.core::num) → dart.core::num}, (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}){([dart.core::int, dart.core::int?]) → dart.typed_data::Uint8List});
+    set blah(a::NestedStruct #externalFieldValue) → void
+      return dart.ffi::_memCopy(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C8, (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
+    @#C19
+    static get #sizeOf() → dart.core::int*
+      return (#C21).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+  }
+  @#C24
+  class NestedStruct extends dart.ffi::Struct {
+    synthetic constructor •() → a::NestedStruct
+      : super dart.ffi::Struct::•()
+      ;
+    constructor #fromTypedDataBase(dart.core::Object #typedDataBase) → a::NestedStruct
+      : super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
+      ;
+    get n1() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set n1(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get n2() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set n2(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get n3() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set n3(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    @#C19
+    static get #sizeOf() → dart.core::int*
+      return (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+  }
+}
+library from "org-dartlang-test:///b.dart" as b {
+
+  import "dart:ffi";
+  import "dart:isolate";
+  import "dart:async";
+  import "org-dartlang-test:///a.dart";
+
+  @#C28
+  class StructB extends dart.ffi::Struct {
+    synthetic constructor •() → b::StructB
+      : super dart.ffi::Struct::•()
+      ;
+    constructor #fromTypedDataBase(dart.core::Object #typedDataBase) → b::StructB
+      : super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
+      ;
+    get b1() → a::StructA
+      return new a::StructA::#fromTypedDataBase( block {
+        dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
+        dart.core::int #offset = (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+      } =>#typedDataBase is dart.ffi::Pointer<dynamic> ?{dart.core::Object} dart.ffi::_fromAddress<a::StructA>(#typedDataBase.{dart.ffi::Pointer::address}{dart.core::int}.{dart.core::num::+}(#offset){(dart.core::num) → dart.core::num}) : let dart.typed_data::TypedData #typedData = dart._internal::unsafeCast<dart.typed_data::TypedData>(#typedDataBase) in #typedData.{dart.typed_data::TypedData::buffer}{dart.typed_data::ByteBuffer}.{dart.typed_data::ByteBuffer::asUint8List}(#typedData.{dart.typed_data::TypedData::offsetInBytes}{dart.core::int}.{dart.core::num::+}(#offset){(dart.core::num) → dart.core::num}, (#C21).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}){([dart.core::int, dart.core::int?]) → dart.typed_data::Uint8List});
+    set b1(a::StructA #externalFieldValue) → void
+      return dart.ffi::_memCopy(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C8, (#C21).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
+    @#C19
+    static get #sizeOf() → dart.core::int*
+      return (#C21).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+  }
+  static method periodic() → void {
+    dart.core::print(b::StructB::#sizeOf);
+  }
+  static method main() → void {
+    dart.async::Timer::periodic(#C30, (dart.async::Timer _) → void => b::periodic());
+  }
+}
+constants  {
+  #C1 = "vm:ffi:struct-fields"
+  #C2 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
+  #C3 = TypeLiteralConstant(a::NestedStruct)
+  #C4 = <dart.core::Type>[#C2, #C2, #C2, #C3]
+  #C5 = null
+  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = dart.core::pragma {name:#C1, options:#C6}
+  #C8 = 0
+  #C9 = <dart.core::int*>[#C8, #C8, #C8]
+  #C10 = 8
+  #C11 = 4
+  #C12 = <dart.core::int*>[#C10, #C11, #C11]
+  #C13 = 16
+  #C14 = <dart.core::int*>[#C13, #C10, #C10]
+  #C15 = 24
+  #C16 = 12
+  #C17 = <dart.core::int*>[#C15, #C16, #C16]
+  #C18 = "vm:prefer-inline"
+  #C19 = dart.core::pragma {name:#C18, options:#C5}
+  #C20 = 48
+  #C21 = <dart.core::int*>[#C20, #C15, #C15]
+  #C22 = <dart.core::Type>[#C2, #C2, #C2]
+  #C23 = dart.ffi::_FfiStructLayout {fieldTypes:#C22, packing:#C5}
+  #C24 = dart.core::pragma {name:#C1, options:#C23}
+  #C25 = TypeLiteralConstant(a::StructA)
+  #C26 = <dart.core::Type>[#C25]
+  #C27 = dart.ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C5}
+  #C28 = dart.core::pragma {name:#C1, options:#C27}
+  #C29 = 1000000
+  #C30 = dart.core::Duration {_duration:#C29}
+}
diff --git a/pkg/front_end/testcases/incremental/issue_46666.yaml.world.2.expect b/pkg/front_end/testcases/incremental/issue_46666.yaml.world.2.expect
new file mode 100644
index 0000000..516a77e
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/issue_46666.yaml.world.2.expect
@@ -0,0 +1,126 @@
+main = b::main;
+library from "org-dartlang-test:///a.dart" as a {
+
+  import "dart:ffi";
+
+  @#C7
+  class StructA extends dart.ffi::Struct {
+    synthetic constructor •() → a::StructA
+      : super dart.ffi::Struct::•()
+      ;
+    constructor #fromTypedDataBase(dart.core::Object #typedDataBase) → a::StructA
+      : super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
+      ;
+    get a1() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set a1(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get a2() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set a2(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get a3() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set a3(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get blah() → a::NestedStruct
+      return new a::NestedStruct::#fromTypedDataBase( block {
+        dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
+        dart.core::int #offset = (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+      } =>#typedDataBase is dart.ffi::Pointer<dynamic> ?{dart.core::Object} dart.ffi::_fromAddress<a::NestedStruct>(#typedDataBase.{dart.ffi::Pointer::address}{dart.core::int}.{dart.core::num::+}(#offset){(dart.core::num) → dart.core::num}) : let dart.typed_data::TypedData #typedData = dart._internal::unsafeCast<dart.typed_data::TypedData>(#typedDataBase) in #typedData.{dart.typed_data::TypedData::buffer}{dart.typed_data::ByteBuffer}.{dart.typed_data::ByteBuffer::asUint8List}(#typedData.{dart.typed_data::TypedData::offsetInBytes}{dart.core::int}.{dart.core::num::+}(#offset){(dart.core::num) → dart.core::num}, (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}){([dart.core::int, dart.core::int?]) → dart.typed_data::Uint8List});
+    set blah(a::NestedStruct #externalFieldValue) → void
+      return dart.ffi::_memCopy(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C8, (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
+    @#C19
+    static get #sizeOf() → dart.core::int*
+      return (#C21).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+  }
+  @#C24
+  class NestedStruct extends dart.ffi::Struct {
+    synthetic constructor •() → a::NestedStruct
+      : super dart.ffi::Struct::•()
+      ;
+    constructor #fromTypedDataBase(dart.core::Object #typedDataBase) → a::NestedStruct
+      : super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
+      ;
+    get n1() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set n1(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get n2() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set n2(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    get n3() → dart.ffi::Pointer<dart.ffi::Void>
+      return dart.ffi::_fromAddress<dart.ffi::Void>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}));
+    set n3(dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::Pointer::address}{dart.core::int});
+    @#C19
+    static get #sizeOf() → dart.core::int*
+      return (#C17).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+  }
+}
+library from "org-dartlang-test:///b.dart" as b {
+
+  import "dart:ffi";
+  import "dart:isolate";
+  import "dart:async";
+  import "org-dartlang-test:///a.dart";
+
+  @#C28
+  class StructB extends dart.ffi::Struct {
+    synthetic constructor •() → b::StructB
+      : super dart.ffi::Struct::•()
+      ;
+    constructor #fromTypedDataBase(dart.core::Object #typedDataBase) → b::StructB
+      : super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
+      ;
+    get b1() → a::StructA
+      return new a::StructA::#fromTypedDataBase( block {
+        dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
+        dart.core::int #offset = (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+      } =>#typedDataBase is dart.ffi::Pointer<dynamic> ?{dart.core::Object} dart.ffi::_fromAddress<a::StructA>(#typedDataBase.{dart.ffi::Pointer::address}{dart.core::int}.{dart.core::num::+}(#offset){(dart.core::num) → dart.core::num}) : let dart.typed_data::TypedData #typedData = dart._internal::unsafeCast<dart.typed_data::TypedData>(#typedDataBase) in #typedData.{dart.typed_data::TypedData::buffer}{dart.typed_data::ByteBuffer}.{dart.typed_data::ByteBuffer::asUint8List}(#typedData.{dart.typed_data::TypedData::offsetInBytes}{dart.core::int}.{dart.core::num::+}(#offset){(dart.core::num) → dart.core::num}, (#C21).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}){([dart.core::int, dart.core::int?]) → dart.typed_data::Uint8List});
+    set b1(a::StructA #externalFieldValue) → void
+      return dart.ffi::_memCopy(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, (#C9).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*}, #externalFieldValue.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C8, (#C21).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
+    @#C19
+    static get #sizeOf() → dart.core::int*
+      return (#C21).{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*};
+  }
+  static method periodic() → void {
+    dart.core::print(b::StructB::#sizeOf);
+  }
+  static method main() → void {
+    dart.async::Timer::periodic(#C30, (dart.async::Timer _) → void => b::periodic());
+  }
+}
+constants  {
+  #C1 = "vm:ffi:struct-fields"
+  #C2 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
+  #C3 = TypeLiteralConstant(a::NestedStruct)
+  #C4 = <dart.core::Type>[#C2, #C2, #C2, #C3]
+  #C5 = null
+  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = dart.core::pragma {name:#C1, options:#C6}
+  #C8 = 0
+  #C9 = <dart.core::int*>[#C8, #C8, #C8]
+  #C10 = 8
+  #C11 = 4
+  #C12 = <dart.core::int*>[#C10, #C11, #C11]
+  #C13 = 16
+  #C14 = <dart.core::int*>[#C13, #C10, #C10]
+  #C15 = 24
+  #C16 = 12
+  #C17 = <dart.core::int*>[#C15, #C16, #C16]
+  #C18 = "vm:prefer-inline"
+  #C19 = dart.core::pragma {name:#C18, options:#C5}
+  #C20 = 48
+  #C21 = <dart.core::int*>[#C20, #C15, #C15]
+  #C22 = <dart.core::Type>[#C2, #C2, #C2]
+  #C23 = dart.ffi::_FfiStructLayout {fieldTypes:#C22, packing:#C5}
+  #C24 = dart.core::pragma {name:#C1, options:#C23}
+  #C25 = TypeLiteralConstant(a::StructA)
+  #C26 = <dart.core::Type>[#C25]
+  #C27 = dart.ffi::_FfiStructLayout {fieldTypes:#C26, packing:#C5}
+  #C28 = dart.core::pragma {name:#C1, options:#C27}
+  #C29 = 1000000
+  #C30 = dart.core::Duration {_duration:#C29}
+}
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 340f2b9..26cdd5e 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -733,13 +733,15 @@
     for (final fieldType in fieldTypes.entries) {
       if (fieldType is TypeLiteralConstant) {
         final dartType = fieldType.type;
-        members.add(NativeTypeCfe(this, dartType));
+        members
+            .add(NativeTypeCfe(this, dartType, compoundCache: compoundCache));
       } else if (fieldType is InstanceConstant) {
         final singleElementConstant = fieldType
                 .fieldValues[ffiInlineArrayElementTypeField.getterReference]
             as TypeLiteralConstant;
-        final singleElementType =
-            NativeTypeCfe(this, singleElementConstant.type);
+        final singleElementType = NativeTypeCfe(
+            this, singleElementConstant.type,
+            compoundCache: compoundCache);
         final arrayLengthConstant =
             fieldType.fieldValues[ffiInlineArrayLengthField.getterReference]
                 as IntConstant;