[vm/ffi] Remove derived pointers inside structs

Required for finalizers: https://github.com/dart-lang/sdk/issues/35770

Change-Id: Ic512a4efd81cbd38cd836a8e8ad80464d2a3481f
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,analyzer-nnbd-linux-release-try,dart2js-nnbd-linux-x64-chrome-try,ddc-nnbd-linux-release-chrome-try,front-end-nnbd-linux-release-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135906
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.strong.transformed.expect b/pkg/front_end/testcases/general/ffi_sample.dart.strong.transformed.expect
index 0b6ab81..bcf2699 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.strong.transformed.expect
@@ -18,24 +18,18 @@
   static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
     return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in let final void #t2 = #t1.{self::Coordinate::x} = x in let final void #t3 = #t1.{self::Coordinate::y} = y in let final void #t4 = #t1.{self::Coordinate::next} = next in #t1;
   }
-  get #_ptr_x() → ffi::Pointer<ffi::Double*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::cast}<ffi::Double*>();
   get x() → core::double*
-    return ffi::_loadDouble(this.{self::Coordinate::#_ptr_x}, #C7);
+    return ffi::_loadDouble(this.{ffi::Struct::_addressOf}, (#C8).{core::List::[]}(ffi::_abi()));
   set x(core::double* #v) → void
-    return ffi::_storeDouble(this.{self::Coordinate::#_ptr_x}, #C7, #v);
-  get #_ptr_y() → ffi::Pointer<ffi::Double*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::_offsetBy}((#C9).{core::List::[]}(ffi::_abi())).{ffi::Pointer::cast}<ffi::Double*>();
+    return ffi::_storeDouble(this.{ffi::Struct::_addressOf}, (#C8).{core::List::[]}(ffi::_abi()), #v);
   get y() → core::double*
-    return ffi::_loadDouble(this.{self::Coordinate::#_ptr_y}, #C7);
+    return ffi::_loadDouble(this.{ffi::Struct::_addressOf}, (#C10).{core::List::[]}(ffi::_abi()));
   set y(core::double* #v) → void
-    return ffi::_storeDouble(this.{self::Coordinate::#_ptr_y}, #C7, #v);
-  get #_ptr_next() → ffi::Pointer<ffi::Pointer<self::Coordinate*>*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::_offsetBy}((#C11).{core::List::[]}(ffi::_abi())).{ffi::Pointer::cast}<ffi::Pointer<self::Coordinate*>*>();
+    return ffi::_storeDouble(this.{ffi::Struct::_addressOf}, (#C10).{core::List::[]}(ffi::_abi()), #v);
   get next() → ffi::Pointer<self::Coordinate*>*
-    return ffi::_loadPointer<ffi::Pointer<self::Coordinate*>*>(this.{self::Coordinate::#_ptr_next}, #C7);
+    return ffi::_fromAddress<self::Coordinate*>(ffi::_loadIntPtr(this.{ffi::Struct::_addressOf}, (#C12).{core::List::[]}(ffi::_abi())));
   set next(ffi::Pointer<self::Coordinate*>* #v) → void
-    return ffi::_storePointer<ffi::Pointer<self::Coordinate*>*>(this.{self::Coordinate::#_ptr_next}, #C7, #v);
+    return ffi::_storeIntPtr(this.{ffi::Struct::_addressOf}, (#C12).{core::List::[]}(ffi::_abi()), #v.{=ffi::Pointer::address});
 }
 static method main() → dynamic {}
 
@@ -47,8 +41,9 @@
   #C5 = 20
   #C6 = <core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <core::int*>[#C10, #C10, #C10]
+  #C8 = <core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.strong.transformed.expect
index 0b6ab81..bcf2699 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.strong.transformed.expect
@@ -18,24 +18,18 @@
   static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
     return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in let final void #t2 = #t1.{self::Coordinate::x} = x in let final void #t3 = #t1.{self::Coordinate::y} = y in let final void #t4 = #t1.{self::Coordinate::next} = next in #t1;
   }
-  get #_ptr_x() → ffi::Pointer<ffi::Double*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::cast}<ffi::Double*>();
   get x() → core::double*
-    return ffi::_loadDouble(this.{self::Coordinate::#_ptr_x}, #C7);
+    return ffi::_loadDouble(this.{ffi::Struct::_addressOf}, (#C8).{core::List::[]}(ffi::_abi()));
   set x(core::double* #v) → void
-    return ffi::_storeDouble(this.{self::Coordinate::#_ptr_x}, #C7, #v);
-  get #_ptr_y() → ffi::Pointer<ffi::Double*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::_offsetBy}((#C9).{core::List::[]}(ffi::_abi())).{ffi::Pointer::cast}<ffi::Double*>();
+    return ffi::_storeDouble(this.{ffi::Struct::_addressOf}, (#C8).{core::List::[]}(ffi::_abi()), #v);
   get y() → core::double*
-    return ffi::_loadDouble(this.{self::Coordinate::#_ptr_y}, #C7);
+    return ffi::_loadDouble(this.{ffi::Struct::_addressOf}, (#C10).{core::List::[]}(ffi::_abi()));
   set y(core::double* #v) → void
-    return ffi::_storeDouble(this.{self::Coordinate::#_ptr_y}, #C7, #v);
-  get #_ptr_next() → ffi::Pointer<ffi::Pointer<self::Coordinate*>*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::_offsetBy}((#C11).{core::List::[]}(ffi::_abi())).{ffi::Pointer::cast}<ffi::Pointer<self::Coordinate*>*>();
+    return ffi::_storeDouble(this.{ffi::Struct::_addressOf}, (#C10).{core::List::[]}(ffi::_abi()), #v);
   get next() → ffi::Pointer<self::Coordinate*>*
-    return ffi::_loadPointer<ffi::Pointer<self::Coordinate*>*>(this.{self::Coordinate::#_ptr_next}, #C7);
+    return ffi::_fromAddress<self::Coordinate*>(ffi::_loadIntPtr(this.{ffi::Struct::_addressOf}, (#C12).{core::List::[]}(ffi::_abi())));
   set next(ffi::Pointer<self::Coordinate*>* #v) → void
-    return ffi::_storePointer<ffi::Pointer<self::Coordinate*>*>(this.{self::Coordinate::#_ptr_next}, #C7, #v);
+    return ffi::_storeIntPtr(this.{ffi::Struct::_addressOf}, (#C12).{core::List::[]}(ffi::_abi()), #v.{=ffi::Pointer::address});
 }
 static method main() → dynamic {}
 
@@ -47,8 +41,9 @@
   #C5 = 20
   #C6 = <core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <core::int*>[#C10, #C10, #C10]
+  #C8 = <core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
index 0b6ab81..bcf2699 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
@@ -18,24 +18,18 @@
   static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
     return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in let final void #t2 = #t1.{self::Coordinate::x} = x in let final void #t3 = #t1.{self::Coordinate::y} = y in let final void #t4 = #t1.{self::Coordinate::next} = next in #t1;
   }
-  get #_ptr_x() → ffi::Pointer<ffi::Double*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::cast}<ffi::Double*>();
   get x() → core::double*
-    return ffi::_loadDouble(this.{self::Coordinate::#_ptr_x}, #C7);
+    return ffi::_loadDouble(this.{ffi::Struct::_addressOf}, (#C8).{core::List::[]}(ffi::_abi()));
   set x(core::double* #v) → void
-    return ffi::_storeDouble(this.{self::Coordinate::#_ptr_x}, #C7, #v);
-  get #_ptr_y() → ffi::Pointer<ffi::Double*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::_offsetBy}((#C9).{core::List::[]}(ffi::_abi())).{ffi::Pointer::cast}<ffi::Double*>();
+    return ffi::_storeDouble(this.{ffi::Struct::_addressOf}, (#C8).{core::List::[]}(ffi::_abi()), #v);
   get y() → core::double*
-    return ffi::_loadDouble(this.{self::Coordinate::#_ptr_y}, #C7);
+    return ffi::_loadDouble(this.{ffi::Struct::_addressOf}, (#C10).{core::List::[]}(ffi::_abi()));
   set y(core::double* #v) → void
-    return ffi::_storeDouble(this.{self::Coordinate::#_ptr_y}, #C7, #v);
-  get #_ptr_next() → ffi::Pointer<ffi::Pointer<self::Coordinate*>*>*
-    return this.{ffi::Struct::_addressOf}.{ffi::Pointer::_offsetBy}((#C11).{core::List::[]}(ffi::_abi())).{ffi::Pointer::cast}<ffi::Pointer<self::Coordinate*>*>();
+    return ffi::_storeDouble(this.{ffi::Struct::_addressOf}, (#C10).{core::List::[]}(ffi::_abi()), #v);
   get next() → ffi::Pointer<self::Coordinate*>*
-    return ffi::_loadPointer<ffi::Pointer<self::Coordinate*>*>(this.{self::Coordinate::#_ptr_next}, #C7);
+    return ffi::_fromAddress<self::Coordinate*>(ffi::_loadIntPtr(this.{ffi::Struct::_addressOf}, (#C12).{core::List::[]}(ffi::_abi())));
   set next(ffi::Pointer<self::Coordinate*>* #v) → void
-    return ffi::_storePointer<ffi::Pointer<self::Coordinate*>*>(this.{self::Coordinate::#_ptr_next}, #C7, #v);
+    return ffi::_storeIntPtr(this.{ffi::Struct::_addressOf}, (#C12).{core::List::[]}(ffi::_abi()), #v.{=ffi::Pointer::address});
 }
 static method main() → dynamic {}
 
@@ -47,8 +41,9 @@
   #C5 = 20
   #C6 = <core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <core::int*>[#C10, #C10, #C10]
+  #C8 = <core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_01.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_01.yaml.world.1.expect
index 748c4c0..78fb060 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_01.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_01.yaml.world.1.expect
@@ -14,24 +14,18 @@
     static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
       return null;
     }
-    get #_ptr_x() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
     get x() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_x}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()));
     set x(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_x}, #C7, #v);
-    get #_ptr_y() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C9).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get y() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_y}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()));
     set y(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_y}, #C7, #v);
-    get #_ptr_next() → dart.ffi::Pointer<dart.ffi::Pointer<lib::Coordinate*>*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C11).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Pointer<lib::Coordinate*>*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get next() → dart.ffi::Pointer<lib::Coordinate*>*
-      return dart.ffi::_loadPointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7);
+      return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi())));
     set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
-      return dart.ffi::_storePointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7, #v);
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v.{=dart.ffi::Pointer::address});
   }
 }
 library from "org-dartlang-test:///main.dart" as main {
@@ -53,8 +47,9 @@
   #C5 = 20
   #C6 = <dart.core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <dart.core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <dart.core::int*>[#C10, #C10, #C10]
+  #C8 = <dart.core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <dart.core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <dart.core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_01.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_01.yaml.world.2.expect
index 2fefb04..d24f770 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_01.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_01.yaml.world.2.expect
@@ -14,24 +14,18 @@
     static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
       return null;
     }
-    get #_ptr_x() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
     get x() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_x}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()));
     set x(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_x}, #C7, #v);
-    get #_ptr_y() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C9).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get y() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_y}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()));
     set y(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_y}, #C7, #v);
-    get #_ptr_next() → dart.ffi::Pointer<dart.ffi::Pointer<lib::Coordinate*>*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C11).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Pointer<lib::Coordinate*>*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get next() → dart.ffi::Pointer<lib::Coordinate*>*
-      return dart.ffi::_loadPointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7);
+      return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi())));
     set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
-      return dart.ffi::_storePointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7, #v);
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v.{=dart.ffi::Pointer::address});
   }
 }
 library from "org-dartlang-test:///main.dart" as main {
@@ -57,8 +51,9 @@
   #C5 = 20
   #C6 = <dart.core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <dart.core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <dart.core::int*>[#C10, #C10, #C10]
+  #C8 = <dart.core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <dart.core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <dart.core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_02.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_02.yaml.world.1.expect
index 51d68a9..faed25b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_02.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/ffi_02.yaml.world.1.expect
@@ -14,24 +14,18 @@
     static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
       return null;
     }
-    get #_ptr_x() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
     get x() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_x}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()));
     set x(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_x}, #C7, #v);
-    get #_ptr_y() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C9).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get y() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_y}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()));
     set y(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_y}, #C7, #v);
-    get #_ptr_next() → dart.ffi::Pointer<dart.ffi::Pointer<lib::Coordinate*>*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C11).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Pointer<lib::Coordinate*>*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get next() → dart.ffi::Pointer<lib::Coordinate*>*
-      return dart.ffi::_loadPointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7);
+      return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi())));
     set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
-      return dart.ffi::_storePointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7, #v);
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v.{=dart.ffi::Pointer::address});
   }
 }
 library from "org-dartlang-test:///main.dart" as main {
@@ -54,8 +48,9 @@
   #C5 = 20
   #C6 = <dart.core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <dart.core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <dart.core::int*>[#C10, #C10, #C10]
+  #C8 = <dart.core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <dart.core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <dart.core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.1.expect
index 748c4c0..78fb060 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.1.expect
@@ -14,24 +14,18 @@
     static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
       return null;
     }
-    get #_ptr_x() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
     get x() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_x}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()));
     set x(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_x}, #C7, #v);
-    get #_ptr_y() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C9).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get y() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_y}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()));
     set y(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_y}, #C7, #v);
-    get #_ptr_next() → dart.ffi::Pointer<dart.ffi::Pointer<lib::Coordinate*>*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C11).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Pointer<lib::Coordinate*>*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get next() → dart.ffi::Pointer<lib::Coordinate*>*
-      return dart.ffi::_loadPointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7);
+      return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi())));
     set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
-      return dart.ffi::_storePointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7, #v);
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v.{=dart.ffi::Pointer::address});
   }
 }
 library from "org-dartlang-test:///main.dart" as main {
@@ -53,8 +47,9 @@
   #C5 = 20
   #C6 = <dart.core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <dart.core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <dart.core::int*>[#C10, #C10, #C10]
+  #C8 = <dart.core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <dart.core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <dart.core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.2.expect
index b1805b0..a90ca05 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.2.expect
@@ -14,24 +14,18 @@
     static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
       return null;
     }
-    get #_ptr_x() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
     get x() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_x}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()));
     set x(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_x}, #C7, #v);
-    get #_ptr_y() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C9).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get y() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_y}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()));
     set y(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_y}, #C7, #v);
-    get #_ptr_next() → dart.ffi::Pointer<dart.ffi::Pointer<lib::Coordinate*>*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C11).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Pointer<lib::Coordinate*>*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get next() → dart.ffi::Pointer<lib::Coordinate*>*
-      return dart.ffi::_loadPointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7);
+      return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi())));
     set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
-      return dart.ffi::_storePointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7, #v);
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v.{=dart.ffi::Pointer::address});
   }
 }
 library from "org-dartlang-test:///main.dart" as main {
@@ -54,8 +48,9 @@
   #C5 = 20
   #C6 = <dart.core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <dart.core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <dart.core::int*>[#C10, #C10, #C10]
+  #C8 = <dart.core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <dart.core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <dart.core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.3.expect
index 32cc854..72a0cac 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_35.yaml.world.3.expect
@@ -15,24 +15,18 @@
       dart.core::print("hello");
       return null;
     }
-    get #_ptr_x() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
     get x() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_x}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()));
     set x(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_x}, #C7, #v);
-    get #_ptr_y() → dart.ffi::Pointer<dart.ffi::Double*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C9).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Double*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C8).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get y() → dart.core::double*
-      return dart.ffi::_loadDouble(this.{lib::Coordinate::#_ptr_y}, #C7);
+      return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()));
     set y(dart.core::double* #v) → void
-      return dart.ffi::_storeDouble(this.{lib::Coordinate::#_ptr_y}, #C7, #v);
-    get #_ptr_next() → dart.ffi::Pointer<dart.ffi::Pointer<lib::Coordinate*>*>*
-      return this.{dart.ffi::Struct::_addressOf}.{dart.ffi::Pointer::_offsetBy}((#C11).{dart.core::List::[]}(dart.ffi::_abi())).{dart.ffi::Pointer::cast}<dart.ffi::Pointer<lib::Coordinate*>*>();
+      return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_addressOf}, (#C10).{dart.core::List::[]}(dart.ffi::_abi()), #v);
     get next() → dart.ffi::Pointer<lib::Coordinate*>*
-      return dart.ffi::_loadPointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7);
+      return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi())));
     set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
-      return dart.ffi::_storePointer<dart.ffi::Pointer<lib::Coordinate*>*>(this.{lib::Coordinate::#_ptr_next}, #C7, #v);
+      return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_addressOf}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v.{=dart.ffi::Pointer::address});
   }
 }
 library from "org-dartlang-test:///main.dart" as main {
@@ -55,8 +49,9 @@
   #C5 = 20
   #C6 = <dart.core::int*>[#C4, #C5, #C4]
   #C7 = 0
-  #C8 = 8
-  #C9 = <dart.core::int*>[#C8, #C8, #C8]
-  #C10 = 16
-  #C11 = <dart.core::int*>[#C10, #C10, #C10]
+  #C8 = <dart.core::int*>[#C7, #C7, #C7]
+  #C9 = 8
+  #C10 = <dart.core::int*>[#C9, #C9, #C9]
+  #C11 = 16
+  #C12 = <dart.core::int*>[#C11, #C11, #C11]
 }
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 9875288..3f67eee 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -196,12 +196,14 @@
   final Procedure castMethod;
   final Procedure offsetByMethod;
   final Procedure elementAtMethod;
+  final Procedure addressGetter;
   final Procedure asFunctionMethod;
   final Procedure asFunctionInternal;
   final Procedure lookupFunctionMethod;
   final Procedure fromFunctionMethod;
   final Field addressOfField;
   final Constructor structFromPointer;
+  final Procedure fromAddressInternal;
   final Procedure libraryLookupMethod;
   final Procedure abiMethod;
   final Procedure pointerFromFunctionProcedure;
@@ -231,9 +233,12 @@
         castMethod = index.getMember('dart:ffi', 'Pointer', 'cast'),
         offsetByMethod = index.getMember('dart:ffi', 'Pointer', '_offsetBy'),
         elementAtMethod = index.getMember('dart:ffi', 'Pointer', 'elementAt'),
+        addressGetter = index.getMember('dart:ffi', 'Pointer', 'get:address'),
         addressOfField = index.getMember('dart:ffi', 'Struct', '_addressOf'),
         structFromPointer =
             index.getMember('dart:ffi', 'Struct', '_fromPointer'),
+        fromAddressInternal =
+            index.getTopLevelMember('dart:ffi', '_fromAddress'),
         asFunctionMethod =
             index.getMember('dart:ffi', 'NativeFunctionPointer', 'asFunction'),
         asFunctionInternal =
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 75ff955..ee3028d 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -309,64 +309,42 @@
         listElementAt);
   }
 
-  /// Sample output:
-  /// ffi.Pointer<ffi.Double> get _xPtr => addressOf.cast();
-  /// double get x => _xPtr.load();
-  /// set x(double v) => _xPtr.store(v);
   List<Procedure> _generateMethodsForField(Field field, NativeType type,
       Map<Abi, int> offsets, IndexedClass indexedClass) {
     final DartType nativeType = type == NativeType.kPointer
         ? field.type
         : InterfaceType(nativeTypesClasses[type.index], Nullability.legacy);
-    final DartType pointerType =
-        InterfaceType(pointerClass, Nullability.legacy, [nativeType]);
-    final Name pointerName = Name('#_ptr_${field.name.name}');
-
-    // Sample output:
-    // ffi.Pointer<ffi.Double> get _xPtr => addressOf.offsetBy(...).cast<ffi.Pointer<ffi.Double>>();
-    Expression pointer =
-        PropertyGet(ThisExpression(), addressOfField.name, addressOfField);
-    final hasNonZero = offsets.values.skipWhile((i) => i == 0).isNotEmpty;
-    if (hasNonZero) {
-      pointer = MethodInvocation(pointer, offsetByMethod.name,
-          Arguments([_runtimeBranchOnLayout(offsets)]), offsetByMethod);
-    }
-
     final Class nativeClass = (nativeType as InterfaceType).classNode;
     final NativeType nt = getType(nativeClass);
-    final typeArguments = [
-      if (nt == NativeType.kPointer && pointerType is InterfaceType)
-        pointerType.typeArguments[0]
-    ];
-
-    final Procedure pointerGetter = Procedure(
-        pointerName,
-        ProcedureKind.Getter,
-        FunctionNode(
-            ReturnStatement(MethodInvocation(pointer, castMethod.name,
-                Arguments([], types: [nativeType]), castMethod)),
-            returnType: pointerType),
-        fileUri: field.fileUri,
-        reference:
-            indexedClass?.lookupProcedureNotSetter(pointerName.name)?.reference)
-      ..fileOffset = field.fileOffset
-      ..isNonNullableByDefault = field.isNonNullableByDefault;
+    final bool isPointer = nt == NativeType.kPointer;
 
     // Sample output:
-    // double get x => _xPtr.value;
-    final loadMethod =
-        optimizedTypes.contains(nt) ? loadMethods[nt] : loadStructMethod;
+    // int get x => _loadInt8(pointer, offset);
+    //
+    // Treat Pointer fields different to get correct behavior without casts:
+    // Pointer<Int8> get x =>
+    //   _fromAddress<Int8>(_loadIntPtr(pointer, offset));
+    final loadMethod = isPointer
+        ? loadMethods[NativeType.kIntptr]
+        : optimizedTypes.contains(nt) ? loadMethods[nt] : loadStructMethod;
+    Expression getterReturnValue = StaticInvocation(
+        loadMethod,
+        Arguments([
+          PropertyGet(ThisExpression(), addressOfField.name, addressOfField)
+            ..fileOffset = field.fileOffset,
+          _runtimeBranchOnLayout(offsets)
+        ]))
+      ..fileOffset = field.fileOffset;
+    if (isPointer) {
+      final typeArg = (nativeType as InterfaceType).typeArguments.single;
+      getterReturnValue = StaticInvocation(
+          fromAddressInternal, Arguments([getterReturnValue], types: [typeArg]))
+        ..fileOffset = field.fileOffset;
+    }
     final Procedure getter = Procedure(
         field.name,
         ProcedureKind.Getter,
-        FunctionNode(
-            ReturnStatement(StaticInvocation(
-                loadMethod,
-                Arguments([
-                  PropertyGet(ThisExpression(), pointerName, pointerGetter),
-                  ConstantExpression(IntConstant(0),
-                      InterfaceType(intClass, Nullability.legacy))
-                ], types: typeArguments))),
+        FunctionNode(ReturnStatement(getterReturnValue),
             returnType: field.type),
         fileUri: field.fileUri,
         reference:
@@ -375,12 +353,25 @@
       ..isNonNullableByDefault = field.isNonNullableByDefault;
 
     // Sample output:
-    // set x(double v) { _xPtr.value = v; };
-    final storeMethod = storeMethods[nt];
+    // set x(int v) => _storeInt8(pointer, offset, v);
+    //
+    // Treat Pointer fields different to get correct behavior without casts:
+    // set x(Pointer<Int8> v) =>
+    //   _storeIntPtr(pointer, offset, (v as Pointer<Int8>).address);
+    final storeMethod =
+        isPointer ? storeMethods[NativeType.kIntptr] : storeMethods[nt];
     Procedure setter = null;
     if (!field.isFinal) {
       final VariableDeclaration argument =
-          VariableDeclaration('#v', type: field.type);
+          VariableDeclaration('#v', type: field.type)
+            ..fileOffset = field.fileOffset;
+      Expression argumentExpression = VariableGet(argument)
+        ..fileOffset = field.fileOffset;
+      if (isPointer) {
+        argumentExpression =
+            DirectPropertyGet(argumentExpression, addressGetter)
+              ..fileOffset = field.fileOffset;
+      }
       setter = Procedure(
           field.name,
           ProcedureKind.Setter,
@@ -388,11 +379,13 @@
               ReturnStatement(StaticInvocation(
                   storeMethod,
                   Arguments([
-                    PropertyGet(ThisExpression(), pointerName, pointerGetter),
-                    ConstantExpression(IntConstant(0),
-                        InterfaceType(intClass, Nullability.legacy)),
-                    VariableGet(argument)
-                  ], types: typeArguments))),
+                    PropertyGet(
+                        ThisExpression(), addressOfField.name, addressOfField)
+                      ..fileOffset = field.fileOffset,
+                    _runtimeBranchOnLayout(offsets),
+                    argumentExpression
+                  ]))
+                ..fileOffset = field.fileOffset),
               returnType: VoidType(),
               positionalParameters: [argument]),
           fileUri: field.fileUri,
@@ -405,7 +398,7 @@
     replacedGetters[field] = getter;
     replacedSetters[field] = setter;
 
-    return [pointerGetter, getter, if (setter != null) setter];
+    return [getter, if (setter != null) setter];
   }
 
   /// Sample output: